borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgInstallation.java
@@ -22,8 +22,6 @@ private Logger log = LoggerFactory.getLogger(BorgInstallation.class); private static final BorgInstallation instance = new BorgInstallation(); private BorgVersion borgVersion = new BorgVersion(); public static BorgInstallation getInstance() { return instance; } @@ -35,36 +33,76 @@ return; } } String[] binary = getBinary(RunningMode.getOSType()); File file = download(binary); configuration.setBorgCommand(file.getAbsolutePath()); initialize(getBinary(RunningMode.getOSType())); if (version(configuration)) { return; } BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); log.warn("No working borg version found. Please configure a borg version with minimal version '" + borgVersion.getMinimumRequiredBorgVersion() + "'."); } /** * @return a clone of this.borgVersion. * Configures a new borg configuration if modifications was done. * @param oldVersion The old version before this current modification. */ public BorgVersion getVersion() { return new BorgVersion().copyFrom(borgVersion); public void configure(BorgVersion oldVersion) { Configuration configuration = ConfigurationHandler.getConfiguration(); BorgVersion newVersion = ServerConfiguration.get()._getBorgVersion(); boolean borgBinaryChanged = !StringUtils.equals(oldVersion.getBorgBinary(), newVersion.getBorgBinary()); boolean manualBorgCommand = "manual".equals(newVersion.getBorgBinary()); if (manualBorgCommand) { boolean borgCommandChanged = !StringUtils.equals(oldVersion.getBorgCommand(), newVersion.getBorgCommand()); if (borgCommandChanged) { configuration.setBorgCommand(newVersion.getBorgCommand()); version(configuration); } } else { if (borgBinaryChanged) { newVersion.setBorgCommand(oldVersion.getBorgCommand()); // Don't modify borg command, if not manual. initialize(getBinary(newVersion.getBorgBinary())); } else { newVersion.copyFrom(oldVersion); // Restore all old settings. } } } private boolean initialize(String[] binary) { if (binary == null) { return false; } Configuration configuration = ConfigurationHandler.getConfiguration(); File file = download(binary); BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); if (file != null) { configuration.setBorgCommand(file.getAbsolutePath()); borgVersion.setBorgCommand(file.getAbsolutePath()); borgVersion.setBorgBinary(binary[0]); } return version(configuration); } private boolean version(Configuration configuration) { String versionString = BorgCommands.version(); boolean versionOK = false; BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); String msg = null; if (versionString != null) { borgVersion.setVersion(versionString); int cmp = versionString.compareTo(borgVersion.getMinimumRequiredBorgVersion()); if (cmp < 0) { log.info("Found borg version '" + versionString + "' is less than minimum required version '" + borgVersion.getMinimumRequiredBorgVersion() + "'."); msg = "Found borg version '" + versionString + "' is less than minimum required version '" + borgVersion.getMinimumRequiredBorgVersion() + "'."; log.info(msg); } else { versionOK = true; log.info("Found borg '" + configuration.getBorgCommand() + "', version: " + versionString + " (equals to or newer than '" + borgVersion.getMinimumRequiredBorgVersion() + "', OK)."); msg = "Found borg '" + configuration.getBorgCommand() + "', version: " + versionString + " (equals to or newer than '" + borgVersion.getMinimumRequiredBorgVersion() + "', OK)."; log.info(msg); } } else { msg = "Couldn't execute borg command '" + configuration.getBorgCommand() + "'."; } borgVersion.setVersionOK(versionOK); borgVersion.setStatusMessage(msg); return versionOK; } @@ -81,9 +119,14 @@ os = "freebsd64"; break; } return getBinary(os); } private String[] getBinary(String os) { if (os == null) { return null; } BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); for (String[] binary : borgVersion.getBorgBinaries()) { if (binary[0].contains(os)) { return binary; @@ -107,6 +150,7 @@ // File already downloaded, nothing to do. return file; } BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); String url = borgVersion.getBinariesDownloadUrl() + getDownloadFilename(binary); log.info("Trying to download borg binary '" + binary[0] + "' (" + binary[1] + ") from url: " + url + "..."); HttpClientBuilder builder = HttpClients.custom() @@ -137,6 +181,7 @@ log.info("Creating binary directory: " + dir.getAbsolutePath()); dir.mkdirs(); } BorgVersion borgVersion = ServerConfiguration.get()._getBorgVersion(); return new File(dir, getDownloadFilename(binary) + "-" + borgVersion.getBinariesDownloadVersion()); } borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgVersion.java
@@ -24,6 +24,7 @@ * using a manual installed borg version. */ @Getter @Setter(AccessLevel.PACKAGE) private String borgBinary; /** * The path of the borg command to use. @@ -38,12 +39,16 @@ @Getter @Setter(AccessLevel.PACKAGE) private String version; @Getter @Setter(AccessLevel.PACKAGE) private String statusMessage; public BorgVersion copyFrom(BorgVersion other) { this.borgCommand = other.borgCommand; this.borgBinary = other.borgBinary; this.versionOK = other.versionOK; this.version = other.version; this.statusMessage = other.statusMessage; return this; } } borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java
@@ -4,7 +4,6 @@ import de.micromata.borgbutler.cache.ButlerCache; import de.micromata.borgbutler.config.Configuration; import de.micromata.borgbutler.config.ConfigurationHandler; import lombok.Getter; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,7 +18,6 @@ private int port = WEBSERVER_PORT_DEFAULT; private boolean webDevelopmentMode = WEB_DEVELOPMENT_MODE_PREF_DEFAULT; @Getter private BorgVersion borgVersion = new BorgVersion(); @JsonProperty public String getCacheDir() { @@ -34,6 +32,17 @@ return SUPPORTED_LANGUAGES; } /** * @return a clone of this.borgVersion. */ public BorgVersion getBorgVersion() { return new BorgVersion().copyFrom(borgVersion); } BorgVersion _getBorgVersion() { return this.borgVersion; } public static String getApplicationHome() { if (applicationHome == null) { applicationHome = System.getProperty("applicationHome"); borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ConfigurationRest.java
@@ -3,6 +3,8 @@ import de.micromata.borgbutler.cache.ButlerCache; import de.micromata.borgbutler.config.ConfigurationHandler; import de.micromata.borgbutler.json.JsonUtils; import de.micromata.borgbutler.server.BorgInstallation; import de.micromata.borgbutler.server.BorgVersion; import de.micromata.borgbutler.server.ServerConfiguration; import de.micromata.borgbutler.server.user.UserData; import de.micromata.borgbutler.server.user.UserManager; @@ -37,7 +39,9 @@ ConfigurationHandler configurationHandler = ConfigurationHandler.getInstance(); ServerConfiguration config = (ServerConfiguration)configurationHandler.getConfiguration(); ServerConfiguration srcConfig = JsonUtils.fromJson(ServerConfiguration.class, jsonConfig); BorgVersion oldBorgVersion = config.getBorgVersion(); config.copyFrom(srcConfig); BorgInstallation.getInstance().configure(oldBorgVersion); configurationHandler.save(); } borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/SystemInfoRest.java
@@ -2,8 +2,8 @@ import de.micromata.borgbutler.BorgQueueExecutor; import de.micromata.borgbutler.json.JsonUtils; import de.micromata.borgbutler.server.BorgInstallation; import de.micromata.borgbutler.server.BorgVersion; import de.micromata.borgbutler.server.ServerConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ * @see JsonUtils#toJson(Object, boolean) */ public String getStatistics() { BorgVersion borgVersion = BorgInstallation.getInstance().getVersion(); BorgVersion borgVersion = ServerConfiguration.get().getBorgVersion(); SystemInfo systemInfonfo = new SystemInfo() .setQueueStatistics(BorgQueueExecutor.getInstance().getStatistics()) .setConfigurationOK(borgVersion.isVersionOK()) borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx
@@ -1,5 +1,5 @@ import React from 'react'; import {Button} from 'reactstrap'; import {Alert} from 'reactstrap'; import { FormCheckbox, FormField, @@ -35,6 +35,8 @@ .then((data) => { this.setState({ loading: false, borgBinary: data.borgVersion.borgBinary, borgCommand: data.borgVersion.borgCommand, ...data }) }) @@ -58,7 +60,8 @@ showDemoRepos: true, maxArchiveContentCacheCapacityMb: 100, redirect: false, borgVersion: null borgCommand: null, borgBinary: null }; this.handleTextChange = this.handleTextChange.bind(this); @@ -84,7 +87,11 @@ port: this.state.port, maxArchiveContentCacheCapacityMb: this.state.maxArchiveContentCacheCapacityMb, webDevelopmentMode: this.state.webDevelopmentMode, showDemoRepos: this.state.showDemoRepos showDemoRepos: this.state.showDemoRepos, borgVersion: { borgCommand: this.state.borgCommand, borgBinary: this.state.borgBinary } }; return fetch(getRestServiceUrl("configuration/config"), { method: 'POST', @@ -114,6 +121,14 @@ return <ErrorAlertGenericRestFailure handleClick={this.loadConfig}/>; } const borgVersion = this.state.borgVersion; let borgStatus = <Alert color="success"> {`Borg version '${borgVersion.version}' is OK.`} </Alert> if (!borgVersion.versionOK) { borgStatus = <Alert color="danger"> {`${borgVersion.statusMessage}`} </Alert> } return ( <div> <form> @@ -121,8 +136,8 @@ <FormLabel>{'Borg command'}</FormLabel> <FormField length={2}> <FormSelect value={borgVersion.binary} name={'binary'} value={this.state.borgBinary} name={'borgBinary'} onChange={this.handleTextChange} hint={`Choose your OS and BorgButler will download and use a ready to run borg binary from ${borgVersion.binariesDownloadUrl} or choose a manual installed version.`} > @@ -132,15 +147,17 @@ <FormOption label={'Manual'} value={'manual'}/> </FormSelect> </FormField> <FormField length={6}> <FormField length={8}> <FormInput name={'borgCommand'} value={this.state.borgCommand} onChange={this.handleTextChange} placeholder="Enter path of borg command"/> placeholder="Enter path of borg command" disabled={this.state.borgBinary !== "manual"}/> </FormField> <FormField length={2}> <Button className={'outline-primary'} onClick={this.onCancel} hint={'Tests the borg version.'}>Test </Button> </FormGroup> <FormGroup> <FormField length={2} /> <FormField length={10}> {borgStatus} </FormField> </FormGroup> <FormLabelInputField label={'Port'} fieldLength={2} type="number" min={0} max={65535}