Compare commits

..

4 Commits

Author SHA1 Message Date
e983b66c28 1.0.54 2019-09-11 20:25:46 +02:00
c79f6a698f fix(core): update 2019-09-11 20:25:45 +02:00
0ef098e9c8 1.0.53 2019-09-08 19:22:20 +02:00
d56350ff28 fix(core): update 2019-09-08 19:22:20 +02:00
7 changed files with 143 additions and 29 deletions

29
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@mojoio/docker", "name": "@mojoio/docker",
"version": "1.0.52", "version": "1.0.54",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -249,9 +249,9 @@
"integrity": "sha512-jmrJMUEmBCWChWK8CIcx4Vw3wv/8OgVNmkaxJrbs+WMaoRUfJtpWWJfrAwwHWt9ZXJbarJ+CwfwfYiiZXymndQ==" "integrity": "sha512-jmrJMUEmBCWChWK8CIcx4Vw3wv/8OgVNmkaxJrbs+WMaoRUfJtpWWJfrAwwHWt9ZXJbarJ+CwfwfYiiZXymndQ=="
}, },
"@pushrocks/smartrequest": { "@pushrocks/smartrequest": {
"version": "1.1.23", "version": "1.1.26",
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartrequest/-/smartrequest-1.1.23.tgz", "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartrequest/-/smartrequest-1.1.26.tgz",
"integrity": "sha512-Hws3YfzIE0b/E3aTkSugLskKWBq7e8HDXEN+RlRyTFONxW/XONKJFTw4mp3jk+puWpYGDoOTcP+Ua4jd19z9pA==", "integrity": "sha512-8tYY+N42qdSTN5x40m6Afqmjo8HwkuZW+iWdMwO8PFxhrymcx8kuf5rYcG0wVLGtBjDgKgVNidb8GgFEhG40Yw==",
"requires": { "requires": {
"@pushrocks/smartpromise": "^3.0.2", "@pushrocks/smartpromise": "^3.0.2",
"@types/form-data": "^2.2.1", "@types/form-data": "^2.2.1",
@ -313,6 +313,22 @@
"luxon": "^1.16.0" "luxon": "^1.16.0"
} }
}, },
"@pushrocks/smartversion": {
"version": "2.0.4",
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartversion/-/smartversion-2.0.4.tgz",
"integrity": "sha512-LrtaWRn1DD2zIUr8nVAsKwZ+Y55TFIVZ0z3xjwAQ46SoiTrFWooeQ2Xw18DqsEo1cEqMZyGAskaJkOaRkXHtUA==",
"requires": {
"@types/semver": "^6.0.2",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://verdaccio.lossless.one/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
"@pushrocks/tapbundle": { "@pushrocks/tapbundle": {
"version": "3.0.13", "version": "3.0.13",
"resolved": "https://verdaccio.lossless.one/@pushrocks%2ftapbundle/-/tapbundle-3.0.13.tgz", "resolved": "https://verdaccio.lossless.one/@pushrocks%2ftapbundle/-/tapbundle-3.0.13.tgz",
@ -409,6 +425,11 @@
"resolved": "https://verdaccio.lossless.one/@types%2fportscanner/-/portscanner-2.1.0.tgz", "resolved": "https://verdaccio.lossless.one/@types%2fportscanner/-/portscanner-2.1.0.tgz",
"integrity": "sha512-II0FA05TSt4r7PBUvYTqub+yrXTRu7L/PQnTtjcJYzAeBts6xHM/OA2MKyeQ80sFxX7p+0BTo68Nh1P3N6Oj/g==" "integrity": "sha512-II0FA05TSt4r7PBUvYTqub+yrXTRu7L/PQnTtjcJYzAeBts6xHM/OA2MKyeQ80sFxX7p+0BTo68Nh1P3N6Oj/g=="
}, },
"@types/semver": {
"version": "6.0.2",
"resolved": "https://verdaccio.lossless.one/@types%2fsemver/-/semver-6.0.2.tgz",
"integrity": "sha512-G1Ggy7/9Nsa1Jt2yiBR2riEuyK2DFNnqow6R7cromXPMNynackRY1vqFTLz/gwnef1LHokbXThcPhqMRjUbkpQ=="
},
"@types/vinyl": { "@types/vinyl": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://verdaccio.lossless.one/@types%2fvinyl/-/vinyl-2.0.3.tgz", "resolved": "https://verdaccio.lossless.one/@types%2fvinyl/-/vinyl-2.0.3.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "@mojoio/docker", "name": "@mojoio/docker",
"version": "1.0.52", "version": "1.0.54",
"description": "easy communication with docker remote api from node, TypeScript ready", "description": "easy communication with docker remote api from node, TypeScript ready",
"private": false, "private": false,
"main": "dist/index.js", "main": "dist/index.js",
@ -31,7 +31,8 @@
"@pushrocks/smartlog": "^2.0.19", "@pushrocks/smartlog": "^2.0.19",
"@pushrocks/smartnetwork": "^1.1.14", "@pushrocks/smartnetwork": "^1.1.14",
"@pushrocks/smartpromise": "^3.0.2", "@pushrocks/smartpromise": "^3.0.2",
"@pushrocks/smartrequest": "^1.1.23", "@pushrocks/smartrequest": "^1.1.26",
"@pushrocks/smartversion": "^2.0.4",
"rxjs": "^6.5.3" "rxjs": "^6.5.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -5,12 +5,12 @@ import { DockerService } from '../ts/index';
let testDockerHost: docker.DockerHost; let testDockerHost: docker.DockerHost;
tap.test('should create a new Dockersock instance', async () => { tap.test('should create a new Dockersock instance', async () => {
testDockerHost = new docker.DockerHost(); testDockerHost = new docker.DockerHost('http://unix:/var/run/docker.sock:');
return expect(testDockerHost).to.be.instanceof(docker.DockerHost); return expect(testDockerHost).to.be.instanceof(docker.DockerHost);
}); });
tap.test('should create a docker swarm', async () => { tap.test('should create a docker swarm', async () => {
await testDockerHost.activateSwarm();
}); });
// Containers // Containers
@ -63,7 +63,7 @@ tap.test('should activate swarm mode', async () => {
}); });
tap.test('should list all services', async tools => { tap.test('should list all services', async tools => {
const services = await docker.DockerService.getServices(testDockerHost); const services = await testDockerHost.getServices();
console.log(services); console.log(services);
}); });
@ -71,7 +71,7 @@ tap.test('should create a service', async () => {
const testNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, { const testNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, {
Name: 'testNetwork' Name: 'testNetwork'
}); });
await DockerService.createService(testDockerHost, { const testService = await DockerService.createService(testDockerHost, {
Image: 'nginx:latest', Image: 'nginx:latest',
Labels: { Labels: {
'testlabel': 'hi' 'testlabel': 'hi'
@ -80,6 +80,8 @@ tap.test('should create a service', async () => {
networks: [testNetwork], networks: [testNetwork],
networkAlias: 'testService' networkAlias: 'testService'
}); });
await testService.remove();
await testNetwork.remove();
}); });
tap.start(); tap.start();

View File

@ -1,6 +1,7 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins';
import { DockerContainer } from './docker.classes.container'; import { DockerContainer } from './docker.classes.container';
import { DockerNetwork } from './docker.classes.network'; import { DockerNetwork } from './docker.classes.network';
import { DockerService } from './docker.classes.service';
export class DockerHost { export class DockerHost {
/** /**
@ -52,6 +53,14 @@ export class DockerHost {
return containerArray; return containerArray;
} }
/**
* gets all services
*/
public async getServices() {
const serviceArray = await DockerService.getServices(this);
return serviceArray;
}
/** /**
* *
*/ */
@ -115,7 +124,8 @@ export class DockerHost {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Host: 'docker.sock' Host: 'docker.sock'
}, },
requestBody: dataArg requestBody: dataArg,
keepAlive: false
}); });
if (response.statusCode !== 200) { if (response.statusCode !== 200) {
console.log(response.body); console.log(response.body);
@ -130,10 +140,11 @@ export class DockerHost {
{ {
method: methodArg, method: methodArg,
headers: { headers: {
// 'Content-Type': 'application/json', 'Content-Type': 'application/json',
Host: 'docker.sock' Host: 'docker.sock'
}, },
requestBody: null requestBody: null,
keepAlive: false
}, },
true true
); );

View File

@ -8,7 +8,9 @@ export class DockerNetwork {
const dockerNetworks: DockerNetwork[] = []; const dockerNetworks: DockerNetwork[] = [];
const response = await dockerHost.request('GET', '/networks'); const response = await dockerHost.request('GET', '/networks');
for (const networkObject of response.body) { for (const networkObject of response.body) {
dockerNetworks.push(new DockerNetwork(dockerHost, networkObject)); const dockerNetwork = new DockerNetwork(dockerHost);
Object.assign(dockerNetwork, networkObject);
dockerNetworks.push(dockerNetwork);
} }
return dockerNetworks; return dockerNetworks;
} }
@ -78,11 +80,8 @@ export class DockerNetwork {
]; ];
}; };
constructor(dockerHostArg: DockerHost, dockerNetworkObjectArg: any) { constructor(dockerHostArg: DockerHost) {
this.dockerHost = dockerHostArg; this.dockerHost = dockerHostArg;
Object.keys(dockerNetworkObjectArg).forEach(keyArg => {
this[keyArg] = dockerNetworkObjectArg[keyArg];
});
} }
/** /**

View File

@ -10,24 +10,37 @@ export class DockerService {
const services: DockerService[] = []; const services: DockerService[] = [];
const response = await dockerHost.request('GET', '/services'); const response = await dockerHost.request('GET', '/services');
for (const serviceObject of response.body) { for (const serviceObject of response.body) {
services.push(new DockerService(dockerHost, serviceObject)); const dockerService = new DockerService(dockerHost);
Object.assign(dockerService, serviceObject);
services.push(dockerService);
} }
return services; return services;
} }
public static async getServiceByName(dockerHost: DockerHost, networkName: string): Promise<DockerService> {
const allServices = await DockerService.getServices(dockerHost);
const wantedService = allServices.find(service => {
return service.Spec.Name === networkName;
});
return wantedService;
}
/** /**
* creates a service * creates a service
*/ */
public static async createService( public static async createService(
dockerHost: DockerHost, dockerHost: DockerHost,
serviceCreationDescriptor: interfaces.IServiceCreationDescriptor serviceCreationDescriptor: interfaces.IServiceCreationDescriptor
) { ): Promise<DockerService> {
// lets get the image // lets get the image
plugins.smartlog.defaultLogger.log('info', `downloading image for service ${serviceCreationDescriptor.Name}`); plugins.smartlog.defaultLogger.log('info', `downloading image for service ${serviceCreationDescriptor.Name}`);
const serviceImage = await DockerImage.createFromRegistry(dockerHost, { const serviceImage = await DockerImage.createFromRegistry(dockerHost, {
imageUrl: serviceCreationDescriptor.Image imageUrl: serviceCreationDescriptor.Image
}); });
const serviceVersion = serviceImage.Labels.version;
serviceCreationDescriptor.Labels.version = serviceVersion;
const networkArray: any[] = []; const networkArray: any[] = [];
for (const network of serviceCreationDescriptor.networks) { for (const network of serviceCreationDescriptor.networks) {
networkArray.push({ networkArray.push({
@ -36,28 +49,94 @@ export class DockerService {
}); });
} }
dockerHost.request('POST', '/services/create', { const response = await dockerHost.request('POST', '/services/create', {
Name: serviceCreationDescriptor.Name, Name: serviceCreationDescriptor.Name,
TaskTemplate: { TaskTemplate: {
ContainerSpec: { ContainerSpec: {
Image: serviceCreationDescriptor.Image, Image: serviceCreationDescriptor.Image,
Labels: serviceCreationDescriptor.Labels Labels: serviceCreationDescriptor.Labels
} },
ForceUpdate: 1
}, },
Labels: serviceCreationDescriptor.Labels, Labels: serviceCreationDescriptor.Labels,
Networks: networkArray Networks: networkArray
}); });
const createdService = await DockerService.getServiceByName(dockerHost, serviceCreationDescriptor.Name);
return createdService;
} }
// INSTANCE // INSTANCE
public dockerHost: DockerHost; public dockerHostRef: DockerHost;
public ID: string;
public Version: { Index: number };
public CreatedAt: string;
public UpdatedAt: string;
public Spec: {
Name: string;
Labels: interfaces.TLabels; // ZBD
TaskTemplate: {
ContainerSpec: {
Image: string;
Isolation: string;
}
ForceUpdate: 0;
},
Mode: {};
Networks: [any[]]
};
public Endpoint: { Spec: {}, VirtualIPs: [any[]] };
constructor(dockerHostArg: DockerHost, serviceObject) {
this.dockerHost = dockerHostArg; constructor(dockerHostArg: DockerHost) {
Object.assign(this, serviceObject); this.dockerHostRef = dockerHostArg;
} }
update() { public async update() {
const labels: interfaces.TLabels = {
...this.Spec.Labels,
};
const dockerData = await this.dockerHostRef.request('POST', `/servces/${this.ID}/update?version=${this.Version.Index}`, {
Name: this.Spec.Name,
TaskTemplate: {
ContainerSpec: {
Image: this.Spec.TaskTemplate.ContainerSpec.Image,
Labels: labels
},
ForceUpdate: 1
},
Labels: labels,
});
Object.assign(this, dockerData);
}
public async remove() {
await this.dockerHostRef.request('DELETE', `/services/${this.ID}`);
}
public async reReadFromDockerEngine () {
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
Object.assign(this, dockerData);
}
public async updateFromRegistry () {
// TODO: implement digest based update recognition
await this.reReadFromDockerEngine();
const dockerImage = await DockerImage.createFromRegistry(this.dockerHostRef, {
imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image
});
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version);
if (imageVersion.greaterThan(serviceVersion)) {
console.log('service needs to be updated');
this.update();
}
} }
} }

View File

@ -4,10 +4,11 @@ import * as smartlog from '@pushrocks/smartlog';
import * as smartnetwork from '@pushrocks/smartnetwork'; import * as smartnetwork from '@pushrocks/smartnetwork';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartpromise from '@pushrocks/smartpromise';
import * as smartrequest from '@pushrocks/smartrequest'; import * as smartrequest from '@pushrocks/smartrequest';
import * as smartversion from '@pushrocks/smartversion';
smartlog.defaultLogger.enableConsole(); smartlog.defaultLogger.enableConsole();
export { lik, smartlog, smartnetwork, smartpromise, smartrequest }; export { lik, smartlog, smartnetwork, smartpromise, smartrequest, smartversion };
// third party // third party
import * as rxjs from 'rxjs'; import * as rxjs from 'rxjs';