diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc27e6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.project +.settings +/target +.checkstyle +.idea +*.iml +/vagrant/.vagrant +/vagrant/ansible +.classpath +/bin + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d8c3222 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +language: java +script: mvn clean verify diff --git a/pom.xml b/pom.xml index e44a1ec..5ef3a36 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ commons-cli commons-cli - 1.2 + 1.3.1 org.apache.commons @@ -23,7 +23,7 @@ org.apache.zookeeper zookeeper - 3.4.3 + 3.4.9 com.sun.jmx diff --git a/readme.md b/readme.md index 9fa77fc..141c2f8 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,25 @@ - usage: guano +BADGES + +[ ![Download](https://api.bintray.com/packages/feldoh/Guano/guano/images/download.svg) ](https://bintray.com/feldoh/Guano/guano/_latestVersion) [![Build Status](https://travis-ci.org/feldoh/guano.svg?branch=master)](https://travis-ci.org/feldoh/guano) - -s,--server the zookeeper remote server to connect to (ie - "localhost:2181" +NAME + + guano -- dump or restore Zookeeper trees + +SYNOPSIS + + guano [operands ...] + +DESCRIPTION + + This tool dumps and restores zookeeper state to/from a matching folder structure on disk. + The server argument is mandatory then either a node to dump and where to dump it, + or a previous dump to restore and the root to restore it to. + + usage: guano [-v] -s [-d -o ] [-r -i ] + + -s,--server *Required, the zookeeper remote server to connect to + i.e. "localhost:2181" -d,--dump-znode the znode to dump (recursively) -o,--output-dir the output directory to which znode @@ -14,3 +32,11 @@ restored -v,--verbose enable debug output + + Note: When restoring you need to provide one level up as the node selected for the dump is included. + e.g. java -jar target/guano-0.1a.jar -s "zookeeper-01.mydomain.com" -o "/tmp/zkdump" -d "/myroot" + java -jar target/guano-0.1a.jar -s "zookeeper-01.mydomain.com" -i "/tmp/zkdump" -r "/" + +PREBUILT BINARIES + + Pre-built binaries are available for most common platforms on Bintray diff --git a/src/main/java/com/d2fn/guano/DumpJob.java b/src/main/java/com/d2fn/guano/DumpJob.java index 488272e..0d57318 100644 --- a/src/main/java/com/d2fn/guano/DumpJob.java +++ b/src/main/java/com/d2fn/guano/DumpJob.java @@ -1,11 +1,13 @@ package com.d2fn.guano; -import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.List; /** @@ -62,8 +64,7 @@ private void dumpChild(ZooKeeper zk, String outputPath, String znodeParent, Stri if(!children.isEmpty()) { // ensure parent dir is created - File f = new File(outputPath); - boolean s = f.mkdirs(); + createFolder(outputPath); // this znode is a dir, so ensure the directory is created and build a __znode value in its dir writeZnode(zk, outputPath + "/_znode", currznode); @@ -90,9 +91,26 @@ private void writeZnode(ZooKeeper zk, String outFile, String znode) throws Excep out.flush(); out.close(); } + } else { + if (!outFile.contains("_znode") && stat.getEphemeralOwner() == 0) { + // Create an empty folder for Permanent nodes. + createFolder(outFile); + } + } } + private void createFolder(String path) { + File f = new File(path); + if(!f.exists() ) { + boolean s = f.mkdirs(); + if (s) { + System.out.println("Created folder: " + path); + } + } + + } + @Override public void process(WatchedEvent watchedEvent) { ;;