From d46ddab639561a6bdfae72e560bb2b1c4e1dd9bf Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Mon, 14 Jan 2019 22:52:30 +0000
Subject: [PATCH] Auto-install borg...
---
borgbutler-server/src/main/java/de/micromata/borgbutler/server/RunningMode.java | 4 +
borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java | 14 ++++
borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgInstallation.java | 109 ++++++++++++++++++++++++++++++++++++
borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx | 4
borgbutler-server/src/test/java/de/micromata/borgbutler/server/BorgInstallationTest.java | 35 +++++++++++
5 files changed, 162 insertions(+), 4 deletions(-)
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
index 68fbdcf..996f873 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/config/Configuration.java
@@ -22,7 +22,9 @@
private static final String RESTORE_DIRNAME = "restore";
@Getter
- private String[][] binaries = {
+ private String binariesDownloadUrl = "https://github.com/borgbackup/borg/releases/download/1.1.8/";
+ @Getter
+ private String[][] borgBinaries = {
{"freebsd64", "FreeBSD 64"},
{"linux32", "Linux 32"},
{"linux64", "Linux 64"},
@@ -32,7 +34,17 @@
@Setter(AccessLevel.PACKAGE)
private File workingDir;
+ /**
+ * One of the values "macosx64", "linux64" etc. for using a binary provided by BorgButler or null / "manual" for
+ * using a manual installed borg version.
+ */
@Getter
+ private String borgBinary;
+ /**
+ * The path of the borg command to use.
+ */
+ @Getter
+ @Setter
private String borgCommand = "borg";
/**
* Default is 100 MB (approximately).
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgInstallation.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgInstallation.java
new file mode 100644
index 0000000..46b1490
--- /dev/null
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/BorgInstallation.java
@@ -0,0 +1,109 @@
+package de.micromata.borgbutler.server;
+
+import de.micromata.borgbutler.BorgCommands;
+import de.micromata.borgbutler.config.Configuration;
+import de.micromata.borgbutler.config.ConfigurationHandler;
+import org.apache.commons.io.FileUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+
+public class BorgInstallation {
+ private Logger log = LoggerFactory.getLogger(BorgInstallation.class);
+ private static final BorgInstallation instance = new BorgInstallation();
+
+ public static BorgInstallation getInstance() {
+ return instance;
+ }
+
+ public void initialize() {
+ Configuration configuration = ConfigurationHandler.getConfiguration();
+ String version = BorgCommands.version();
+ if (version != null) {
+ log.info("Using borg '" + configuration.getBorgCommand() + "', version: " + version);
+ return;
+ }
+ String[] binary = getBinary(RunningMode.getOSType());
+ download(binary);
+ }
+
+ private String[] getBinary(RunningMode.OSType osType) {
+ String os = null;
+ switch (osType) {
+ case MAC_OS:
+ os = "mac";
+ break;
+ case LINUX:
+ os = "linux64";
+ break;
+ case FREEBSD:
+ os = "freebsd64";
+ break;
+ }
+ if (os == null) {
+ return null;
+ }
+ for (String[] binary : ConfigurationHandler.getConfiguration().getBorgBinaries()) {
+ if (binary[0].contains(os)) {
+ return binary;
+ }
+ }
+ return null;
+ }
+
+ File download(RunningMode.OSType osType) {
+ String[] binary = getBinary(osType);
+ if (binary == null) {
+ log.info("Can't download binary (no binary found for OS '" + osType + "'.");
+ return null;
+ }
+ return download(binary);
+ }
+
+ private File download(String[] binary) {
+ String url = ConfigurationHandler.getConfiguration().getBinariesDownloadUrl() + "borg-" + binary[0];
+ log.info("Trying to download borg binary '" + binary[0] + "' (" + binary[1] + ") from url: " + url + "...");
+ HttpClientBuilder builder = HttpClients.custom()
+ .setDefaultRequestConfig(RequestConfig.custom()
+ .setCookieSpec(CookieSpecs.STANDARD).build());
+ try (CloseableHttpClient httpClient = builder.build()) {
+ HttpGet getRequest = new HttpGet(url);
+
+ HttpResponse response = httpClient.execute(getRequest);
+
+ if (response.getStatusLine().getStatusCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + response.getStatusLine().getStatusCode());
+ }
+ File file = new File(getBinaryDir(), "borg-" + binary[0]);
+ FileUtils.copyInputStreamToFile(response.getEntity().getContent(), file);
+ log.info("Downloaded: " + file.getAbsolutePath());
+ file.setExecutable(true, false);
+ return file;
+ } catch (IOException ex) {
+ log.error(ex.getMessage(), ex);
+ return null;
+ }
+ }
+
+ private File getBinaryDir() {
+ File dir = new File(ConfigurationHandler.getInstance().getWorkingDir(), "bin");
+ if (!dir.exists()) {
+ log.info("Creating binary directory: " + dir.getAbsolutePath());
+ dir.mkdirs();
+ }
+ return dir;
+ }
+
+ private BorgInstallation() {
+ }
+}
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/RunningMode.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/RunningMode.java
index a3940ef..3da4739 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/RunningMode.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/RunningMode.java
@@ -16,7 +16,7 @@
public enum UserManagement {SINGLE}
- public enum OSType {MAC_OS, WINDOWS, LINUX, OTHER}
+ public enum OSType {MAC_OS, WINDOWS, LINUX, FREEBSD, OTHER}
private static boolean running;
private static File baseDir;
@@ -49,6 +49,8 @@
osType = OSType.WINDOWS;
} else if (osTypeString.toLowerCase().contains("linux")) {
osType = OSType.LINUX;
+ } else if (osTypeString.toLowerCase().contains("freebsd")) {
+ osType = OSType.FREEBSD;
} else {
osType = OSType.OTHER;
}
diff --git a/borgbutler-server/src/test/java/de/micromata/borgbutler/server/BorgInstallationTest.java b/borgbutler-server/src/test/java/de/micromata/borgbutler/server/BorgInstallationTest.java
new file mode 100644
index 0000000..f898948
--- /dev/null
+++ b/borgbutler-server/src/test/java/de/micromata/borgbutler/server/BorgInstallationTest.java
@@ -0,0 +1,35 @@
+package de.micromata.borgbutler.server;
+
+import de.micromata.borgbutler.config.ConfigurationHandler;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class BorgInstallationTest {
+ private Logger log = LoggerFactory.getLogger(BorgInstallationTest.class);
+
+ @Test
+ void foo() throws Exception {
+ ConfigurationHandler.getConfiguration().setBorgCommand("hurzel");
+ BorgInstallation borgInstallation = BorgInstallation.getInstance();
+ borgInstallation.initialize();
+ }
+
+ @Test
+ void downloadTest() {
+ checkDownload(RunningMode.OSType.LINUX, "borg-linux64");
+ checkDownload(RunningMode.OSType.MAC_OS, "borg-macosx64");
+ checkDownload(RunningMode.OSType.FREEBSD, "borg-freebsd64");
+ assertNull(BorgInstallation.getInstance().download(RunningMode.OSType.WINDOWS));
+ }
+
+ private void checkDownload(RunningMode.OSType osType, String expectedName) {
+ File file = BorgInstallation.getInstance().download(osType);
+ assertEquals(expectedName, file.getName());
+ assertTrue(file.canExecute());
+ }
+}
diff --git a/borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx b/borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx
index 3143c7e..b38500e 100644
--- a/borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx
+++ b/borgbutler-webapp/src/components/views/config/ConfigurationServerTab.jsx
@@ -124,9 +124,9 @@
value={this.state.binary}
name={'binary'}
onChange={this.handleTextChange}
- hint={'Choose your OS and BorgButler will download and use a ready to run borg binary from https://github.com/borgbackup/borg/releases or choose a manual installed version.'}
+ hint={`Choose your OS and BorgButler will download and use a ready to run borg binary from ${this.state.binariesDownloadUrl} or choose a manual installed version.`}
>
- {this.state.binaries
+ {this.state.borgBinaries
.map((binary, index) => <FormOption label={binary[1]} value={binary[0]}
key={index}/>)}
<FormOption label={'Manual'} value={'manual'}/>
--
Gitblit v1.10.0