Merge branch 'master' of github.com:duplicati/duplicati

This commit is contained in:
Kenneth Skovhede
2018-02-22 09:50:34 +01:00
15 changed files with 229 additions and 29 deletions
+10 -2
View File
@@ -235,7 +235,7 @@ namespace Duplicati.Server
}
}
public LogEntry[] AfterID(long id, LogMessageType level)
public LogEntry[] AfterID(long id, LogMessageType level, int pagesize)
{
RenewTimeout(level);
UpdateLogLevel();
@@ -245,7 +245,15 @@ namespace Duplicati.Server
if (m_buffer == null)
return new LogEntry[0];
return m_buffer.FlatArray((x) => x.ID > id && x.Type >= level );
var buffer = m_buffer.FlatArray((x) => x.ID > id && x.Type >= level );
// Return the <page_size> newest entries
if (buffer.Length > pagesize) {
var index = buffer.Length - pagesize;
return buffer.Skip(index).Take(pagesize).ToArray();
}
else {
return buffer;
}
}
}
@@ -286,7 +286,7 @@ namespace Duplicati.Server.WebServer
else
{
response.Status = System.Net.HttpStatusCode.BadRequest;
response.Reason = "Missing XSRF Token";
response.Reason = "Missing XSRF Token. Please reload the page";
return true;
}
@@ -574,7 +574,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
var backup = Program.DataConnection.GetBackup(key);
if (backup == null)
{
info.ReportClientError("Invalid or missing backup id");
info.ReportClientError("Invalid or missing backup id", System.Net.HttpStatusCode.NotFound);
return;
}
@@ -29,13 +29,19 @@ namespace Duplicati.Server.WebServer.RESTMethods
var level_str = input["level"].Value ?? "";
var id_str = input["id"].Value ?? "";
int pagesize;
if (!int.TryParse(info.Request.QueryString["pagesize"].Value, out pagesize))
pagesize = 100;
pagesize = Math.Max(1, Math.Min(500, pagesize));
Library.Logging.LogMessageType level;
long id;
long.TryParse(id_str, out id);
Enum.TryParse(level_str, true, out level);
info.OutputOK(Program.LogHandler.AfterID(id, level));
info.OutputOK(Program.LogHandler.AfterID(id, level, pagesize));
}
else
{
@@ -204,19 +204,14 @@ ul.tabs {
}
.entries {
div.entryline {
div.entryline.clickable {
cursor: pointer;
}
}
.entries.livedata {
li {
height: 1.2em;
}
li.expanded {
height: auto;
overflow: auto;
}
}
@@ -1492,7 +1487,7 @@ body {
ul.entries {
li {
padding-top: 30px;
padding-top: 10px;
}
}
}
@@ -315,21 +315,26 @@ backupApp.controller('EditBackupController', function ($rootScope, $scope, $rout
return;
}
if ($scope.KeepType == 'time' || $scope.KeepType == '')
{
delete opts['keep-versions'];
delete opts['retention-policy'];
// Retention options are mutual exclusive -> allow only one to be selected at a time
function resetAllRetentionOptionsExcept(optionToKeep = '') {
['keep-versions', 'keep-time', 'retention-policy'].forEach(function(entry) {
if (entry != optionToKeep) {
delete opts[entry];
}
});
}
if ($scope.KeepType == 'versions' || $scope.KeepType == '')
{
delete opts['keep-time'];
delete opts['retention-policy'];
}
if ($scope.KeepType == 'smart' || $scope.KeepType == '')
{
delete opts['keep-versions'];
delete opts['keep-time'];
delete opts['retention-policy'];
if ($scope.KeepType == 'time') {
resetAllRetentionOptionsExcept('keep-time');
} else if ($scope.KeepType == 'versions') {
resetAllRetentionOptionsExcept('keep-versions');
} else if ($scope.KeepType == 'smart' || $scope.KeepType == 'custom') {
resetAllRetentionOptionsExcept('retention-policy');
} else {
resetAllRetentionOptionsExcept(); // keep none
}
if ($scope.KeepType == 'time' && (opts['keep-time'] || '').trim().length == 0)
@@ -32,7 +32,8 @@ backupApp.controller('LogController', function($scope, $routeParams, $timeout, S
resp.data.reverse();
$scope.LiveData.unshift.apply($scope.LiveData, resp.data);
$scope.LiveData.Length = Math.min(1000, $scope.LiveData.length);
$scope.LiveData.Length = Math.min(300, $scope.LiveData.length);
$scope.LiveData = $scope.LiveData.slice(0,$scope.LiveData.Length)
$scope.LiveRefreshing = false;
if ($scope.LiveRefreshPending)
@@ -34,7 +34,7 @@
<ul class="entries livedata">
<li ng-repeat="item in LiveData" ng-class="{expanded: expanded}">
<div ng-click="expanded = !expanded" class="entryline" ng-class="{noexception: item.Exception == null}">{{item.When | parsetimestamp}}: {{item.Message}}</div>
<div ng-click="expanded = !expanded" class="entryline" ng-class="{noexception: item.Exception == null, clickable: item.Exception != null}">{{item.When | parsetimestamp}}: {{item.Message}}</div>
<div ng-show="expanded &amp;&amp; item.Exception != null" class="prewrapped-text exceptiontext">{{item.Exception}}</div>
</li>
</ul>
+64
View File
@@ -0,0 +1,64 @@
# [Duplicati](https://www.duplicati.com)
Duplicati is a free, open source, backup client that securely stores encrypted, incremental, compressed backups on cloud storage services and remote file servers. It works with:
*Amazon S3, OneDrive, Google Drive, Rackspace Cloud Files, HubiC, Backblaze (B2), Amazon Cloud Drive (AmzCD), Swift / OpenStack, WebDAV, SSH (SFTP), FTP, and more!*
Duplicati is licensed under LGPL and available for Windows, OSX and Linux (.NET 4.5+ or Mono required).
## Available tags
* `beta` - the most recent beta release
* `experimental` - the most recent experimental release
* `canary` - the most recent canary release
* `latest` - an alias for `beta`
* specific versions like `2.0.2.1_beta_2017-08-01`
Images for the following OS/architecture combinations are available:
* `linux-amd64`
* `linux-arm32v7` - 32-bit ARMv7 devices like the Raspberry Pi 2
The default architecture is `linux-amd64`. To pull an image for another architecture, prepend the architecture string to the image tag, e.g. `linux-arm32v7-beta`.
## How to use this image
```console
$ docker run -p 8200:8200 -v /some/path:/some/path duplicati/duplicati
```
Then, open [http://localhost:8200](http://localhost:8200) on the host to access the Duplicati web interface and configure backups. Any host directory that you want to back up needs to be mounted into the container using the `-v` option.
### Preserving configuration
All configuration is stored in `/data` inside the container, so you can mount a volume at that path to preserve the configuration:
```console
$ docker run --name=duplicati -v duplicati-data:/data duplicati/duplicati
```
This allows you to delete and recreate the container without losing your configuration:
```console
$ docker rm duplicati
$ docker run --name=duplicati -v duplicati-data:/data duplicati/duplicati
```
### Using Duplicati CLI
Run the `duplicati-cli` command to use the Duplicati command-line interface:
```console
$ docker run --rm duplicati/duplicati duplicati-cli help
See duplicati.commandline.exe help <topic> for more information.
General: example, changelog
...
$ docker run --rm -v /home:/backup/home duplicati/duplicati duplicati-cli backup ssh://user@host /backup/home
```
### Specifying server arguments
To launch the Duplicati server with additional arguments, run the `duplicati-server` command:
```console
$ docker run duplicati/duplicati duplicati-server --log-level=debug
```
+71
View File
@@ -0,0 +1,71 @@
#!/bin/bash
if [ ! -f "$1" ]; then
echo "Please provide the filename of an existing zip build as the first argument"
exit
fi
ARCHITECTURES="amd64 arm32v7"
DEFAULT_ARCHITECTURE=amd64
DEFAULT_CHANNEL=beta
REPOSITORY=duplicati/duplicati
ARCHIVE_NAME=$(basename -s .zip $1)
VERSION=$(echo "${ARCHIVE_NAME}" | cut -d "-" -f 2-)
CHANNEL=$(echo "${ARCHIVE_NAME}" | cut -d "_" -f 2)
DIRNAME=duplicati
if [ -d "${DIRNAME}" ]; then
rm -rf "${DIRNAME}"
fi
unzip -d "${DIRNAME}" "$1"
for n in "../oem" "../../oem" "../../../oem"
do
if [ -d $n ]; then
echo "Installing OEM files"
cp -R $n "${DIRNAME}/webroot/"
fi
done
for n in "oem-app-name.txt" "oem-update-url.txt" "oem-update-key.txt" "oem-update-readme.txt" "oem-update-installid.txt"
do
for p in "../$n" "../../$n" "../../../$n"
do
if [ -f $p ]; then
echo "Installing OEM override file"
cp $p "${DIRNAME}"
fi
done
done
for arch in ${ARCHITECTURES}; do
tags="linux-${arch}-${VERSION} linux-${arch}-${CHANNEL}"
if [ ${CHANNEL} = ${DEFAULT_CHANNEL} ]; then
tags="linux-${arch}-latest ${tags}"
fi
if [ ${arch} = ${DEFAULT_ARCHITECTURE} ]; then
tags="${VERSION} ${CHANNEL} ${tags}"
fi
if [ ${CHANNEL} = ${DEFAULT_CHANNEL} -a ${arch} = ${DEFAULT_ARCHITECTURE} ]; then
tags="latest ${tags}"
fi
args=""
for tag in ${tags}; do
args="-t ${REPOSITORY}:${tag} ${args}"
done
docker build \
${args} \
--build-arg ARCH=${arch}/ \
--build-arg VERSION=${VERSION} \
--build-arg CHANNEL=${CHANNEL} \
--file context/Dockerfile \
.
for tag in ${tags}; do
docker push ${REPOSITORY}:${tag}
done
done
+31
View File
@@ -0,0 +1,31 @@
ARG ARCH=
FROM ${ARCH}mono:5-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
libmono-sqlite4.0-cil \
libmono-system-drawing4.0-cil \
referenceassemblies-pcl && \
rm -rf /var/lib/apt/lists && \
cert-sync /etc/ssl/certs/ca-certificates.crt
ENV TINI_VERSION v0.16.1
RUN curl -L -o /usr/sbin/tini https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-$(dpkg --print-architecture) && \
chmod 0755 /usr/sbin/tini
ENTRYPOINT ["/usr/sbin/tini", "--"]
ENV XDG_CONFIG_HOME=/data
VOLUME /data
COPY context/duplicati-cli context/duplicati-server /usr/bin/
RUN chmod 0755 /usr/bin/duplicati-cli /usr/bin/duplicati-server
ARG CHANNEL=
ARG VERSION=
ENV DUPLICATI_CHANNEL=${CHANNEL}
ENV DUPLICATI_VERSION=${VERSION}
COPY duplicati /opt/duplicati
EXPOSE 8200
CMD ["/usr/bin/duplicati-server", "--webservice-port=8200", "--webservice-interface=any"]
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
EXE_FILE=/opt/duplicati/Duplicati.CommandLine.exe
APP_NAME=Duplicati.CommandLine
exec -a "$APP_NAME" mono "$EXE_FILE" "$@"
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
EXE_FILE=/opt/duplicati/Duplicati.Server.exe
APP_NAME=DuplicatiServer
exec -a "$APP_NAME" mono "$EXE_FILE" "$@"
+1 -1
View File
@@ -26,7 +26,7 @@ REQUIRED_MINOR=0
VERSION_TITLE="Cannot launch $APP_NAME"
VERSION_MSG="$APP_NAME requires the Mono Framework version $REQUIRED_MAJOR.$REQUIRED_MINOR or later."
DOWNLOAD_URL="http://www.go-mono.com/mono-downloads/download.html"
DOWNLOAD_URL="http://www.mono-project.com/download/stable/#download-mac"
# Try to find system default Mono if an override was not supplied
if [ "z${MONO_BIN}" == "z" ]; then
+11
View File
@@ -136,6 +136,17 @@ mv "Installer/fedora/${RPMNAME}" "${UPDATE_TARGET}"
echo "Done building rpm package"
echo ""
echo ""
echo "Building Docker images ..."
cd Installer/Docker
bash build-images.sh ../../$1
cd ../..
echo "Done building Docker images"
echo ""
echo ""
echo "Building Windows instance in virtual machine"