Skip to content

Commit

Permalink
by-hash initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
origin-yaropolk committed Apr 1, 2024
1 parent 051b4aa commit 562800e
Showing 1 changed file with 36 additions and 11 deletions.
47 changes: 36 additions & 11 deletions src/deb/deb-builder.mts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createHash, randomBytes } from 'crypto';
import { createGzip } from 'zlib';

import * as fs from 'fs';
Expand All @@ -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 {
Expand All @@ -47,6 +49,24 @@ function iterateDebs(repo: DebRepo, callback: (distribution: string, component:
});
}

function sha512(filePath: string): Promise<string> {
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<void> {
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;
Expand Down Expand Up @@ -102,15 +122,13 @@ export class DebBuilder implements Deployer {
.replace('$COMPONENT', component);

const distributionPath = path.join(this.distsPath, distribution);
const releaseFilePath = path.join(distributionPath, 'Release');
const releaseGpgFilePath = path.join(distributionPath, 'Release.gpg');
const tempReleaseFile = path.join(this.tempPath, `Release-${randomBytes(4).toString('hex')}`);
const inReleaseFilePath = path.join(distributionPath, 'InRelease');

await fs.promises.writeFile(releaseFilePath, releaseContent);
await fs.promises.writeFile(tempReleaseFile, releaseContent);

await execToolToFile('apt-ftparchive', ['release', distributionPath], releaseFilePath, true);
await execToolToFile('gpg', ['--no-tty', '--default-key', this.config.gpgKeyName, '-abs', '-o', releaseGpgFilePath, releaseFilePath]);
await execToolToFile('gpg', ['--no-tty', '--default-key', this.config.gpgKeyName, '--clearsign', '-o', inReleaseFilePath, releaseFilePath]);
await execToolToFile('apt-ftparchive', ['release', distributionPath], tempReleaseFile, true);
await execToolToFile('gpg', ['--no-tty', '--default-key', this.config.gpgKeyName, '--clearsign', '-o', inReleaseFilePath, tempReleaseFile]);
}

private async dpkgScanpackages(): Promise<void> {
Expand Down Expand Up @@ -201,19 +219,20 @@ export class DebBuilder implements Deployer {
}

private async makeRelease(): Promise<{}> {
const compressFile = (filePath: string): Promise<void> => new Promise<void>(resolve => {
const compressFile = (filePath: string): Promise<string> => new Promise<string>(resolve => {
const inp = fs.createReadStream(filePath);
const out = fs.createWriteStream(`${filePath}.gz`);

const gzip = createGzip({ level: 9 });

inp.pipe(gzip).pipe(out)
.on('finish', () => {
resolve();
resolve(`${filePath}.gz`);
});
});

const compressPromises: Promise<void>[] = [];
const compressPromises: Promise<string>[] = [];
const byHashPromises: Promise<void>[] = [];

iterateComponents(this.config.repo, (distribution, component) => {
const componentRoot = path.join(this.distsPath, distribution, component);
Expand All @@ -234,12 +253,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<void>[] = [];

Expand Down

0 comments on commit 562800e

Please sign in to comment.