Commit 4aae8cd0 authored by nanahira's avatar nanahira

sha256 and migrate

parent 5cef4cc5
Pipeline #4864 passed with stages
in 4 minutes
...@@ -15,8 +15,8 @@ import { AppPrefixDto } from '../dto/AppPrefix.dto'; ...@@ -15,8 +15,8 @@ import { AppPrefixDto } from '../dto/AppPrefix.dto';
export class AdminController { export class AdminController {
constructor(private readonly appService: AppService) {} constructor(private readonly appService: AppService) {}
@Post('migrate') @Post('migrate/apps.json')
@ApiOperation({ summary: '迁移', description: '上传一个 apps.json 文件' }) @ApiOperation({ summary: '迁移 apps', description: '上传一个 apps.json 文件' })
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data') @ApiConsumes('multipart/form-data')
@ApiBody({ @ApiBody({
...@@ -24,7 +24,7 @@ export class AdminController { ...@@ -24,7 +24,7 @@ export class AdminController {
type: FileUploadDto, type: FileUploadDto,
}) })
@ApiCreatedResponse({ type: BlankReturnMessageDto }) @ApiCreatedResponse({ type: BlankReturnMessageDto })
async migrate(@UploadedFile('file') file: Express.Multer.File): Promise<BlankReturnMessageDto> { async migrateApps(@UploadedFile('file') file: Express.Multer.File): Promise<BlankReturnMessageDto> {
if (!file) { if (!file) {
throw new BlankReturnMessageDto(400, 'no file').toException(); throw new BlankReturnMessageDto(400, 'no file').toException();
} }
...@@ -32,6 +32,13 @@ export class AdminController { ...@@ -32,6 +32,13 @@ export class AdminController {
return this.appService.migrateFromAppsJson(apps); return this.appService.migrateFromAppsJson(apps);
} }
@Post('migrate/hash')
@ApiOperation({ summary: '迁移 hash' })
@ApiCreatedResponse({ type: BlankReturnMessageDto })
async migrateHash(@UploadedFile('file') file: Express.Multer.File): Promise<BlankReturnMessageDto> {
return this.appService.migrateHashes();
}
@Put('app/:id') @Put('app/:id')
@ApiOperation({ summary: '创建 app' }) @ApiOperation({ summary: '创建 app' })
@ApiOkResponse({ type: BlankReturnMessageDto }) @ApiOkResponse({ type: BlankReturnMessageDto })
......
...@@ -13,6 +13,8 @@ import { Build } from './entities/Build.entity'; ...@@ -13,6 +13,8 @@ import { Build } from './entities/Build.entity';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { Archive, ArchiveType } from './entities/Archive.entity'; import { Archive, ArchiveType } from './entities/Archive.entity';
import { PackageS3Service } from './package-s3/package-s3.service'; import { PackageS3Service } from './package-s3/package-s3.service';
import axios from 'axios';
import { createHash } from 'crypto';
@Injectable() @Injectable()
export class AppService extends ConsoleLogger { export class AppService extends ConsoleLogger {
...@@ -309,4 +311,33 @@ export class AppService extends ConsoleLogger { ...@@ -309,4 +311,33 @@ export class AppService extends ConsoleLogger {
} }
return null; return null;
} }
async getHashForMigrate(fullPath: string): Promise<string> {
const url = `${this.packageS3.cdnUrl}/${fullPath}`;
this.log(`Migrating hash: ${url} `);
const { data } = await axios.get<internal.Readable>(url, { responseType: 'stream' });
//data.pipe(hashObject);
const hash = await new Promise<string>((resolve, reject) => {
const hashObject = createHash('sha256');
data.on('data', (data) => hashObject.update(data));
data.on('error', reject);
data.on('end', () => resolve(hashObject.digest('hex')));
});
this.log(`Migrated hash: ${url} => ${hash}`);
return hash;
}
async migrateHashes() {
const archivesToDo = await this.db.getRepository(Archive).find({ where: { hash: IsNull() }, select: ['id', 'hash', 'path'] });
const tmpMap = new Map<string, string>();
for (const archive of archivesToDo) {
if (tmpMap.has(archive.path)) {
archive.hash = tmpMap.get(archive.path);
} else {
archive.hash = await this.getHashForMigrate(archive.archiveFullPath);
tmpMap.set(archive.path, archive.hash);
}
}
await this.db.getRepository(Archive).save(archivesToDo);
return new BlankReturnMessageDto(200, 'success');
}
} }
...@@ -21,7 +21,7 @@ export class Archive extends TimeBase { ...@@ -21,7 +21,7 @@ export class Archive extends TimeBase {
@Column('varchar', { length: 128 }) @Column('varchar', { length: 128 })
path: string; path: string;
@Column('varchar', { length: 128, nullable: true }) @Column('varchar', { length: 64, nullable: true })
hash: string; hash: string;
@Column('int', { unsigned: true }) @Column('int', { unsigned: true })
......
...@@ -201,7 +201,7 @@ export class PackagerService extends ConsoleLogger { ...@@ -201,7 +201,7 @@ export class PackagerService extends ConsoleLogger {
reject(error); reject(error);
}); });
}); });
const hashObject = createHash('sha512'); const hashObject = createHash('sha256');
child.stdout.on('data', (chunk) => { child.stdout.on('data', (chunk) => {
hashObject.update(chunk); hashObject.update(chunk);
}); });
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
{{#archives}} {{#archives}}
<file name="{{path}}.tar.zst"> <file name="{{path}}.tar.zst">
<size>{{size}}</size> <size>{{size}}</size>
<hash type="sha-256">{{hash}}</hash>
<url priority="1">{{&cdnUrl}}/{{path}}.tar.zst</url> <url priority="1">{{&cdnUrl}}/{{path}}.tar.zst</url>
</file> </file>
{{/archives}} {{/archives}}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment