Skip to content
This repository has been archived by the owner on Jul 26, 2022. It is now read-only.

Commit

Permalink
Automatically add folder to daemon config in sy init/connect
Browse files Browse the repository at this point in the history
  • Loading branch information
binwiederhier committed Sep 3, 2014
1 parent f5aa457 commit 1f92cf6
Show file tree
Hide file tree
Showing 17 changed files with 260 additions and 98 deletions.
4 changes: 2 additions & 2 deletions gradle/bash/syncany.bash-completion
Expand Up @@ -91,7 +91,7 @@ _sy ()
cmdOpts=( -M --no-database-merge -V --no-version-remove -k --keep-versions= -f --force-checksum )
;;
connect)
cmdOpts=( -P --plugin= -o --plugin-option= -I --no-interaction )
cmdOpts=( -P --plugin= -o --plugin-option= -I --no-interaction -N --no-daemon )

case $curOpt in
--plugin|-P)
Expand All @@ -107,7 +107,7 @@ _sy ()
cmdOpts=( -s --short )
;;
init)
cmdOpts=( -P --plugin= -o --plugin-option= -E --no-encryption -G --no-compression -t --create-target -a --advanced -I --no-interaction )
cmdOpts=( -P --plugin= -o --plugin-option= -E --no-encryption -G --no-compression -t --create-target -a --advanced -I --no-interaction -N --no-daemon )

case $curOpt in
--plugin|-P)
Expand Down
7 changes: 7 additions & 0 deletions syncany-cli/src/main/java/org/syncany/cli/ConnectCommand.java
Expand Up @@ -77,6 +77,7 @@ private ConnectOperationOptions parseConnectOptions(String[] operationArguments)
OptionSpec<String> optionPlugin = parser.acceptsAll(asList("P", "plugin")).withRequiredArg();
OptionSpec<String> optionPluginOpts = parser.acceptsAll(asList("o", "plugin-option")).withRequiredArg();
OptionSpec<Void> optionNonInteractive = parser.acceptsAll(asList("I", "no-interaction"));
OptionSpec<Void> optionNoDaemon = parser.acceptsAll(asList("N", "no-daemon"));

OptionSet options = parser.parse(operationArguments);
List<?> nonOptionArgs = options.nonOptionArguments();
Expand Down Expand Up @@ -109,6 +110,7 @@ else if (nonOptionArgs.size() == 0) {

operationOptions.setLocalDir(localDir);
operationOptions.setConfigTO(configTO);
operationOptions.setDaemon(!options.has(optionNoDaemon));

return operationOptions;
}
Expand All @@ -119,6 +121,11 @@ private void printResults(ConnectOperationResult operationResult) {
out.println("Repository connected, and local folder initialized.");
out.println("You can now use the 'syncany' command to sync your files.");
out.println();

if (operationResult.isAddedToDaemon()) {
out.println("To automatically sync this folder, simply restart the daemon with 'sy daemon restart'.");
out.println();
}
}
else if (operationResult.getResultCode() == ConnectResultCode.NOK_TEST_FAILED) {
StorageTestResult testResult = operationResult.getTestResult();
Expand Down
7 changes: 7 additions & 0 deletions syncany-cli/src/main/java/org/syncany/cli/InitCommand.java
Expand Up @@ -95,6 +95,7 @@ private InitOperationOptions parseInitOptions(String[] operationArguments) throw
OptionSpec<String> optionPlugin = parser.acceptsAll(asList("P", "plugin")).withRequiredArg();
OptionSpec<String> optionPluginOpts = parser.acceptsAll(asList("o", "plugin-option")).withRequiredArg();
OptionSpec<Void> optionNonInteractive = parser.acceptsAll(asList("I", "no-interaction"));
OptionSpec<Void> optionNoDaemon = parser.acceptsAll(asList("N", "no-daemon"));

OptionSet options = parser.parse(operationArguments);

Expand Down Expand Up @@ -130,6 +131,7 @@ private InitOperationOptions parseInitOptions(String[] operationArguments) throw
operationOptions.setEncryptionEnabled(encryptionEnabled);
operationOptions.setCipherSpecs(cipherSpecs);
operationOptions.setPassword(null); // set by callback in operation
operationOptions.setDaemon(!options.has(optionNoDaemon));

return operationOptions;
}
Expand All @@ -141,6 +143,11 @@ private void printResults(InitOperationOptions operationOptions, InitOperationRe
out.println("with others, you can share this link:");

printLink(operationResult.getGenLinkResult(), false);

if (operationResult.isAddedToDaemon()) {
out.println("To automatically sync this folder, simply restart the daemon with 'sy daemon restart'.");
out.println();
}
}
else if (operationResult.getResultCode() == InitResultCode.NOK_TEST_FAILED) {
StorageTestResult testResult = operationResult.getTestResult();
Expand Down
Expand Up @@ -5,7 +5,7 @@ SYNOPSIS
sy connect <syncany-link>

sy connect [-P | --plugin=<plugin>] [-o | --plugin-option=<key=value>]
[-I | --no-interaction]
[-I | --no-interaction] [-N | --no-daemon]

DESCRIPTION
This command connects to an existing remote repository and initializes
Expand Down Expand Up @@ -41,5 +41,10 @@ OPTIONS
for any input. The command will fail if not all mandatory options are
given on the command line. This option can be used to automate repository
creation.

-N, --no-daemon
The initialized local folder is automatically added to the daemon
configuration for automatic synchronization. Use this option to avoid
that.

%RESOURCE:incl/footer.skel%
Expand Up @@ -5,6 +5,7 @@ SYNOPSIS
sy init [-P | --plugin=<plugin>] [-o | --plugin-option=<key=value>]
[-E | --no-encryption] [-G | --no-compression]
[-t | --create-target] [-a | --advanced] [-I | --no-interaction]
[-N | --no-daemon]

DESCRIPTION
This command creates a new remote repository using the specified plugin, and
Expand Down Expand Up @@ -57,5 +58,10 @@ OPTIONS
for any input. The command will fail if not all mandatory options are
given on the command line. This option can be used to automate repository
creation.

-N, --no-daemon
The initialized local folder is automatically added to the daemon
configuration for automatic synchronization. Use this option to avoid
that.

%RESOURCE:incl/footer.skel%
2 changes: 1 addition & 1 deletion syncany-lib/src/main/java/org/syncany/config/Config.java
Expand Up @@ -71,7 +71,7 @@ public class Config {
// Files in .syncany/state
public static final String FILE_PORT = "port.xml";
public static final String FILE_CLEANUP = "cleanup.xml";

private byte[] repoId;
private String machineName;
private String displayName;
Expand Down
56 changes: 55 additions & 1 deletion syncany-lib/src/main/java/org/syncany/config/UserConfig.java
Expand Up @@ -21,11 +21,15 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.syncany.config.to.DaemonConfigTO;
import org.syncany.config.to.FolderTO;
import org.syncany.config.to.UserConfigTO;
import org.syncany.config.to.UserTO;
import org.syncany.crypto.CipherUtil;
import org.syncany.util.EnvironmentUtil;

Expand All @@ -44,10 +48,17 @@ public class UserConfig {
*
*/

// Daemon-specific config
public static final String DAEMON_FILE = "daemon.xml";
public static final String DAEMON_EXAMPLE_FILE = "daemon-example.xml";
public static final String DEFAULT_FOLDER = "Syncany";
public static final String USER_ADMIN = "admin";
public static final String USER_CLI = "CLI";

// These fields are not final to enable a PluginOperationTest
private static File USER_APP_DIR_WINDOWS = new File(System.getenv("APPDATA") + "\\Syncany");
private static File USER_APP_DIR_UNIX_LIKE = new File(System.getProperty("user.home") + "/.config/syncany");

private static final String USER_PLUGINS_LIB_DIR = "plugins/lib";
private static final String USER_PLUGINS_USERDATA_DIR_FORMAT = "plugins/userdata/%s";
private static final String USER_CONFIG_FILE = "userconfig.xml";
Expand Down Expand Up @@ -180,6 +191,49 @@ private static void writeExampleUserConfigFile(File userConfigFile) {
}
}

// Daemon XML config methods

public static DaemonConfigTO createAndWriteDefaultDaemonConfig(File daemonConfigFile) {
return createAndWriteConfig(daemonConfigFile, new ArrayList<FolderTO>());
}

public static DaemonConfigTO createAndWriteExampleDaemonConfig(File configFileExample) {
File defaultFolder = new File(System.getProperty("user.home"), UserConfig.DEFAULT_FOLDER);
return createAndWriteDaemonConfig(configFileExample, defaultFolder);
}

public static DaemonConfigTO createAndWriteDaemonConfig(File configFile, File syncFolder) {
FolderTO defaultFolderTO = new FolderTO();
defaultFolderTO.setPath(syncFolder.getAbsolutePath());

ArrayList<FolderTO> folders = new ArrayList<FolderTO>();
folders.add(defaultFolderTO);

return createAndWriteConfig(configFile, folders);
}

public static DaemonConfigTO createAndWriteConfig(File configFile, ArrayList<FolderTO> folders) {
UserTO defaultUserTO = new UserTO();
defaultUserTO.setUsername(UserConfig.USER_ADMIN);
defaultUserTO.setPassword(CipherUtil.createRandomAlphabeticString(12));

ArrayList<UserTO> users = new ArrayList<UserTO>();
users.add(defaultUserTO);

DaemonConfigTO defaultDaemonConfigTO = new DaemonConfigTO();
defaultDaemonConfigTO.setFolders(folders);
defaultDaemonConfigTO.setUsers(users);

try {
DaemonConfigTO.save(defaultDaemonConfigTO, configFile);
}
catch (Exception e) {
// Don't care!
}

return defaultDaemonConfigTO;
}

// Key store / Trust store methods

private static void initUserTrustStore() {
Expand Down
10 changes: 9 additions & 1 deletion syncany-lib/src/main/java/org/syncany/config/to/FolderTO.java
Expand Up @@ -28,8 +28,16 @@ public class FolderTO {
private boolean enabled = true;

@Element(name="watch", required = false)
private WatchOperationOptions watchOptions = new WatchOperationOptions();
private WatchOperationOptions watchOptions;

public FolderTO() {
// Nothing!
}

public FolderTO(String path) {
this.path = path;
}

public String getPath() {
return path;
}
Expand Down
Expand Up @@ -19,15 +19,13 @@

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.syncany.config.Config;
import org.syncany.config.ConfigException;
import org.syncany.config.UserConfig;
import org.syncany.config.to.DaemonConfigTO;
import org.syncany.config.to.FolderTO;
import org.syncany.config.to.PortTO;
import org.syncany.config.to.UserTO;
import org.syncany.crypto.CipherUtil;
Expand Down Expand Up @@ -65,15 +63,8 @@
* @author Pim Otte
*/
public class DaemonOperation extends Operation {
private static final Logger logger = Logger.getLogger(DaemonOperation.class.getSimpleName());

private static final Logger logger = Logger.getLogger(DaemonOperation.class.getSimpleName());
private static final String PID_FILE = "daemon.pid";
private static final String DAEMON_FILE = "daemon.xml";
private static final String DAEMON_EXAMPLE_FILE = "daemon-example.xml";
private static final String DEFAULT_FOLDER = "Syncany";

private static final String USER_CLI = "CLI";
private static final String USER_ADMIN = "admin";

private File pidFile;

Expand Down Expand Up @@ -158,16 +149,16 @@ private void reloadOperation() {

private void loadOrCreateConfig() {
try {
File daemonConfigFile = new File(UserConfig.getUserConfigDir(), DAEMON_FILE);
File daemonConfigFileExample = new File(UserConfig.getUserConfigDir(), DAEMON_EXAMPLE_FILE);
File daemonConfigFile = new File(UserConfig.getUserConfigDir(), UserConfig.DAEMON_FILE);
File daemonConfigFileExample = new File(UserConfig.getUserConfigDir(), UserConfig.DAEMON_EXAMPLE_FILE);

if (daemonConfigFile.exists()) {
daemonConfig = DaemonConfigTO.load(daemonConfigFile);
}
else {
// Write example config to daemon-example.xml, and default config to daemon.xml
createAndWriteExampleConfig(daemonConfigFileExample);
daemonConfig = createAndWriteDefaultConfig(daemonConfigFile);
UserConfig.createAndWriteExampleDaemonConfig(daemonConfigFileExample);
daemonConfig = UserConfig.createAndWriteDefaultDaemonConfig(daemonConfigFile);
}

// Add user and password for access from the CLI
Expand All @@ -176,7 +167,7 @@ private void loadOrCreateConfig() {
String accessToken = CipherUtil.createRandomAlphabeticString(20);

UserTO cliUser = new UserTO();
cliUser.setUsername(USER_CLI);
cliUser.setUsername(UserConfig.USER_CLI);
cliUser.setPassword(accessToken);

portTO = new PortTO();
Expand All @@ -197,45 +188,7 @@ else if (daemonConfig.getPortTO() == null) {
catch (Exception e) {
logger.log(Level.WARNING, "Cannot (re-)load config. Exception thrown.", e);
}
}

private DaemonConfigTO createAndWriteDefaultConfig(File daemonConfigFile) {
return createAndWriteConfig(daemonConfigFile, new ArrayList<FolderTO>());
}

private DaemonConfigTO createAndWriteExampleConfig(File configFileExample) {
File defaultFolder = new File(System.getProperty("user.home"), DEFAULT_FOLDER);

FolderTO defaultFolderTO = new FolderTO();
defaultFolderTO.setPath(defaultFolder.getAbsolutePath());

ArrayList<FolderTO> folders = new ArrayList<FolderTO>();
folders.add(defaultFolderTO);

return createAndWriteConfig(configFileExample, folders);
}

private DaemonConfigTO createAndWriteConfig(File configFile, ArrayList<FolderTO> folders) {
UserTO defaultUserTO = new UserTO();
defaultUserTO.setUsername(USER_ADMIN);
defaultUserTO.setPassword(CipherUtil.createRandomAlphabeticString(12));

ArrayList<UserTO> users = new ArrayList<UserTO>();
users.add(defaultUserTO);

DaemonConfigTO defaultDaemonConfigTO = new DaemonConfigTO();
defaultDaemonConfigTO.setFolders(folders);
defaultDaemonConfigTO.setUsers(users);

try {
DaemonConfigTO.save(defaultDaemonConfigTO, configFile);
}
catch (Exception e) {
// Don't care!
}

return defaultDaemonConfigTO;
}
}

// Web server starting and stopping functions

Expand Down
Expand Up @@ -104,18 +104,23 @@ public void stop() {
private void startWatchOperations(Map<File, FolderTO> newWatchedFolderTOs) throws ConfigException, ServiceAlreadyStartedException {
for (Map.Entry<File, FolderTO> folderEntry : newWatchedFolderTOs.entrySet()) {
File localDir = folderEntry.getKey();
WatchOperationOptions watchOperationOptions = folderEntry.getValue().getWatchOptions();

try {
Config watchConfig = ConfigHelper.loadConfig(localDir);

if (watchConfig != null) {
logger.log(Level.INFO, "- Starting watch operation at " + localDir + " ...");

WatchRunner watchOperationThread = new WatchRunner(watchConfig, watchOperationOptions, portTO);
watchOperationThread.start();
WatchOperationOptions watchOptions = folderEntry.getValue().getWatchOptions();

if (watchOptions == null) {
watchOptions = new WatchOperationOptions();
}

WatchRunner watchRunner = new WatchRunner(watchConfig, watchOptions, portTO);
watchRunner.start();

watchOperations.put(localDir, watchOperationThread);
watchOperations.put(localDir, watchRunner);
}
else {
logger.log(Level.INFO, "- CANNOT start watch, because no config found at " + localDir + " ...");
Expand Down

0 comments on commit 1f92cf6

Please sign in to comment.