-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Increased CDN cache duration from 90 to 180 days. Use beta releases o…
…f Unfucked and DataSizeUnits libraries instead of local builds. Update some MIME types for PGP files.
- Loading branch information
Showing
9 changed files
with
210 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,37 @@ | ||
using Azure; | ||
using Azure.ResourceManager.Cdn; | ||
using Azure.ResourceManager.Cdn.Models; | ||
|
||
namespace RaspberryPiDotnetRepository.Azure; | ||
|
||
/* | ||
* There seems to be no upper limit to the duration of a certificate that Azure apps can use, unlike client secrets, which must be rotated at least once every 2 years. | ||
* | ||
* You can generate a new certificate using PowerShell: | ||
* | ||
* New-SelfSignedCertificate -KeyAlgorithm RSA -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -Subject "CN=RaspberryPiDotnetRepository" -NotAfter (Get-Date).AddYears(100) | ||
* | ||
* Then, use certmgr.msc to export this certificate as a CER file without the private key, and upload it to portal.azure.com > App registrations > your app > Certificates & secrets. | ||
* | ||
* Next, export the same certificate as a PFX file with the private key and a password, and pass its absolute path as certFilePath. | ||
* | ||
* You may now delete the cert from the Personal store if you want. | ||
*/ | ||
public interface CdnClient { | ||
|
||
Task purge(); | ||
|
||
} | ||
|
||
public class CdnClientImpl(CdnEndpointResource? cdnEndpoint, ILogger<CdnClientImpl> logger): CdnClient { | ||
|
||
public async Task purge() { | ||
if (cdnEndpoint != null) { | ||
await cdnEndpoint.PurgeContentAsync(WaitUntil.Started, new PurgeContent(["/dists/*", "/badges/*"])); | ||
logger.LogInformation("Starting CDN purge, will finish asynchronously later"); | ||
} else { | ||
logger.LogInformation("No CDN configured, not purging"); | ||
} | ||
} | ||
|
||
using Azure; | ||
using Azure.ResourceManager.Cdn; | ||
using Azure.ResourceManager.Cdn.Models; | ||
|
||
namespace RaspberryPiDotnetRepository.Azure; | ||
|
||
/* | ||
* There seems to be no upper limit to the duration of a certificate that Azure apps can use, unlike client secrets, which must be rotated at least once every 2 years. | ||
* | ||
* You can generate a new certificate using PowerShell: | ||
* | ||
* New-SelfSignedCertificate -KeyAlgorithm RSA -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -Subject "CN=RaspberryPiDotnetRepository" -NotAfter (Get-Date).AddYears(100) | ||
* | ||
* Then, use certmgr.msc to export this certificate as a CER file without the private key, and upload it to portal.azure.com > App registrations > your app > Certificates & secrets. | ||
* | ||
* Next, export the same certificate as a PFX file with the private key and a password, and pass its absolute path as certFilePath. | ||
* | ||
* You may now delete the cert from the Personal store if you want. | ||
*/ | ||
public interface CdnClient { | ||
|
||
Task purge(IEnumerable<string> paths); | ||
|
||
} | ||
|
||
public class CdnClientImpl(CdnEndpointResource? cdnEndpoint, ILogger<CdnClientImpl> logger): CdnClient { | ||
|
||
public async Task purge(IEnumerable<string> paths) { | ||
if (cdnEndpoint != null) { | ||
await cdnEndpoint.PurgeContentAsync(WaitUntil.Started, new PurgeContent(paths)); | ||
logger.LogInformation("Starting CDN purge, will finish asynchronously later"); | ||
} else { | ||
logger.LogInformation("No CDN configured, not purging"); | ||
} | ||
} | ||
|
||
} |
173 changes: 81 additions & 92 deletions
173
RaspberryPiDotnetRepository/Debian/Package/PackageBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,82 @@ | ||
using LibObjectFile.Ar; | ||
using RaspberryPiDotnetRepository.Data.ControlMetadata; | ||
using SharpCompress.Common; | ||
using SharpCompress.Compressors; | ||
using SharpCompress.Compressors.Deflate; | ||
using SharpCompress.IO; | ||
using SharpCompress.Writers; | ||
using SharpCompress.Writers.GZip; | ||
using SharpCompress.Writers.Tar; | ||
using TarWriter = Unfucked.Compression.Writers.Tar.TarWriter; | ||
|
||
namespace RaspberryPiDotnetRepository.Debian.Package; | ||
|
||
//TODO update comments for new Control type | ||
/// <summary> | ||
/// Create a Debian package with given files to install and control metadata. | ||
/// | ||
/// <list type="number"> | ||
/// <item><description>Construct a new <see cref="PackageBuilderImpl"/> instance</description></item> | ||
/// <item><description>Set <see cref="control"/> to be the control metadata (see <see href="https://www.debian.org/doc/debian-policy/ch-controlfields.html"/>)</description></item> | ||
/// <item><description>Add files to install by getting <see cref="data"/> and calling <see cref="TarWriter.WriteFile"/>, <see cref="TarWriter.WriteDirectory"/>, or <see cref="TarWriter.WriteSymLink"/> as many times as you want on it</description></item> | ||
/// <item><description>Create a destination stream (like a <see cref="FileStream"/>) and call <see cref="build"/> to save the package to a .deb file</description></item> | ||
/// </list> | ||
/// </summary> | ||
public interface PackageBuilder: IAsyncDisposable, IDisposable { | ||
|
||
CompressionLevel gzipCompressionLevel { get; set; } | ||
TarWriter data { get; } | ||
|
||
Task build(Control control, Stream output); | ||
|
||
} | ||
|
||
public class PackageBuilderImpl: PackageBuilder { | ||
|
||
public const string CONTROL_ARCHIVE_FILENAME = "control.tar.gz"; | ||
|
||
public CompressionLevel gzipCompressionLevel { get; set; } = CompressionLevel.Default; | ||
public TarWriter data { get; } | ||
|
||
private readonly Stream dataArchiveStream = new MemoryStream(); | ||
private readonly GZipStream dataGzipStream; | ||
|
||
public PackageBuilderImpl() { | ||
dataGzipStream = new GZipStream(NonDisposingStream.Create(dataArchiveStream), CompressionMode.Compress, gzipCompressionLevel); | ||
data = new TarWriter(dataGzipStream, new TarWriterOptions(CompressionType.None, true)); | ||
} | ||
|
||
public async Task build(Control control, Stream output) { | ||
data.Dispose(); | ||
await dataGzipStream.DisposeAsync(); | ||
dataArchiveStream.Position = 0; | ||
|
||
await using Stream controlArchiveStream = new MemoryStream(); | ||
using (IWriter controlArchiveWriter = WriterFactory.Open(controlArchiveStream, ArchiveType.Tar, new GZipWriterOptions { CompressionLevel = gzipCompressionLevel })) { | ||
await using Stream controlFileBuffer = control.serialize().ToStream(); | ||
controlArchiveWriter.Write("./control", controlFileBuffer); | ||
} | ||
|
||
controlArchiveStream.Position = 0; | ||
|
||
ArArchiveFile debArchive = new() { Kind = ArArchiveKind.Common }; | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = "debian-binary", | ||
Stream = "2.0\n".ToStream() | ||
}); | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = CONTROL_ARCHIVE_FILENAME, | ||
Stream = controlArchiveStream | ||
}); | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = "data.tar.gz", | ||
Stream = dataArchiveStream | ||
}); | ||
|
||
debArchive.Write(output); | ||
} | ||
|
||
public void Dispose() { | ||
data.Dispose(); | ||
dataGzipStream.Dispose(); | ||
dataArchiveStream.Dispose(); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
public async ValueTask DisposeAsync() { | ||
data.Dispose(); | ||
await dataGzipStream.DisposeAsync(); | ||
await dataArchiveStream.DisposeAsync(); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
using LibObjectFile.Ar; | ||
using RaspberryPiDotnetRepository.Data.ControlMetadata; | ||
using SharpCompress.Common; | ||
using SharpCompress.Compressors; | ||
using SharpCompress.Compressors.Deflate; | ||
using SharpCompress.IO; | ||
using SharpCompress.Writers; | ||
using SharpCompress.Writers.GZip; | ||
using SharpCompress.Writers.Tar; | ||
using TarWriter = Unfucked.Compression.Writers.Tar.TarWriter; | ||
|
||
namespace RaspberryPiDotnetRepository.Debian.Package; | ||
|
||
public interface PackageBuilder: IAsyncDisposable, IDisposable { | ||
|
||
CompressionLevel gzipCompressionLevel { get; set; } | ||
TarWriter data { get; } | ||
|
||
Task build(Control control, Stream output); | ||
|
||
} | ||
|
||
public class PackageBuilderImpl: PackageBuilder { | ||
|
||
public const string CONTROL_ARCHIVE_FILENAME = "control.tar.gz"; | ||
|
||
public CompressionLevel gzipCompressionLevel { get; set; } = CompressionLevel.Default; | ||
public TarWriter data { get; } | ||
|
||
private readonly Stream dataArchiveStream = new MemoryStream(); | ||
private readonly GZipStream dataGzipStream; | ||
|
||
public PackageBuilderImpl() { | ||
dataGzipStream = new GZipStream(NonDisposingStream.Create(dataArchiveStream), CompressionMode.Compress, gzipCompressionLevel); | ||
data = new TarWriter(dataGzipStream, new TarWriterOptions(CompressionType.None, true)); | ||
} | ||
|
||
public async Task build(Control control, Stream output) { | ||
data.Dispose(); | ||
await dataGzipStream.DisposeAsync(); | ||
dataArchiveStream.Position = 0; | ||
|
||
await using Stream controlArchiveStream = new MemoryStream(); | ||
using (IWriter controlArchiveWriter = WriterFactory.Open(controlArchiveStream, ArchiveType.Tar, new GZipWriterOptions { CompressionLevel = gzipCompressionLevel })) { | ||
await using Stream controlFileBuffer = control.serialize().ToByteStream(); | ||
controlArchiveWriter.Write("./control", controlFileBuffer); | ||
} | ||
|
||
controlArchiveStream.Position = 0; | ||
|
||
ArArchiveFile debArchive = new() { Kind = ArArchiveKind.Common }; | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = "debian-binary", | ||
Stream = "2.0\n".ToByteStream() | ||
}); | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = CONTROL_ARCHIVE_FILENAME, | ||
Stream = controlArchiveStream | ||
}); | ||
debArchive.AddFile(new ArBinaryFile { | ||
Name = "data.tar.gz", | ||
Stream = dataArchiveStream | ||
}); | ||
|
||
debArchive.Write(output); | ||
} | ||
|
||
public void Dispose() { | ||
data.Dispose(); | ||
dataGzipStream.Dispose(); | ||
dataArchiveStream.Dispose(); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
public async ValueTask DisposeAsync() { | ||
data.Dispose(); | ||
await dataGzipStream.DisposeAsync(); | ||
await dataArchiveStream.DisposeAsync(); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...itory/Debian/Package/StatisticsService.cs → ...ryPiDotnetRepository/StatisticsService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.