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.commons.lang3.StringUtils;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.io.InputStream;
|
|
public class BorgInstallation {
|
private Logger log = LoggerFactory.getLogger(BorgInstallation.class);
|
private static final BorgInstallation instance = new BorgInstallation();
|
|
public static BorgInstallation getInstance() {
|
return instance;
|
}
|
|
private BorgConfig borgConfig = new BorgConfig();
|
|
public void initialize() {
|
Configuration configuration = ConfigurationHandler.getConfiguration();
|
if (StringUtils.isNotBlank(configuration.getBorgCommand())) {
|
if (version(configuration)) {
|
return;
|
}
|
}
|
borgConfig.setVersion(configuration.getBorgVersion());
|
initialize(getBinary(RunningMode.getOSType()));
|
if (!borgConfig.isVersionOK()) {
|
log.warn("No working borg version found. Please configure a borg version with minimal version '" + borgConfig.getMinimumRequiredBorgVersion() + "'.");
|
}
|
}
|
|
/**
|
* Configures a new borg configuration if modifications was done.
|
*
|
* @param newConfiguration The new configuration with the (new) borg command to use (executable).
|
* @param newBorgConfig The new config, including the id of the borg binary (Mac OS X, Linux 64, manual etc.) and version.
|
*/
|
public void configure(ServerConfiguration newConfiguration, BorgConfig newBorgConfig) {
|
ServerConfiguration configuration = ServerConfiguration.get();
|
String oldBorgBinary = borgConfig.getBorgBinary();
|
String oldVersion = borgConfig.getVersion();
|
String newBorgBinary = newBorgConfig.getBorgBinary();
|
String newVersion = newConfiguration.getBorgVersion();
|
boolean borgBinaryChanged = !StringUtils.equals(oldBorgBinary, newBorgBinary) ||
|
!StringUtils.equals(oldVersion, newVersion);
|
borgConfig.setBorgBinary(newBorgBinary); // Update borg binary (if changed).
|
borgConfig.setVersion(newVersion);
|
boolean manualBorgCommand = "manual".equals( newBorgConfig.getBorgBinary());
|
if (manualBorgCommand) {
|
boolean borgCommandChanged = !StringUtils.equals(newConfiguration.getBorgCommand(), configuration.getBorgCommand());
|
if (borgCommandChanged) {
|
configuration.setBorgCommand(newConfiguration.getBorgCommand());
|
version(configuration);
|
}
|
} else {
|
if (borgBinaryChanged) {
|
initialize(getBinary(newBorgBinary));
|
}
|
newConfiguration.setBorgCommand(configuration.getBorgCommand()); // borg command of this class overwrites new configuration for mode != 'manual'.
|
newConfiguration.setBorgVersion(newVersion);
|
if (!StringUtils.equals(oldVersion, newVersion)) {
|
log.info("Version '" + oldVersion + "' -> '" + newVersion + "'.");
|
}
|
if (!StringUtils.equals(oldBorgBinary, newBorgBinary)) {
|
log.info("Binary '" + oldBorgBinary + "' -> '" + newBorgBinary + "'.");
|
}
|
}
|
}
|
|
private boolean initialize(String[] binary) {
|
if (binary == null) {
|
return false;
|
}
|
Configuration configuration = ConfigurationHandler.getConfiguration();
|
File file = download(binary);
|
if (file != null) {
|
configuration.setBorgCommand(file.getAbsolutePath());
|
borgConfig.setBorgBinary(binary[0]);
|
}
|
return version(configuration);
|
}
|
|
private boolean version(Configuration configuration) {
|
String borgCommand = configuration.getBorgCommand();
|
if (StringUtils.isNotBlank(borgCommand)) {
|
for (String[] borgBinary : borgConfig.getBorgBinaries()) {
|
if (borgCommand.contains(borgBinary[0])) {
|
borgConfig.setBorgBinary(borgBinary[0]);
|
break;
|
}
|
}
|
}
|
String versionString = BorgCommands.version();
|
boolean versionOK = false;
|
String msg = null;
|
if (versionString != null) {
|
borgConfig.setVersion(versionString);
|
int cmp = BorgConfig.compareVersions(versionString, borgConfig.getMinimumRequiredBorgVersion());
|
if (cmp < 0) {
|
msg = "Found borg version '" + versionString + "' is less than minimum required version '" + borgConfig.getMinimumRequiredBorgVersion() + "'.";
|
log.info(msg);
|
} else {
|
versionOK = true;
|
msg = "Found borg '" + configuration.getBorgCommand() + "', version: " + versionString + " (equals to or newer than '" + borgConfig.getMinimumRequiredBorgVersion()
|
+ "', OK).";
|
log.info(msg);
|
}
|
} else {
|
msg = "Couldn't execute borg command '" + configuration.getBorgCommand() + "'.";
|
}
|
borgConfig.setVersionOK(versionOK);
|
borgConfig.setStatusMessage(msg);
|
return versionOK;
|
}
|
|
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;
|
}
|
return getBinary(os);
|
}
|
|
private String[] getBinary(String os) {
|
if (os == null) {
|
return null;
|
}
|
for (String[] binary : borgConfig.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) {
|
File file = getBinaryFile(binary);
|
if (file.exists()) {
|
// File already downloaded, nothing to do.
|
return file;
|
}
|
String url = borgConfig.getBinariesDownloadUrl() + getDownloadFilename(binary);
|
log.info("Trying to download borg binary '" + binary[0] + "' (" + binary[1] + ") from url: " + url + "...");
|
HttpClientBuilder builder = HttpClients.custom()
|
.setDefaultRequestConfig(RequestConfig.custom()
|
.setCookieSpec(StandardCookieSpec.STRICT).build());
|
|
try (CloseableHttpClient httpClient = builder.build()) {
|
HttpGet getRequest = new HttpGet(url);
|
try (ClassicHttpResponse response = (ClassicHttpResponse) httpClient.execute(getRequest);
|
InputStream inputStream = response.getEntity().getContent()) {
|
|
int statusCode = response.getCode();
|
|
if (statusCode != 200) {
|
throw new RuntimeException("Failed : HTTP error code : " + statusCode);
|
}
|
|
FileUtils.copyInputStreamToFile(inputStream, file);
|
}
|
|
log.info("Downloaded: " + file.getAbsolutePath());
|
file.setExecutable(true, false);
|
return file;
|
} catch (IOException ex) {
|
log.error(ex.getMessage(), ex);
|
return null;
|
}
|
}
|
|
private File getBinaryFile(String[] binary) {
|
File dir = new File(ConfigurationHandler.getInstance().getWorkingDir(), "bin");
|
if (!dir.exists()) {
|
log.info("Creating binary directory: " + dir.getAbsolutePath());
|
dir.mkdirs();
|
}
|
return new File(dir, getDownloadFilename(binary) + "-" + borgConfig.getVersion());
|
}
|
|
private String getDownloadFilename(String[] binary) {
|
return "borg-" + binary[0];
|
}
|
|
private BorgInstallation() {
|
}
|
|
public BorgConfig getBorgConfig() {
|
return this.borgConfig;
|
}
|
}
|