Merge remote-tracking branch 'upstream/master' into test/recovery_tool
This commit is contained in:
+1
-1
@@ -69,7 +69,7 @@ jobs:
|
||||
directories:
|
||||
- $BUILD_DIR
|
||||
script:
|
||||
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler
|
||||
- ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler,RepairHandler
|
||||
|
||||
- stage: tests
|
||||
cache:
|
||||
|
||||
@@ -850,7 +850,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
{
|
||||
string optstr = Environment.GetEnvironmentVariable(string.Format(UPDATE_STRATEGY_ENVNAME_TEMPLATE, APPNAME));
|
||||
AutoUpdateStrategy strategy;
|
||||
if (string.IsNullOrWhiteSpace(optstr) || !Enum.TryParse(optstr, out strategy))
|
||||
if (string.IsNullOrWhiteSpace(optstr) || !Enum.TryParse(optstr, true, out strategy))
|
||||
strategy = defaultstrategy;
|
||||
|
||||
System.Threading.Thread backgroundChecker = null;
|
||||
|
||||
@@ -309,138 +309,134 @@ namespace Duplicati.Library.Main.Operation
|
||||
}
|
||||
else if (n.Type == RemoteVolumeType.Index)
|
||||
{
|
||||
using (IndexVolumeWriter w = new IndexVolumeWriter(m_options))
|
||||
IndexVolumeWriter w = new IndexVolumeWriter(m_options);
|
||||
newEntry = w;
|
||||
w.SetRemoteFilename(n.Name);
|
||||
|
||||
var h = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
|
||||
|
||||
foreach (var blockvolume in db.GetBlockVolumesFromIndexName(n.Name))
|
||||
{
|
||||
newEntry = w;
|
||||
w.SetRemoteFilename(n.Name);
|
||||
w.StartVolume(blockvolume.Name);
|
||||
var volumeid = db.GetRemoteVolumeID(blockvolume.Name);
|
||||
|
||||
var h = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
|
||||
foreach (var b in db.GetBlocks(volumeid))
|
||||
w.AddBlock(b.Hash, b.Size);
|
||||
|
||||
foreach (var blockvolume in db.GetBlockVolumesFromIndexName(n.Name))
|
||||
{
|
||||
w.StartVolume(blockvolume.Name);
|
||||
var volumeid = db.GetRemoteVolumeID(blockvolume.Name);
|
||||
w.FinishVolume(blockvolume.Hash, blockvolume.Size);
|
||||
|
||||
foreach (var b in db.GetBlocks(volumeid))
|
||||
w.AddBlock(b.Hash, b.Size);
|
||||
if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full)
|
||||
foreach (var b in db.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
|
||||
{
|
||||
var bh = Convert.ToBase64String(h.ComputeHash(b.Item2, 0, b.Item3));
|
||||
if (bh != b.Item1)
|
||||
throw new Exception(string.Format("Internal consistency check failed, generated index block has wrong hash, {0} vs {1}", bh, b.Item1));
|
||||
|
||||
w.FinishVolume(blockvolume.Hash, blockvolume.Size);
|
||||
w.WriteBlocklist(b.Item1, b.Item2, 0, b.Item3);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full)
|
||||
foreach (var b in db.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
|
||||
{
|
||||
var bh = Convert.ToBase64String(h.ComputeHash(b.Item2, 0, b.Item3));
|
||||
if (bh != b.Item1)
|
||||
throw new Exception(string.Format("Internal consistency check failed, generated index block has wrong hash, {0} vs {1}", bh, b.Item1));
|
||||
w.Close();
|
||||
|
||||
w.WriteBlocklist(b.Item1, b.Item2, 0, b.Item3);
|
||||
}
|
||||
}
|
||||
|
||||
w.Close();
|
||||
|
||||
if (m_options.Dryrun)
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadIndexFile", "would re-upload index file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
|
||||
else
|
||||
{
|
||||
db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
|
||||
backend.Put(w);
|
||||
}
|
||||
if (m_options.Dryrun)
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadIndexFile", "would re-upload index file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
|
||||
else
|
||||
{
|
||||
db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
|
||||
backend.Put(w);
|
||||
}
|
||||
}
|
||||
else if (n.Type == RemoteVolumeType.Blocks)
|
||||
{
|
||||
using (BlockVolumeWriter w = new BlockVolumeWriter(m_options))
|
||||
BlockVolumeWriter w = new BlockVolumeWriter(m_options);
|
||||
newEntry = w;
|
||||
w.SetRemoteFilename(n.Name);
|
||||
|
||||
using (var mbl = db.CreateBlockList(n.Name))
|
||||
{
|
||||
newEntry = w;
|
||||
w.SetRemoteFilename(n.Name);
|
||||
|
||||
using (var mbl = db.CreateBlockList(n.Name))
|
||||
//First we grab all known blocks from local files
|
||||
foreach (var block in mbl.GetSourceFilesWithBlocks(m_options.Blocksize))
|
||||
{
|
||||
//First we grab all known blocks from local files
|
||||
foreach (var block in mbl.GetSourceFilesWithBlocks(m_options.Blocksize))
|
||||
var hash = block.Hash;
|
||||
var size = (int) block.Size;
|
||||
|
||||
foreach (var source in block.Sources)
|
||||
{
|
||||
var hash = block.Hash;
|
||||
var size = (int) block.Size;
|
||||
var file = source.File;
|
||||
var offset = source.Offset;
|
||||
|
||||
foreach (var source in block.Sources)
|
||||
{
|
||||
var file = source.File;
|
||||
var offset = source.Offset;
|
||||
|
||||
try
|
||||
{
|
||||
if (System.IO.File.Exists(file))
|
||||
using (var f = System.IO.File.OpenRead(file))
|
||||
{
|
||||
f.Position = offset;
|
||||
if (size == Library.Utility.Utility.ForceStreamRead(f, buffer, size))
|
||||
{
|
||||
var newhash = Convert.ToBase64String(blockhasher.ComputeHash(buffer, 0, size));
|
||||
if (newhash == hash)
|
||||
{
|
||||
if (mbl.SetBlockRestored(hash, size))
|
||||
w.AddBlock(hash, buffer, 0, size, Duplicati.Library.Interface.CompressionHint.Default);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log.WriteErrorMessage(LOGTAG, "FileAccessError", ex, "Failed to access file: {0}", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Then we grab all remote volumes that have the missing blocks
|
||||
foreach (var vol in new AsyncDownloader(mbl.GetMissingBlockSources().ToList(), backend))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var tmpfile = vol.TempFile)
|
||||
using (var f = new BlockVolumeReader(RestoreHandler.GetCompressionModule(vol.Name), tmpfile, m_options))
|
||||
foreach (var b in f.Blocks)
|
||||
if (mbl.SetBlockRestored(b.Key, b.Value))
|
||||
if (f.ReadBlock(b.Key, buffer) == b.Value)
|
||||
w.AddBlock(b.Key, buffer, 0, (int) b.Value, Duplicati.Library.Interface.CompressionHint.Default);
|
||||
if (System.IO.File.Exists(file))
|
||||
using (var f = System.IO.File.OpenRead(file))
|
||||
{
|
||||
f.Position = offset;
|
||||
if (size == Library.Utility.Utility.ForceStreamRead(f, buffer, size))
|
||||
{
|
||||
var newhash = Convert.ToBase64String(blockhasher.ComputeHash(buffer, 0, size));
|
||||
if (newhash == hash)
|
||||
{
|
||||
if (mbl.SetBlockRestored(hash, size))
|
||||
w.AddBlock(hash, buffer, 0, size, Duplicati.Library.Interface.CompressionHint.Default);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log.WriteErrorMessage(LOGTAG, "RemoteFileAccessError", ex, "Failed to access remote file: {0}", vol.Name);
|
||||
Logging.Log.WriteErrorMessage(LOGTAG, "FileAccessError", ex, "Failed to access file: {0}", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we managed to recover all blocks, NICE!
|
||||
var missingBlocks = mbl.GetMissingBlocks().Count();
|
||||
if (missingBlocks > 0)
|
||||
//Then we grab all remote volumes that have the missing blocks
|
||||
foreach (var vol in new AsyncDownloader(mbl.GetMissingBlockSources().ToList(), backend))
|
||||
{
|
||||
try
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RepairMissingBlocks", "Repair cannot acquire {0} required blocks for volume {1}, which are required by the following filesets: ", missingBlocks, n.Name);
|
||||
foreach (var f in mbl.GetFilesetsUsingMissingBlocks())
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "AffectedFilesetName", f.Name);
|
||||
using (var tmpfile = vol.TempFile)
|
||||
using (var f = new BlockVolumeReader(RestoreHandler.GetCompressionModule(vol.Name), tmpfile, m_options))
|
||||
foreach (var b in f.Blocks)
|
||||
if (mbl.SetBlockRestored(b.Key, b.Value))
|
||||
if (f.ReadBlock(b.Key, buffer) == b.Value)
|
||||
w.AddBlock(b.Key, buffer, 0, (int) b.Value, Duplicati.Library.Interface.CompressionHint.Default);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log.WriteErrorMessage(LOGTAG, "RemoteFileAccessError", ex, "Failed to access remote file: {0}", vol.Name);
|
||||
}
|
||||
}
|
||||
|
||||
var recoverymsg = string.Format("If you want to continue working with the database, you can use the \"{0}\" and \"{1}\" commands to purge the missing data from the database and the remote storage.", "list-broken-files", "purge-broken-files");
|
||||
// If we managed to recover all blocks, NICE!
|
||||
var missingBlocks = mbl.GetMissingBlocks().Count();
|
||||
if (missingBlocks > 0)
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RepairMissingBlocks", "Repair cannot acquire {0} required blocks for volume {1}, which are required by the following filesets: ", missingBlocks, n.Name);
|
||||
foreach (var f in mbl.GetFilesetsUsingMissingBlocks())
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "AffectedFilesetName", f.Name);
|
||||
|
||||
if (!m_options.Dryrun)
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", "This may be fixed by deleting the filesets and running repair again");
|
||||
var recoverymsg = string.Format("If you want to continue working with the database, you can use the \"{0}\" and \"{1}\" commands to purge the missing data from the database and the remote storage.", "list-broken-files", "purge-broken-files");
|
||||
|
||||
throw new UserInformationException(string.Format("Repair not possible, missing {0} blocks.\n" + recoverymsg, missingBlocks), "RepairIsNotPossible");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", recoverymsg);
|
||||
}
|
||||
if (!m_options.Dryrun)
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", "This may be fixed by deleting the filesets and running repair again");
|
||||
|
||||
throw new UserInformationException(string.Format("Repair not possible, missing {0} blocks.\n" + recoverymsg, missingBlocks), "RepairIsNotPossible");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_options.Dryrun)
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadBlockFile", "would re-upload block file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
|
||||
else
|
||||
{
|
||||
db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
|
||||
backend.Put(w);
|
||||
}
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "RecoverySuggestion", recoverymsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_options.Dryrun)
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "WouldReUploadBlockFile", "would re-upload block file {0}, with size {1}, previous size {2}", n.Name, Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(w.LocalFilename).Length), Library.Utility.Utility.FormatSizeString(n.Size));
|
||||
else
|
||||
{
|
||||
db.UpdateRemoteVolume(w.RemoteFilename, RemoteVolumeState.Uploading, -1, null, null);
|
||||
backend.Put(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ namespace Duplicati.Library.UsageReporter
|
||||
{
|
||||
var str = Environment.GetEnvironmentVariable(string.Format(DISABLED_ENVNAME_TEMPLATE, AutoUpdater.AutoUpdateSettings.AppName));
|
||||
ReportType tmp;
|
||||
if (string.IsNullOrWhiteSpace(str) || !Enum.TryParse(str, out tmp))
|
||||
if (string.IsNullOrWhiteSpace(str) || !Enum.TryParse(str, true, out tmp))
|
||||
Cached_MaxReportLevel = ReportType.Information;
|
||||
else
|
||||
Cached_MaxReportLevel = tmp;
|
||||
|
||||
@@ -204,4 +204,4 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\NUnit.3.12.0\build\NUnit.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Duplicati.Library.Main;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Duplicati.UnitTest
|
||||
{
|
||||
[TestFixture]
|
||||
public class RepairHandlerTests : BasicSetupHelper
|
||||
{
|
||||
public override void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
File.WriteAllBytes(Path.Combine(this.DATAFOLDER, "file"), new byte[] {0});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Category("RepairHandler")]
|
||||
[TestCase("true")]
|
||||
[TestCase("false")]
|
||||
public void RepairMissingIndexFiles(string noEncryption)
|
||||
{
|
||||
Dictionary<string, string> options = new Dictionary<string, string>(this.TestOptions) {["no-encryption"] = noEncryption};
|
||||
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
|
||||
{
|
||||
c.Backup(new[] {this.DATAFOLDER});
|
||||
}
|
||||
|
||||
string[] dindexFiles = Directory.EnumerateFiles(this.TARGETFOLDER, "*dindex*").ToArray();
|
||||
Assert.Greater(dindexFiles.Length, 0);
|
||||
foreach (string f in dindexFiles)
|
||||
{
|
||||
File.Delete(f);
|
||||
}
|
||||
|
||||
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
|
||||
{
|
||||
c.Repair();
|
||||
}
|
||||
|
||||
foreach (string file in dindexFiles)
|
||||
{
|
||||
Assert.IsTrue(File.Exists(Path.Combine(this.TARGETFOLDER, file)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,12 @@ RUN dnf -y install deltarpm
|
||||
RUN dnf -y upgrade
|
||||
RUN dnf -y --allowerasing install @"Minimal Install" @buildsys-build yum-utils rpm-sign gnupg rpmdevtools
|
||||
|
||||
# Install real mono for building
|
||||
# Instructions from here: https://www.mono-project.com/download/stable/#download-lin-fedora
|
||||
RUN rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
|
||||
RUN curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo
|
||||
RUN dnf -y update
|
||||
|
||||
# Install mono things
|
||||
RUN dnf -y install mono-devel gnome-sharp-devel dos2unix git nuget
|
||||
|
||||
|
||||
+15
-3
@@ -26,6 +26,9 @@ MONO=/Library/Frameworks/Mono.framework/Commands/mono
|
||||
|
||||
GPG=/usr/local/bin/gpg2
|
||||
|
||||
# Newer GPG needs this to allow input from a non-terminal
|
||||
export GPG_TTY=$(tty)
|
||||
|
||||
ZIPFILE=$(basename "$1")
|
||||
VERSION=$(echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 1)
|
||||
BUILDTYPE=$(echo "${ZIPFILE}" | cut -d "-" -f 2 | cut -d "_" -f 2)
|
||||
@@ -52,9 +55,18 @@ echo "DEBName: ${DEBNAME}"
|
||||
echo "SPKName: ${SPKNAME}"
|
||||
|
||||
build_file_signatures() {
|
||||
if [ "z${GPGID}" != "z" ]; then
|
||||
echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--output" "$2.sig" "--detach-sig" "$1"
|
||||
echo "$GPGKEY" | "${GPG}" "--passphrase-fd" "0" "--batch" "--yes" "--default-key=${GPGID}" "--armor" "--output" "$2.sig.asc" "--detach-sig" "$1"
|
||||
if [ -f "${GPG_KEYFILE}" ]; then
|
||||
"${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
|
||||
--inputfile=\"$1\" \
|
||||
--signaturefile=\"$2.sig\" \
|
||||
--armor=false --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
|
||||
--keyfile-password="${KEYFILE_PASSWORD}"
|
||||
|
||||
"${MONO}" "BuildTools/GnupgSigningTool/bin/Debug/GnupgSigningTool.exe" \
|
||||
--inputfile=\"$1\" \
|
||||
--signaturefile=\"$2.sig.asc\" \
|
||||
--armor=true --gpgkeyfile="${GPG_KEYFILE}" --gpgpath="${GPG}" \
|
||||
--keyfile-password="${KEYFILE_PASSWORD}"
|
||||
fi
|
||||
|
||||
md5 "$1" | awk -F ' ' '{print $NF}' > "$2.md5"
|
||||
|
||||
+23
-11
@@ -33,6 +33,8 @@ XBUILD=/Library/Frameworks/Mono.framework/Commands/msbuild
|
||||
NUGET=/Library/Frameworks/Mono.framework/Commands/nuget
|
||||
MONO=/Library/Frameworks/Mono.framework/Commands/mono
|
||||
GPG=/usr/local/bin/gpg2
|
||||
AWS=/usr/local/bin/aws
|
||||
GITHUB_RELEASE=/usr/local/bin/github-release
|
||||
|
||||
# Newer GPG needs this to allow input from a non-terminal
|
||||
export GPG_TTY=$(tty)
|
||||
@@ -57,6 +59,18 @@ if [ ! -f "$NUGET" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$AWS" ]; then
|
||||
echo "aws-cli not found: $AWS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$GITHUB_RELEASE" ]; then
|
||||
echo "github-release executable not found: $GITHUB_RELEASE"
|
||||
echo "Grab it from: https://github.com/aktau/github-release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# The "OTHER_UPLOADS" setting is no longer used
|
||||
if [ "${RELEASE_TYPE}" == "nightly" ]; then
|
||||
OTHER_UPLOADS=""
|
||||
@@ -281,12 +295,12 @@ cp "${UPDATE_TARGET}/latest.zip.sig.asc" "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.
|
||||
"${MONO}" "BuildTools/UpdateVersionStamp/bin/Debug/UpdateVersionStamp.exe" --version="2.0.0.7"
|
||||
|
||||
echo "Uploading binaries"
|
||||
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
|
||||
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig"
|
||||
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc"
|
||||
aws --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip.sig.asc" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.zip.sig.asc"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "${UPDATE_TARGET}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest"
|
||||
|
||||
aws --profile=duplicati-upload s3 cp "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.manifest"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "s3://updates.duplicati.com/${RELEASE_TYPE}/${RELEASE_FILE_NAME}.manifest" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.manifest"
|
||||
|
||||
ZIP_MD5=$(md5 ${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip | awk -F ' ' '{print $NF}')
|
||||
ZIP_SHA1=$(shasum -a 1 ${UPDATE_TARGET}/${RELEASE_FILE_NAME}.zip | awk -F ' ' '{print $1}')
|
||||
@@ -311,8 +325,8 @@ echo "duplicati_version_info =" > "latest.js"
|
||||
cat "latest.json" >> "latest.js"
|
||||
echo ";" >> "latest.js"
|
||||
|
||||
aws --profile=duplicati-upload s3 cp "latest.json" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.json"
|
||||
aws --profile=duplicati-upload s3 cp "latest.js" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.js"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "latest.json" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.json"
|
||||
"${AWS}" --profile=duplicati-upload s3 cp "latest.js" "s3://updates.duplicati.com/${RELEASE_TYPE}/latest.js"
|
||||
|
||||
# echo "Propagating to other build types"
|
||||
# for OTHER in ${OTHER_UPLOADS}; do
|
||||
@@ -338,14 +352,12 @@ fi
|
||||
|
||||
RELEASE_MESSAGE=$(printf "Changes in this version:\n${RELEASE_CHANGEINFO_NEWS}")
|
||||
|
||||
# Using the tool from https://github.com/aktau/github-release
|
||||
|
||||
GITHUB_TOKEN=$(cat "${GITHUB_TOKEN_FILE}")
|
||||
|
||||
if [ "x${GITHUB_TOKEN}" == "x" ]; then
|
||||
echo "No GITHUB_TOKEN found in environment, you can manually upload the binaries"
|
||||
else
|
||||
github-release release ${PRE_RELEASE_LABEL} \
|
||||
"${GITHUB_RELEASE}" release ${PRE_RELEASE_LABEL} \
|
||||
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
|
||||
--name "v${RELEASE_VERSION}-${RELEASE_NAME}" \
|
||||
--repo "duplicati" \
|
||||
@@ -353,7 +365,7 @@ else
|
||||
--security-token "${GITHUB_TOKEN}" \
|
||||
--description "${RELEASE_MESSAGE}" \
|
||||
|
||||
github-release upload \
|
||||
"${GITHUB_RELEASE}" upload \
|
||||
--tag "v${RELEASE_VERSION}-${RELEASE_NAME}" \
|
||||
--name "${RELEASE_FILE_NAME}.zip" \
|
||||
--repo "duplicati" \
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ ${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNormal
|
||||
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories BulkNoSize
|
||||
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories SVNDataLong,SVNData,RecoveryTool
|
||||
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Border
|
||||
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler
|
||||
${ROOT_DIR}/pipeline/jobs/unittest_job.sh --testcategories Filter,Targeted,Purge,Serialization,WebApi,Utility,UriUtility,IO,ImportExport,Disruption,RestoreHandler,RepairHandler
|
||||
|
||||
|
||||
Reference in New Issue
Block a user