remove FirmwareCiDaemon.csproj

This commit is contained in:
ig 2023-02-23 16:00:58 +01:00
parent 45bd531206
commit 95048e42d6
15 changed files with 0 additions and 933 deletions

View File

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../InnovEnergy.app.props" />
<PropertyGroup>
<RootNamespace>InnovEnergy.Server.FirmwareCiDaemon</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Reactive.Linq" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../lib/Utils/Utils.csproj" />
</ItemGroup>
</Project>

View File

@ -1,21 +0,0 @@
namespace InnovEnergy.Server.FirmwareCiDaemon;
public enum Branch
{
Release,
Develop,
Victron,
}
public static class BranchExtensions
{
public static String GetName(this Branch branch) => branch switch
{
Branch.Victron => "venus.victron",
Branch.Release => "venus.release",
Branch.Develop => "venus",
_ => throw new Exception($"Unsupported branch: {branch}")
};
}

View File

@ -1,295 +0,0 @@
using System.Text.RegularExpressions;
using CliWrap;
using InnovEnergy.Lib.Utils;
using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public record Build
{
private static readonly Regex RxTimestamp = new Regex(@"\d{14}");
private static readonly Regex RxVersion = new Regex(@"v\d+\.\d+(~\w+)?");
private const Int32 MaxPublishedSwus = 12;
public Device Device { get; init; }
public String VeVersion { get; init; }
public Branch Branch { get; init; }
public String Comment { get; init; }
public String Hash { get; init; }
public String ShortHash => Hash[..6];
public Channel Channel => Branch switch
{
Branch.Victron => Channel.Testing,
Branch.Release => Channel.Release,
Branch.Develop => Channel.Develop,
_ => throw new Exception($"Unsupported branch: {Branch}")
};
public String VersionId => Branch switch
{
Branch.Victron => $"{VeVersion}~victron",
Branch.Release => $"{VeVersion}~{Comment}",
Branch.Develop => $"{VeVersion}~{ShortHash}",
_ => throw new Exception($"Unsupported branch: {Branch}")
};
public static Build Prepare(CommitInfo ie, (Device device, String veVersion) ve)
{
return new Build
{
Device = ve.device,
VeVersion = ve.veVersion,
Branch = ie.Branch,
Comment = ie.Comment,
Hash = ie.Hash
};
}
public void Execute()
{
Log();
Log("======================================================");
Log("Starting build");
Log("======================================================");
Log();
Log($"VE Version: {VeVersion}");
Log($"Channel : {Channel}");
Log($"Device : {Device}");
Log($"Branch : {Branch}");
Log($"Comment : {Comment}");
Log($"Version ID: {VersionId}");
Log($"SWU Name : {Device.SwuName()}");
Log($"Hash : {Hash}");
Log();
Log("======================================================");
Log();
using var veBaseSwuFile = FwSource.Victron.GetLatestSwuPath(Channel.Release, Device).Apply(DownloadFile);
using var ieRepo = Fossil.Checkout(Branch);
using var releaseSwu = MergeSwu(veBaseSwuFile, ieRepo.FirmwareDirectory, Device, VersionId);
var publishedSwu = PublishSwu(Device, Channel, releaseSwu);
RemoveOldFiles(Device, Channel);
var zipPath = Channel.ZipPath();
var removeGlob = Device.SwuBase() + "*";
if (zipPath is null)
return;
Log($"Updating {zipPath[Program.IeBasePath.Length..]}");
zipPath.RemoveFromZip(removeGlob);
zipPath.AddToZip(publishedSwu);
}
public static Disposable<String> DownloadFile(String url)
{
var fileName = Path.GetFileName(url);
var downloadedFile = FileSystem.CreateTempFile(fileName);
Log($"downloading {url}");
var curl = Cli
.Wrap("curl")
.WithArguments(url)
.PipeToFile(downloadedFile);
if (curl.exitCode != 0)
Exit("Failed to download " + url);
return downloadedFile;
}
private static void UpdateVersionFile(String fwDir, String version, String timestamp, String file)
{
Log($"updating {file}");
var fwFile = fwDir.AppendPath(file);
if (!FileSystem.Local.FileExists(fwFile))
Exit($"Cannot find {fwFile}");
var contents = File.ReadAllText(fwFile);
contents = RxTimestamp.Replace(contents, timestamp);
contents = RxVersion.Replace(contents, version);
try
{
File.WriteAllText(fwFile, contents);
}
catch
{
Exit($"Failed to write to {fwFile}");
}
}
private static void PatchIeFiles(String fossilDir, String mountDir)
{
Log("applying changes");
var (exitCode, stdOut, stdErr) = Cli
.Wrap("rsync")
.WithArguments($"-r -t -v -l -i -u -I {fossilDir}/ {mountDir}") // that / is important!
.ExecuteSync();
if (exitCode != 0)
Exit($"Failed to apply changes!\n{stdErr}\n{stdOut}");
}
private static Disposable<String> Unzip(String ext4GzFile)
{
var ext4GzFileName = Path.GetFileName(ext4GzFile);
Log($"extracting {ext4GzFileName}");
var ext4File = ext4GzFileName
.RemoveSuffix(".gz")
.Apply(FileSystem.CreateTempFile);
var zcat = Cli
.Wrap("zcat")
.WithArguments(ext4GzFile)
.PipeToFile(ext4File);
if (zcat.exitCode != 0)
{
ext4File.Dispose();
Exit("Failed to extract " + ext4GzFile);
}
return ext4File;
}
private static Disposable<String> Mount(String ext4File)
{
var ext4FileName = Path.GetFileName(ext4File);
Log($"mounting {ext4FileName}");
var mountDir = FileSystem.CreateTmpDir();
var mount = Cli
.Wrap("mount")
.WithArguments($"-o loop -t ext4 {ext4File} {mountDir}")
.ExecuteSync();
if (mount.exitCode != 0)
{
Log($"\nFailed to mount {ext4File} on {mountDir}:\n{mount.stdErr}");
mountDir.Dispose();
Exit($"\nFailed to mount {ext4File}:\n{mount.stdErr}");
}
return mountDir.BeforeDisposeDo(Unmount);
void Unmount()
{
Log($"unmounting {ext4FileName}");
var umount = Cli
.Wrap("umount")
.WithArguments(mountDir)
.ExecuteSync();
if (umount.exitCode != 0)
Exit($"Failed to unmount {mountDir}\n{umount.stdErr}");
}
}
private static void ApplyChanges(String ieFirmwareDir,
String ext4File,
String timestamp,
String version)
{
using var mountDir = Mount(ext4File); // IMPORTANT: must unmount (dispose) before zipping ext4 file again!
PatchIeFiles(ieFirmwareDir, mountDir);
UpdateVersionFile(mountDir, version, timestamp, "/etc/issue");
UpdateVersionFile(mountDir, version, timestamp, "/etc/issue.net");
UpdateVersionFile(mountDir, version, timestamp, "/etc/version");
UpdateVersionFile(mountDir, version, timestamp, "/opt/victronenergy/version");
}
private static void UpdateSymlink(String newSwuFile, String newSwuLink)
{
var ln = Cli
.Wrap("ln")
.WithArguments($"-sfn {newSwuFile} {newSwuLink}")
.ExecuteSync();
if (ln.exitCode != 0)
Exit($"failed to update symlink {newSwuLink}");
}
private static void RemoveOldFiles(Device device, Channel channel)
{
var oldFiles = Directory
.GetFiles(FwSource.InnovEnergy.GetDirectory(channel, device))
.Where(f => f.EndsWith(".swu"))
.OrderByDescending(File.GetCreationTimeUtc)
.Skip(MaxPublishedSwus);
foreach (var file in oldFiles)
{
Log($"Deleting old swu file {file.Substring(Program.IeBasePath.Length)}");
File.Delete(file);
}
}
private static String PublishSwu(Device device, Channel channel, String releaseSwu)
{
var swuFileName = Path.GetFileName(releaseSwu);
var newSwuFile = FwSource.InnovEnergy.GetDirectory(channel, device).AppendPath(swuFileName);
var newSwuLink = FwSource.InnovEnergy.GetLatestSwuPath(channel, device);
Log($"publishing {newSwuFile[Program.IeBasePath.Length..]}");
new FileInfo(newSwuFile).Directory?.Create(); // create dir if not exits
File.Move(releaseSwu, newSwuFile);
UpdateSymlink(newSwuFile, newSwuLink);
return newSwuFile;
}
private static Disposable<String> MergeSwu(String victronBaseSwuFile,
String ieFirmwareDir,
Device device,
String version)
{
var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
using var cpioDir = Cpio.Extract(victronBaseSwuFile);
var ext4GzFile = cpioDir.Value.AppendPath(device.ExtGzFileName());
using var ext4File = Unzip(ext4GzFile);
UpdateVersionFile(cpioDir, version, timestamp, "/sw-description");
ApplyChanges(ieFirmwareDir, ext4File, timestamp, version);
Zip.GZip(ext4File, ext4GzFile);
var mergedSwuFile = device
.LongSwuFileName(timestamp, version)
.Apply(FileSystem.CreateTempFile);
Cpio.Write(cpioDir, mergedSwuFile);
return mergedSwuFile;
}
}

View File

@ -1,31 +0,0 @@
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public enum Channel
{
Release,
Candidate,
Testing,
Develop
}
public static class ChannelExtensions
{
public static String GetName(this Channel channel)
{
return Enum.GetName(typeof(Channel), channel)?.ToLower()!;
}
public static String? ZipPath(this Channel channel)
{
if (channel is Channel.Candidate or Channel.Develop)
return null;
var fileName = channel is Channel.Release
? "release.zip"
: "victron.zip";
return Program.IeBasePath.AppendPath("venus").AppendPath(fileName);
}
}

View File

@ -1,41 +0,0 @@
using System.Text;
using CliWrap;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public static class CliExtensions
{
// TODO: obsolete, use ExecuteBufferedAsync
public static (Int32 exitCode, String stdOut, String stdErr) ExecuteSync(this Command cmd)
{
var stdErr = new StringBuilder();
var stdOut = new StringBuilder();
var r = cmd
.WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOut))
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErr))
.WithValidation(CommandResultValidation.None)
.ExecuteAsync()
.Task
.Result;
return (r.ExitCode, stdOut.ToString(), stdErr.ToString());
}
public static (Int32 exitCode, String stdErr) PipeToFile(this Command cmd, String file)
{
var stdErr = new StringBuilder();
var r = cmd
.WithStandardOutputPipe(PipeTarget.ToFile(file))
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErr))
.WithValidation(CommandResultValidation.None)
.ExecuteAsync()
.Task
.Result;
return (r.ExitCode, stdErr.ToString());
}
}

View File

@ -1,15 +0,0 @@
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public class Commit : Disposable
{
public String Directory { get; }
public String FirmwareDirectory => Directory.AppendPath("firmware");
public Commit(Disposable<String> directory) : base(directory.Dispose)
{
Directory = directory;
}
}

View File

@ -1,8 +0,0 @@
namespace InnovEnergy.Server.FirmwareCiDaemon;
public record CommitInfo
{
public String Hash { get; init; }
public String Comment { get; init; }
public Branch Branch { get; init; }
}

View File

@ -1,55 +0,0 @@
using CliWrap;
using InnovEnergy.Lib.Utils;
using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public static class Cpio
{
public static void Write(String cpioDir, String swuFile)
{
var swuFileName = Path.GetFileName(swuFile);
Log($"writing {swuFileName}");
// ls | cpio -o -H crc > "../$swu" 2>/dev/null
var ls = Cli
.Wrap("ls")
.WithWorkingDirectory(cpioDir);
var cpio = Cli
.Wrap("cpio")
.WithArguments("-o -H crc")
.WithStandardOutputPipe(PipeTarget.ToFile(swuFile))
.WithWorkingDirectory(cpioDir);
var lsCpio = (ls | cpio).ExecuteAsync().Task.Result;
if (lsCpio.ExitCode != 0)
Exit($"Failed to write {swuFileName}");
}
public static Disposable<String> Extract(String swuFile)
{
Log($"extracting {Path.GetFileName(swuFile)}");
var cpioDir = FileSystem.CreateTmpDir();
var cpio = Cli
.Wrap("cpio")
.WithArguments("-id")
.WithStandardInputPipe(PipeSource.FromFile(swuFile))
.WithWorkingDirectory(cpioDir)
.ExecuteSync();
if (cpio.exitCode != 0)
{
cpioDir.Dispose();
Exit("Failed to extract swu");
}
return cpioDir;
}
}

View File

@ -1,68 +0,0 @@
using System.Diagnostics.CodeAnalysis;
namespace InnovEnergy.Server.FirmwareCiDaemon;
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum Device
{
BeagleBone,
BeagleBone2,
NanoPi,
Einstein,
RaspberryPi2
}
public static class DeviceExtensions
{
public static String GetName(this Device device)
{
if (device == Device.BeagleBone2)
device = Device.BeagleBone;
var name = Enum.GetName(device)?.ToLower();
if (name is null)
throw new ArgumentException(nameof(device));
return name;
}
public static String SwuName(this Device device)
{
return device switch
{
Device.BeagleBone2 => "venus-swu-2",
_ => "venus-swu"
};
}
public static String SwuBase(this Device device)
{
var deviceName = device.GetName();
var swuName = device.SwuName();
return $"{swuName}-{deviceName}";
}
public static String ShortSwuFileName(this Device device)
{
var swuBase = device.SwuBase();
return $"{swuBase}.swu";
}
public static String ExtFileName(this Device device)
{
var deviceName = device.GetName();
return $"venus-image-{deviceName}.ext4";
}
public static String ExtGzFileName(this Device device)
{
return device.ExtFileName() + ".gz";
}
public static String LongSwuFileName(this Device device, String timestamp, String version)
{
var swuBase = device.SwuBase();
return $"{swuBase}-{timestamp}-{version}.swu";
}
}

View File

@ -1,19 +0,0 @@
namespace InnovEnergy.Server.FirmwareCiDaemon;
public class ExitException : Exception
{
public Int32 ExitCode { get; }
public ExitException(Int32 exitCode = 1): base("")
{
ExitCode = exitCode;
}
public ExitException(String message, Int32 exitCode = 1) : base(message)
{
ExitCode = exitCode;
}
public static void Exit(String msg) => throw new ExitException(msg);
public static void Exit(Int32 exitCode) => throw new ExitException(exitCode);
}

View File

@ -1,83 +0,0 @@
using CliWrap;
using InnovEnergy.Lib.Utils;
using static System.StringSplitOptions;
using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public static class Fossil
{
public static String FossilFile { get; set; }
public static String FossilUser { get; set; }
// TODO: get commit/branch without checkout
public static Commit Checkout(this Branch branch)
{
var fossilDir = Open();
Update(fossilDir, branch, FossilUser);
return new Commit(fossilDir);
}
public static CommitInfo GetLatestCommitInfo(this Branch branch)
{
using var fossilDir = Open();
var (hash, comment) = Update(fossilDir, branch, FossilUser);
return new CommitInfo { Hash = hash, Comment = comment, Branch = branch};
}
private static Disposable<String> Open()
{
var fossilDir = FileSystem.CreateTmpDir();
var fossilCmd = Cli
.Wrap("fossil")
.WithWorkingDirectory(fossilDir);
var open = fossilCmd
.WithArguments($"open {FossilFile} --empty")
.ExecuteSync();
if (open.exitCode != 0)
{
fossilDir.Dispose();
Exit("failed to open " + Path.GetFileName(FossilFile) + "\n" + open.stdOut + "\n" + open.stdErr);
}
return fossilDir.BeforeDisposeDo(Close);
void Close() => fossilCmd.WithArguments("close").ExecuteSync();
}
public static (String hash, String comment) Update(String fossilDir, Branch branch, String fossilUser)
{
var fossil = Cli
.Wrap("fossil")
.WithArguments($"update --user {fossilUser} {branch.GetName()}")
.WithWorkingDirectory(fossilDir)
.WithValidation(CommandResultValidation.None)
.ExecuteSync();
if (fossil.exitCode != 0)
Exit($"failed to update!\n{fossil.stdOut}");
var fossilOutLines = fossil.stdOut.SplitLines();
const String checkoutPrefix = "updated-to:";
const String commentPrefix = "comment:";
var hash = fossilOutLines
.Single(l => l.StartsWith(checkoutPrefix))
.Split(" ", RemoveEmptyEntries)
.ElementAt(1);
var comment = fossilOutLines
.Single(l => l.StartsWith(commentPrefix))
.Substring(commentPrefix.Length)
.SkipWhile(c => c == ' ')
.TakeWhile(c => c != '(') // there is a (user: ig) at the end, stops at the first (, but whatever
.Apply(String.Concat)
.Trim();
return (hash, comment);
}
}

View File

@ -1,33 +0,0 @@
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public enum FwSource
{
InnovEnergy,
Victron
}
public static class FwSourceExtensions
{
public static String GetLatestSwuPath(this FwSource source, Channel channel, Device device)
{
var path = source.GetDirectory(channel, device);
var file = device.ShortSwuFileName();
return path.AppendPath(file);
}
public static String GetDirectory(this FwSource source, Channel channel, Device device)
{
var basePath = source == FwSource.InnovEnergy
? Program.IeBasePath
: Program.VeBasePath;
return basePath
.AppendPath("venus")
.AppendPath(channel.GetName())
.AppendPath("images")
.AppendPath(device.GetName()) + '/';
}
}

View File

@ -1,9 +0,0 @@
namespace InnovEnergy.Server.FirmwareCiDaemon;
public static class Logger
{
public static void Log(String s = "")
{
Console.WriteLine($"{DateTime.Now:yyyy'-'MM'-'dd' 'HH':'mm':'ss} {s}");
}
}

View File

@ -1,193 +0,0 @@
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text.RegularExpressions;
using CliWrap;
using InnovEnergy.Lib.Utils;
using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
namespace InnovEnergy.Server.FirmwareCiDaemon;
// dotnet publish FirmwareCiDaemon.csproj -c Release -r linux-x64 -p:PublishSingleFile=true --self-contained true && scp ./bin/Release/netcoreapp5.0/linux-x64/publish/FirmwareCiDaemon ig@salidomo.innovenergy.ch:/home/ig/firmware
public static class Program
{
// use the following scheduler to run everything on a single thread
// Fossil cannot deal with the async introduced by multiple threads/tasks
private static readonly IScheduler Scheduler = new EventLoopScheduler();//NewThreadScheduler();
private static readonly IEnumerable<Device> SupportedDevices = Enum.GetValues<Device>();
private static readonly IEnumerable<Branch> Branches = Enum.GetValues<Branch>();
public static String IeBasePath { get; set; }
public static String VeBasePath => "https://updates.victronenergy.com/feeds/";
public static void Main(String[] args)
{
try
{
Run(args);
}
catch (Exception e)
{
PrintExceptionAndExit(e);
}
//Environment.Exit(0);
}
// runcmd: program <fossil_file> <iePublishDir> <fossil_user>
private static void Run(String[] args)
{
if (!IsRoot) Exit("This program must be run as root");
Fossil.FossilFile = ParseFossilFileArg(args); // TODO: get rid of global vars?
Fossil.FossilUser = ParseFossilUserArg(args);
IeBasePath = ParseIePublishDirArg(args);
var veVersions = SupportedDevices.Select(ObserveVeVersion).ToList();
var branches = Branches.Select(ObserveFossilBranch).ToList();
var buildInfos = from veVersion in veVersions
from branch in branches
select Observable.CombineLatest(branch, veVersion, Build.Prepare);
buildInfos.Merge()
.ObserveOn(Scheduler) // fossil is not thread safe!
.Subscribe(build => build.Execute(), PrintExceptionAndExit);
foreach (var veVersion in veVersions)
veVersion.Connect();
foreach (var branch in branches)
branch.Connect();
while (true) Console.ReadLine();
// ReSharper disable once FunctionNeverReturns
}
private static IConnectableObservable<CommitInfo> ObserveFossilBranch(Branch branch)
{
return Observable
.Interval(TimeSpan.FromMinutes(1))
.StartWith(0)
.ObserveOn(Scheduler) // fossil is not thread safe!
.Select(_ => Fossil.GetLatestCommitInfo(branch))
.DistinctUntilChanged()
.Do(c => Log($"Found new commit '{c.Comment}' on branch {c.Branch} ({c.Hash[..6]})"))
.Publish();
}
private static IConnectableObservable<(Device device, String veVersion)> ObserveVeVersion(Device device)
{
return Observable
.Interval(TimeSpan.FromHours(1))
.StartWith(0)
.Select(_ => device)
.Select(GetLatestVictronVersion)
.DistinctUntilChanged()
.Select(veVersion => (device, veVersion))
.Do(vd => Log($"Found new Victron version '{vd.veVersion}' for {vd.device}"))
.Publish();
}
public static String GetLatestVictronVersion(Device device)
{
var url = FwSource.Victron.GetDirectory(Channel.Release, device);
var curl = Cli
.Wrap("curl")
.WithArguments(url)
.ExecuteSync()
.stdOut;
var deviceName = device.GetName();
var swuName = device.SwuName();
const String timeStampPattern = "[0-9]{14}";
const String releasePattern = @"v[0-9]+\.[0-9]+";
const String extension = ".swu";
const String extensionPattern = @"\" + extension; // escape .
var rxVersion = new Regex($"{swuName}-{deviceName}-{timeStampPattern}-{releasePattern}{extensionPattern}");
return rxVersion
.Matches(curl)
.Select(m => m.Value)
.OrderBy(m => m)
.Last()
.Split("-")
.Last()
.RemoveSuffix(extension);
}
private static Boolean IsRoot
{
get
{
var (exitCode, stdOut, stdErr) = Cli
.Wrap("id")
.WithArguments("-u")
.ExecuteSync();
return exitCode == 0 &&
stdOut.Trim() == "0" &&
String.IsNullOrWhiteSpace(stdErr);
}
}
private static String ParseFossilFileArg(IReadOnlyList<String> args)
{
if (args.Count < 1)
Exit("Missing argument <fossil_file>");
var fossilFile = Path.GetFullPath(args[0]);
if (!FileSystem.Local.FileExists(fossilFile))
Exit($"Cannot find fossil file {fossilFile}");
return fossilFile;
}
private static String ParseIePublishDirArg(IReadOnlyList<String> args)
{
if (args.Count < 2)
Exit("Missing argument <iePublishDir>");
var iePublishDir = Path.GetFullPath(args[1]);
if (!FileSystem.Local.DirectoryExists(iePublishDir))
Exit($"Cannot find directory {iePublishDir}");
return iePublishDir;
}
private static String ParseFossilUserArg(IReadOnlyList<String> args)
{
if (args.Count < 3)
Exit("Missing argument <fossil_user>");
return args[2];
}
private static void PrintExceptionAndExit(Exception e)
{
if (!String.IsNullOrWhiteSpace(e.Message))
{
Console.WriteLine();
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Log(e.Message);
Console.ForegroundColor = color;
}
if (!String.IsNullOrWhiteSpace(e.StackTrace))
Log(e.StackTrace);
Environment.Exit(1);
}
}

View File

@ -1,45 +0,0 @@
using CliWrap;
using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
namespace InnovEnergy.Server.FirmwareCiDaemon;
public static class Zip
{
public static void RemoveFromZip(this String zipFilePath, String zipInternalPathGlob)
{
var zip = Cli
.Wrap("zip")
.WithArguments($"-q -d {zipFilePath} {zipInternalPathGlob}")
.ExecuteSync();
if (zip.exitCode != 0)
Log($"Warning: failed to remove {zipInternalPathGlob} from {zipFilePath}");
}
public static void AddToZip(this String zipFilePath, String filePath)
{
var zip = Cli
.Wrap("zip")
.WithArguments($"-q -j {zipFilePath} {filePath}")
.ExecuteSync();
if (zip.exitCode != 0)
Exit($"failed to add {filePath} to {zipFilePath}");
}
public static void GZip(this String sourceFile, String targetGzFile)
{
// TODO: datetime log
Log($"compressing {Path.GetFileName(sourceFile)}");
var gzip = Cli
.Wrap("gzip")
.WithArguments($"-c {sourceFile}")
.PipeToFile(targetGzFile);
if (gzip.exitCode != 0)
Exit($"Failed to gzip {sourceFile}");
}
}