feat: Add installing

It can install now.
Requires pexec to be present

This may be due to an upstream issue with spectre.console affecting how
stdin/stdout are handled.

TODO:
 - Add backup/restore functionality
 - Refactor sections for neatness
 - Improve UX
This commit is contained in:
Robert Morrison 2023-06-08 11:22:00 +01:00
parent 60e06b2144
commit 79063f97ee
Signed by: robert
GPG Key ID: 73E012EB3F4EC696
3 changed files with 84 additions and 41 deletions

View File

@ -123,7 +123,7 @@ sealed class DebEntry
throw new ArgumentException("buffer too short"); throw new ArgumentException("buffer too short");
} }
name = Encoding.ASCII.GetString(buffer[0..16]); name = Encoding.ASCII.GetString(buffer[0..16]).Trim(); // Trim any trailing whitespace
mtime = long.Parse(Encoding.ASCII.GetString(buffer[16..28])); mtime = long.Parse(Encoding.ASCII.GetString(buffer[16..28]));
mode = int.Parse(Encoding.ASCII.GetString(buffer[28..34])); mode = int.Parse(Encoding.ASCII.GetString(buffer[28..34]));
gid = int.Parse(Encoding.ASCII.GetString(buffer[34..40])); gid = int.Parse(Encoding.ASCII.GetString(buffer[34..40]));

View File

@ -3,6 +3,9 @@ using Serilog;
using Spectre.Console; using Spectre.Console;
using System.Text.Json; using System.Text.Json;
using System.Text; using System.Text;
using SharpCompress.Compressors.Xz;
using System.Formats.Tar;
using System.Diagnostics;
namespace EdgeInstaller; namespace EdgeInstaller;
@ -222,15 +225,12 @@ public static partial class EdgeInstall
RenderPackageAsTable(LatestVersion); RenderPackageAsTable(LatestVersion);
var versionPath = LatestVersion.Filename
.Replace("pool/main/m/", "")
.Replace(".deb", "");
var versionsDir = Path.Join(Archdir, "Versions"); var versionsDir = Path.Join(Archdir, "Versions");
var versionDir = Path.Join(versionsDir, LatestVersion.PackageName, LatestVersion.Version.ToString());
Directory.CreateDirectory(versionDir);
// Let's get and unpack the latest version // Let's get and unpack the latest version
if (true)//!Directory.Exists(Path.Join(versionsDir, versionPath))) // for the moment we will always just grab
{
using (MemoryStream debStream = using (MemoryStream debStream =
await AnsiConsole.Progress() await AnsiConsole.Progress()
.Columns(new ProgressColumn[] .Columns(new ProgressColumn[]
@ -257,37 +257,80 @@ public static partial class EdgeInstall
using (DebFile debfile = new DebFile(debStream)) using (DebFile debfile = new DebFile(debStream))
{ {
foreach (var fileEntry in debfile.fileEntries)
{
AnsiConsole.MarkupLineInterpolated($"FileName: {fileEntry.name}");
AnsiConsole.MarkupLineInterpolated($"FilePos: {fileEntry.offset}");
AnsiConsole.MarkupLineInterpolated($"FileSize: {fileEntry.sizeBytes}");
// NOTE: This is dumb test code // NOTE: deb entries have trailing /
// to verify the files are actually being "extracted" properly DebEntry? dataEntry = debfile.fileEntries.Find(file => file.name == "data.tar.xz/");
if (!debfile.getFile(fileEntry, out Stream contents)) if (dataEntry is null)
{ {
return 1; AnsiConsole.MarkupLine("[red b]ERROR:[/] debfile does not contain data.tar.xz");
Environment.Exit(1);
} }
// Now we write this to tmp. // Looks like we have a hit. Lets try and extract it
// WARN: Without deleting these you will fill up your ram
var temp = Path.GetTempFileName(); if (!debfile.getFile(dataEntry, out Stream dataStream))
using (var tmpfile = File.Open(temp, FileMode.Open))
{ {
contents.CopyTo(tmpfile); AnsiConsole.MarkupLine("[red b]ERROR:[/] couldn't get stream for data.tar.xz");
contents.Dispose(); Environment.Exit(1);
}
using (XZStream dataXZStream = new(dataStream))
{
using (TarReader reader = new(dataXZStream))
{
while (true)
{
var tarEntry = reader.GetNextEntry();
if (tarEntry is null)
{
break; // TarReader returns null when we hit the end of the stream
}
AnsiConsole.MarkupLineInterpolated($"TarEntry {tarEntry.Name}");
// work out where we need to put the extracted file
var filepath = Path.Combine(versionDir, tarEntry.Name);
if (tarEntry.EntryType == TarEntryType.Directory)
{
// createDirectory doesn't fail if already exists
Directory.CreateDirectory(filepath);
continue;
}
if (tarEntry.LinkName != "")
{
// Handle links manually
if (File.Exists(filepath))
{
File.Delete(filepath);
}
File.CreateSymbolicLink(filepath, tarEntry.LinkName);
continue; // we are done with this file so keep going
}
tarEntry.ExtractToFile(filepath, overwrite: true);
} }
} }
} }
// Now assuming nothing broke before now we can copy the files into the system directories.
// WARN: This is dangerous stuff and involves making system calls.
// NOTE: be sure when calling to other programs to wait until they exit.
var Mover = new ProcessStartInfo();
Mover.FileName = "pkexec";
Mover.Arguments = $"cp -dri {versionDir}/opt {versionDir}/usr /";
Mover.UseShellExecute = true;
var pr = Process.Start(Mover);
pr?.WaitForExit();
}
} }
return 0; return 0;
} }
}
/*TODO: /*TODO:
- Check version - Check version
- Offer update - Offer update

View File

@ -9,9 +9,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CST.RecursiveExtractor" Version="1.2.13" />
<PackageReference Include="Serilog" Version="2.12.0" /> <PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SharpCompress" Version="0.33.0" />
<PackageReference Include="Spectre.Console" Version="0.47.0" /> <PackageReference Include="Spectre.Console" Version="0.47.0" />
<PackageReference Include="System.Commandline" Version="2.0.0-beta4.22272.1" /> <PackageReference Include="System.Commandline" Version="2.0.0-beta4.22272.1" />
</ItemGroup> </ItemGroup>