docker/ts/docker.classes.service.ts

191 lines
5.2 KiB
TypeScript
Raw Normal View History

2019-08-15 16:50:13 +00:00
import * as plugins from './docker.plugins';
2019-08-14 12:19:45 +00:00
import * as interfaces from './interfaces';
import { DockerHost } from './docker.classes.host';
2019-08-16 12:46:48 +00:00
import { DockerImage } from './docker.classes.image';
2019-09-12 12:45:36 +00:00
import { DockerSecret } from './docker.classes.secret';
2019-08-14 12:19:45 +00:00
2019-08-16 10:48:40 +00:00
export class DockerService {
// STATIC
public static async getServices(dockerHost: DockerHost) {
const services: DockerService[] = [];
const response = await dockerHost.request('GET', '/services');
for (const serviceObject of response.body) {
2019-09-08 17:22:20 +00:00
const dockerService = new DockerService(dockerHost);
Object.assign(dockerService, serviceObject);
services.push(dockerService);
2019-08-16 10:48:40 +00:00
}
return services;
}
2019-09-12 12:45:36 +00:00
public static async getServiceByName(
dockerHost: DockerHost,
networkName: string
): Promise<DockerService> {
2019-09-08 17:22:20 +00:00
const allServices = await DockerService.getServices(dockerHost);
const wantedService = allServices.find(service => {
return service.Spec.Name === networkName;
});
return wantedService;
}
2019-08-16 10:48:40 +00:00
/**
* creates a service
*/
2019-08-16 10:48:56 +00:00
public static async createService(
dockerHost: DockerHost,
serviceCreationDescriptor: interfaces.IServiceCreationDescriptor
2019-09-08 17:22:20 +00:00
): Promise<DockerService> {
2019-08-16 12:46:48 +00:00
// lets get the image
2019-09-12 12:45:36 +00:00
plugins.smartlog.defaultLogger.log(
'info',
2019-09-13 14:57:21 +00:00
`now creating service ${serviceCreationDescriptor.name}`
2019-09-12 12:45:36 +00:00
);
2019-09-13 14:57:21 +00:00
// await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
const serviceVersion = await serviceCreationDescriptor.image.getVersion();
2019-09-13 12:40:38 +00:00
const labels: interfaces.TLabels = {
...serviceCreationDescriptor.labels,
version: serviceVersion
};
2019-09-11 18:25:45 +00:00
2019-08-16 16:21:55 +00:00
const networkArray: any[] = [];
for (const network of serviceCreationDescriptor.networks) {
networkArray.push({
Target: network.Name,
2019-08-16 16:32:41 +00:00
Aliases: [serviceCreationDescriptor.networkAlias]
2019-08-16 16:21:55 +00:00
});
}
2019-09-12 12:45:36 +00:00
const secretArray: any[] = [];
for (const secret of serviceCreationDescriptor.secrets) {
secretArray.push({
File: {
Name: 'secret.json',
UID: '33',
GID: '33',
Mode: 384
},
SecretID: secret.ID,
SecretName: secret.Spec.Name
});
}
2019-09-08 17:22:20 +00:00
const response = await dockerHost.request('POST', '/services/create', {
2019-09-13 12:40:38 +00:00
Name: serviceCreationDescriptor.name,
2019-08-16 10:48:40 +00:00
TaskTemplate: {
ContainerSpec: {
2019-09-13 14:57:21 +00:00
Image: serviceCreationDescriptor.image.RepoTags[0],
2019-09-13 12:40:38 +00:00
Labels: labels,
2019-09-12 12:45:36 +00:00
Secrets: secretArray
},
UpdateConfig: {
Parallelism: 0,
Delay: 0,
FailureAction: 'pause',
Monitor: 15000000000,
MaxFailureRatio: 0.15
2019-09-11 18:25:45 +00:00
},
ForceUpdate: 1
2019-08-16 10:48:40 +00:00
},
2019-09-13 12:40:38 +00:00
Labels: serviceCreationDescriptor.labels,
2019-08-16 16:21:55 +00:00
Networks: networkArray
2019-08-16 10:48:40 +00:00
});
2019-09-08 17:22:20 +00:00
2019-09-12 12:45:36 +00:00
const createdService = await DockerService.getServiceByName(
dockerHost,
2019-09-13 12:40:38 +00:00
serviceCreationDescriptor.name
2019-09-12 12:45:36 +00:00
);
2019-09-08 17:22:20 +00:00
return createdService;
2019-08-16 10:48:40 +00:00
}
// INSTANCE
2019-09-08 17:22:20 +00:00
public dockerHostRef: DockerHost;
2019-09-12 12:45:36 +00:00
2019-09-08 17:22:20 +00:00
public ID: string;
public Version: { Index: number };
public CreatedAt: string;
public UpdatedAt: string;
public Spec: {
Name: string;
2019-09-13 11:20:01 +00:00
Labels: interfaces.TLabels;
2019-09-11 18:25:45 +00:00
TaskTemplate: {
ContainerSpec: {
Image: string;
Isolation: string;
2019-09-12 12:45:36 +00:00
Secrets: Array<{
File: {
Name: string;
UID: string;
GID: string;
Mode: number;
};
SecretID: string;
SecretName: string;
}>;
};
2019-09-11 18:25:45 +00:00
ForceUpdate: 0;
2019-09-12 12:45:36 +00:00
};
2019-09-11 18:25:45 +00:00
Mode: {};
2019-09-12 12:45:36 +00:00
Networks: [any[]];
2019-09-08 17:22:20 +00:00
};
2019-09-12 12:45:36 +00:00
public Endpoint: { Spec: {}; VirtualIPs: [any[]] };
2019-09-08 17:22:20 +00:00
constructor(dockerHostArg: DockerHost) {
this.dockerHostRef = dockerHostArg;
2019-08-16 10:48:40 +00:00
}
2019-08-16 19:07:59 +00:00
2019-09-08 17:22:20 +00:00
public async update() {
2019-09-11 18:25:45 +00:00
const labels: interfaces.TLabels = {
...this.Spec.Labels,
2019-09-12 12:45:36 +00:00
version: 'x.x.x'
2019-09-11 18:25:45 +00:00
};
2019-09-12 12:45:36 +00:00
const dockerData = await this.dockerHostRef.request(
'POST',
2019-09-12 12:52:55 +00:00
`/services/${this.ID}/update?version=${this.Version.Index}`,
2019-09-12 12:45:36 +00:00
{
Name: this.Spec.Name,
TaskTemplate: this.Spec.TaskTemplate,
Labels: labels,
Networks: this.Spec.Networks
}
);
2019-09-11 18:25:45 +00:00
Object.assign(this, dockerData);
2019-08-16 19:07:59 +00:00
}
2019-09-08 17:22:20 +00:00
public async remove() {
await this.dockerHostRef.request('DELETE', `/services/${this.ID}`);
}
2019-09-11 18:25:45 +00:00
2019-09-12 12:45:36 +00:00
public async reReadFromDockerEngine() {
2019-09-11 18:25:45 +00:00
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
Object.assign(this, dockerData);
}
2019-09-13 11:20:01 +00:00
public async needsUpdate(): Promise<boolean> {
2019-09-11 18:25:45 +00:00
// TODO: implement digest based update recognition
await this.reReadFromDockerEngine();
const dockerImage = await DockerImage.createFromRegistry(this.dockerHostRef, {
2019-09-12 12:45:36 +00:00
imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image
2019-09-11 18:25:45 +00:00
});
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version);
if (imageVersion.greaterThan(serviceVersion)) {
2019-09-13 11:20:01 +00:00
console.log(`service ${this.Spec.Name} needs to be updated`);
return true;
} else {
console.log(`service ${this.Spec.Name} is up to date.`);
}
}
public async updateFromRegistry() {
if (await this.needsUpdate()) {
2019-09-11 18:25:45 +00:00
this.update();
}
}
2019-08-16 10:48:40 +00:00
}