This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/static/js/services/dockerfile/dockerfile.service.impl.ts

197 lines
6 KiB
TypeScript
Raw Normal View History

2017-03-07 19:25:18 +00:00
import { DockerfileService, DockerfileInfo } from './dockerfile.service';
import { Injectable } from 'angular-ts-decorators';
@Injectable(DockerfileService.name)
export class DockerfileServiceImpl implements DockerfileService {
2017-03-08 01:34:43 +00:00
constructor(private DataFileService: any, private Config: any, private FileReaderFactory: () => FileReader) {
}
public extractDockerfile(file: any): Promise<DockerfileInfoImpl | string> {
return new Promise((resolve, reject) => {
2017-03-08 19:43:53 +00:00
var reader: FileReader = this.FileReaderFactory();
reader.onload = (event: any) => {
this.DataFileService.readDataArrayAsPossibleArchive(event.target.result,
(files: any[]) => {
this.processFiles1(files);
},
() => {
// Not an archive. Read directly as a single file.
this.processFile1(event.target.result);
});
};
reader.onerror = (event: any) => reject(event);
reader.readAsArrayBuffer(file);
2017-03-08 01:34:43 +00:00
});
2017-03-07 19:25:18 +00:00
}
public getDockerfile(file: any,
success: (dockerfile: DockerfileInfoImpl) => void,
failure: (error: Event | string) => void): void {
2017-03-08 01:34:43 +00:00
var reader: FileReader = this.FileReaderFactory();
reader.onload = (event: any) => {
this.DataFileService.readDataArrayAsPossibleArchive(event.target.result,
(files: any[]) => {
2017-03-08 05:46:12 +00:00
this.processFiles(files, success, failure);
2017-03-08 01:34:43 +00:00
},
() => {
2017-03-08 05:46:12 +00:00
// Not an archive. Read directly as a single file.
this.processFile(event.target.result, success, failure);
2017-03-07 19:25:18 +00:00
});
};
reader.onerror = failure;
reader.readAsArrayBuffer(file);
}
2017-03-08 05:46:12 +00:00
private processFile(dataArray: any,
success: (dockerfile: DockerfileInfoImpl) => void,
failure: (error: ErrorEvent | string) => void): void {
this.DataFileService.arrayToString(dataArray, (contents: string) => {
var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config);
if (result == null) {
failure('File chosen is not a valid Dockerfile');
}
else {
success(result);
}
});
}
2017-03-08 19:43:53 +00:00
private processFile1(dataArray: any): Promise<DockerfileInfoImpl | string> {
return new Promise((resolve, reject) => {
this.DataFileService.arrayToString(dataArray, (contents: string) => {
var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config);
if (result == null) {
reject('File chosen is not a valid Dockerfile');
}
else {
resolve(result);
}
});
});
}
2017-03-08 01:34:43 +00:00
private processFiles(files: any[],
2017-03-07 19:25:18 +00:00
success: (dockerfile: DockerfileInfoImpl) => void,
failure: (error: ErrorEvent | string) => void): void {
var found: boolean = false;
files.forEach((file) => {
if (file['name'] == 'Dockerfile') {
this.DataFileService.blobToString(file.toBlob(), (contents: string) => {
2017-03-08 01:34:43 +00:00
var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config);
if (result == null) {
2017-03-07 19:25:18 +00:00
failure('Dockerfile inside archive is not a valid Dockerfile');
}
2017-03-08 05:46:12 +00:00
else {
success(result);
}
2017-03-07 19:25:18 +00:00
});
found = true;
}
});
if (!found) {
failure('No Dockerfile found in root of archive');
}
}
2017-03-08 19:43:53 +00:00
private processFiles1(files: any[]): Promise<DockerfileInfoImpl | string> {
return new Promise((resolve, reject) => {
var found: boolean = false;
files.forEach((file) => {
if (file['name'] == 'Dockerfile') {
this.DataFileService.blobToString(file.toBlob(), (contents: string) => {
var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config);
if (result == null) {
reject('Dockerfile inside archive is not a valid Dockerfile');
}
else {
resolve(result);
}
});
found = true;
}
});
if (!found) {
reject('No Dockerfile found in root of archive');
}
});
}
2017-03-07 19:25:18 +00:00
}
export class DockerfileInfoImpl implements DockerfileInfo {
constructor(private contents: string, private config: any) {
}
public static forData(contents: string, config: any): DockerfileInfoImpl | null {
var dockerfileInfo: DockerfileInfoImpl = null;
if (contents.indexOf('FROM ') != -1) {
dockerfileInfo = new DockerfileInfoImpl(contents, config);
}
return dockerfileInfo;
}
public getRegistryBaseImage(): string | null {
var baseImage = this.getBaseImage();
if (!baseImage) {
return null;
}
if (baseImage.indexOf(this.config.getDomain() + '/') != 0) {
return null;
}
return baseImage.substring(this.config.getDomain().length + 1);
}
public getBaseImage(): string | null {
2017-03-08 01:34:43 +00:00
const imageAndTag = this.getBaseImageAndTag();
2017-03-07 19:25:18 +00:00
if (!imageAndTag) {
return null;
}
// Note, we have to handle a few different cases here:
// 1) someimage
// 2) someimage:tag
// 3) host:port/someimage
// 4) host:port/someimage:tag
2017-03-08 01:34:43 +00:00
const lastIndex: number = imageAndTag.lastIndexOf(':');
if (lastIndex == -1) {
2017-03-07 19:25:18 +00:00
return imageAndTag;
}
// Otherwise, check if there is a / in the portion after the split point. If so,
// then the latter is part of the path (and not a tag).
2017-03-08 01:34:43 +00:00
const afterColon: string = imageAndTag.substring(lastIndex + 1);
if (afterColon.indexOf('/') != -1) {
2017-03-07 19:25:18 +00:00
return imageAndTag;
}
return imageAndTag.substring(0, lastIndex);
}
public getBaseImageAndTag(): string | null {
var baseImageAndTag: string = null;
const fromIndex: number = this.contents.indexOf('FROM ');
if (fromIndex != -1) {
var newlineIndex: number = this.contents.indexOf('\n', fromIndex);
if (newlineIndex == -1) {
newlineIndex = this.contents.length;
}
baseImageAndTag = this.contents.substring(fromIndex + 'FROM '.length, newlineIndex).trim();
}
return baseImageAndTag;
}
}