From 5389bde605526ef81b63cf8a9de41827ee39bb20 Mon Sep 17 00:00:00 2001 From: Egor Kushnarev Date: Mon, 1 Apr 2024 10:42:18 +0300 Subject: [PATCH] by-hash initial commit --- src/deb/deb-builder.mts | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/deb/deb-builder.mts b/src/deb/deb-builder.mts index 1464a4b..6f5fbf4 100644 --- a/src/deb/deb-builder.mts +++ b/src/deb/deb-builder.mts @@ -1,4 +1,5 @@ import { createGzip } from 'zlib'; +import { createHash } from 'crypto'; import * as fs from 'fs'; import * as ini from 'ini'; @@ -23,6 +24,7 @@ const ReleaseFileTemplate = Label: Ubuntu/Debian Architecture: $ARCH Component: $COMPONENT +Acquire-By-Hash: yes Codename: $DISTRIBUTION\n`; function iterateComponents(repo: DebRepo, callback: (distribution: string, component: string, deb: Artifact[]) => void): void { @@ -47,6 +49,24 @@ function iterateDebs(repo: DebRepo, callback: (distribution: string, component: }); } +function sha512(filePath: string): Promise { + return new Promise((resolve, reject) => { + const hash = createHash('sha512'); + fs.createReadStream(filePath) + .once('end', () => resolve(hash.digest('hex'))) + .once('error', () => reject) + .pipe(hash); + }); +} + +async function handleByHash(filePath: string): Promise { + const byHashDir = path.join(path.dirname(filePath), 'by-hash', 'SHA512'); + const byHashFileName = path.resolve(path.join(byHashDir, await sha512(filePath))); + + createDir(byHashDir); + return fs.promises.copyFile(filePath, byHashFileName); +} + export interface Config { out: string, gpgKeyName: string; @@ -201,7 +221,7 @@ export class DebBuilder implements Deployer { } private async makeRelease(): Promise<{}> { - const compressFile = (filePath: string): Promise => new Promise(resolve => { + const compressFile = (filePath: string): Promise => new Promise(resolve => { const inp = fs.createReadStream(filePath); const out = fs.createWriteStream(`${filePath}.gz`); @@ -209,11 +229,12 @@ export class DebBuilder implements Deployer { inp.pipe(gzip).pipe(out) .on('finish', () => { - resolve(); + resolve(`${filePath}.gz`); }); }); - const compressPromises: Promise[] = []; + const compressPromises: Promise[] = []; + const byHashPromises: Promise[] = []; iterateComponents(this.config.repo, (distribution, component) => { const componentRoot = path.join(this.distsPath, distribution, component); @@ -234,12 +255,18 @@ export class DebBuilder implements Deployer { } fs.writeFileSync(targetPackagesFile, packagesContent); - + byHashPromises.push(handleByHash(targetPackagesFile)); compressPromises.push(compressFile(targetPackagesFile)); }); }); - await Promise.all(compressPromises); + const compressedPackages = await Promise.all(compressPromises); + + compressedPackages.forEach(packagePath => { + byHashPromises.push(handleByHash(packagePath)); + }); + + await Promise.all(byHashPromises); const releasesPromises: Promise[] = [];