Compare commits

...

12 Commits

Author SHA1 Message Date
ea5e552192 1.0.61 2019-09-13 17:54:18 +02:00
1afe5c6e16 fix(core): update 2019-09-13 17:54:17 +02:00
eb0dc96dbd 1.0.60 2019-09-13 16:57:22 +02:00
55f45b1c3a fix(core): update 2019-09-13 16:57:21 +02:00
87ff0f01bb 1.0.59 2019-09-13 14:45:35 +02:00
dd1939d7b2 fix(core): update 2019-09-13 14:45:35 +02:00
5a2a5f1248 1.0.58 2019-09-13 14:40:38 +02:00
9767b8767a fix(core): update 2019-09-13 14:40:38 +02:00
546e139b46 1.0.57 2019-09-13 13:20:01 +02:00
28d70bb49f fix(core): update 2019-09-13 13:20:01 +02:00
b71f134abd 1.0.56 2019-09-12 14:52:56 +02:00
968b3c7449 fix(core): update 2019-09-12 14:52:55 +02:00
9 changed files with 87 additions and 32 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@mojoio/docker", "name": "@mojoio/docker",
"version": "1.0.55", "version": "1.0.61",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@mojoio/docker", "name": "@mojoio/docker",
"version": "1.0.55", "version": "1.0.61",
"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",

View File

@ -1,6 +1,5 @@
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
import * as docker from '../ts/index'; import * as docker from '../ts/index';
import { DockerService } from '../ts/index';
let testDockerHost: docker.DockerHost; let testDockerHost: docker.DockerHost;
@ -61,6 +60,7 @@ tap.test('should return a change Observable', async tools => {
tap.test('should create a secret', async () => { tap.test('should create a secret', async () => {
const mySecret = await docker.DockerSecret.createSecret(testDockerHost, { const mySecret = await docker.DockerSecret.createSecret(testDockerHost, {
name: 'testSecret', name: 'testSecret',
version: '1.0.3',
contentArg: `{ "hi": "wow"}`, contentArg: `{ "hi": "wow"}`,
labels: {} labels: {}
}); });
@ -89,15 +89,19 @@ tap.test('should create a service', async () => {
}); });
const testSecret = await docker.DockerSecret.createSecret(testDockerHost, { const testSecret = await docker.DockerSecret.createSecret(testDockerHost, {
name: 'serviceSecret', name: 'serviceSecret',
version: '0.0.1',
labels: {}, labels: {},
contentArg: '{"hi": "wow"}' contentArg: '{"hi": "wow"}'
}); });
const testService = await DockerService.createService(testDockerHost, { const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
Image: 'nginx:latest', imageUrl: 'nginx:latest'
Labels: { });
const testService = await docker.DockerService.createService(testDockerHost, {
image: testImage,
labels: {
'testlabel': 'hi' 'testlabel': 'hi'
}, },
Name: 'testService', name: 'testService',
networks: [testNetwork], networks: [testNetwork],
networkAlias: 'testService', networkAlias: 'testService',
secrets: [testSecret] secrets: [testSecret]

View File

@ -8,6 +8,7 @@ export class DockerHost {
* the path where the docker sock can be found * the path where the docker sock can be found
*/ */
public socketPath: string; public socketPath: string;
private registryToken: string = '';
/** /**
* the constructor to instantiate a new docker sock instance * the constructor to instantiate a new docker sock instance
@ -34,8 +35,18 @@ export class DockerHost {
const response = await this.request('POST', '/auth', { const response = await this.request('POST', '/auth', {
serveraddress: registryUrl, serveraddress: registryUrl,
username: userArg, username: userArg,
password: passArg, password: passArg
}); });
if (response.body.Status !== 'Login Succeeded') {
console.log(`Login failed with ${response.body.Status}`);
throw new Error(response.body.Status);
}
console.log(response.body.Status);
this.registryToken = plugins.smartstring.base64.encode(response.body.IdentityToken);
}
public setAuthToken(authToken: string) {
this.registryToken = authToken;
} }
/** /**
@ -122,6 +133,7 @@ export class DockerHost {
method: methodArg, method: methodArg,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Registry-Auth': this.registryToken,
Host: 'docker.sock' Host: 'docker.sock'
}, },
requestBody: dataArg, requestBody: dataArg,

View File

@ -15,9 +15,15 @@ export class DockerImage {
public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) { public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) {
const images = await this.getImages(dockerHost); const images = await this.getImages(dockerHost);
return images.find(image => { const result = images.find(image => {
return image.RepoTags.includes(imageNameArg); if (image.RepoTags) {
return image.RepoTags.includes(imageNameArg);
} else {
return false;
}
}); });
return result;
} }
public static async createFromRegistry( public static async createFromRegistry(
@ -113,7 +119,13 @@ export class DockerImage {
}); });
} }
public tagImage(newTag) {} /**
* tag an image
* @param newTag
*/
public async tagImage(newTag) {
throw new Error('.tagImage is not yet implemented');
}
/** /**
* pulls the latest version from the registry * pulls the latest version from the registry
@ -126,4 +138,9 @@ export class DockerImage {
// TODO: Compare image digists before and after // TODO: Compare image digists before and after
return true; return true;
} }
// get stuff
public async getVersion() {
return this.Labels.version;
}
} }

View File

@ -28,9 +28,13 @@ export class DockerSecret {
} }
public static async createSecret(dockerHostArg: DockerHost, secretDescriptor: interfaces.ISecretCreationDescriptor) { public static async createSecret(dockerHostArg: DockerHost, secretDescriptor: interfaces.ISecretCreationDescriptor) {
const labels: interfaces.TLabels = {
...secretDescriptor.labels,
version: secretDescriptor.version
};
const response = await dockerHostArg.request('POST', '/secrets/create', { const response = await dockerHostArg.request('POST', '/secrets/create', {
Name: secretDescriptor.name, Name: secretDescriptor.name,
Labels: secretDescriptor.labels, Labels: labels,
Data: plugins.smartstring.base64.encode(secretDescriptor.contentArg) Data: plugins.smartstring.base64.encode(secretDescriptor.contentArg)
}); });
@ -46,9 +50,9 @@ export class DockerSecret {
Name: string; Name: string;
Labels: interfaces.TLabels; Labels: interfaces.TLabels;
}; };
Version: { public Version: {
Index:string; Index:string;
} };
public dockerHost: DockerHost; public dockerHost: DockerHost;
constructor(dockerHostArg: DockerHost) { constructor(dockerHostArg: DockerHost) {
@ -70,4 +74,10 @@ export class DockerSecret {
public async remove () { public async remove () {
await this.dockerHost.request('DELETE', `/secrets/${this.ID}`); await this.dockerHost.request('DELETE', `/secrets/${this.ID}`);
} }
// get things
public async getVersion() {
return this.Spec.Labels.version;
}
} }

View File

@ -39,14 +39,16 @@ export class DockerService {
// lets get the image // lets get the image
plugins.smartlog.defaultLogger.log( plugins.smartlog.defaultLogger.log(
'info', 'info',
`downloading image for service ${serviceCreationDescriptor.Name}` `now creating service ${serviceCreationDescriptor.name}`
); );
const serviceImage = await DockerImage.createFromRegistry(dockerHost, {
imageUrl: serviceCreationDescriptor.Image // await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
}); const serviceVersion = await serviceCreationDescriptor.image.getVersion();
const serviceVersion = serviceImage.Labels.version; const labels: interfaces.TLabels = {
serviceCreationDescriptor.Labels.version = serviceVersion; ...serviceCreationDescriptor.labels,
version: serviceVersion
};
const networkArray: any[] = []; const networkArray: any[] = [];
for (const network of serviceCreationDescriptor.networks) { for (const network of serviceCreationDescriptor.networks) {
@ -71,11 +73,11 @@ export class DockerService {
} }
const response = await 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.RepoTags[0],
Labels: serviceCreationDescriptor.Labels, Labels: labels,
Secrets: secretArray Secrets: secretArray
}, },
UpdateConfig: { UpdateConfig: {
@ -87,13 +89,13 @@ export class DockerService {
}, },
ForceUpdate: 1 ForceUpdate: 1
}, },
Labels: serviceCreationDescriptor.Labels, Labels: serviceCreationDescriptor.labels,
Networks: networkArray Networks: networkArray
}); });
const createdService = await DockerService.getServiceByName( const createdService = await DockerService.getServiceByName(
dockerHost, dockerHost,
serviceCreationDescriptor.Name serviceCreationDescriptor.name
); );
return createdService; return createdService;
} }
@ -107,7 +109,7 @@ export class DockerService {
public UpdatedAt: string; public UpdatedAt: string;
public Spec: { public Spec: {
Name: string; Name: string;
Labels: interfaces.TLabels; // ZBD Labels: interfaces.TLabels;
TaskTemplate: { TaskTemplate: {
ContainerSpec: { ContainerSpec: {
Image: string; Image: string;
@ -142,7 +144,7 @@ export class DockerService {
const dockerData = await this.dockerHostRef.request( const dockerData = await this.dockerHostRef.request(
'POST', 'POST',
`/services/${this.ID}/update?version=${this.Version.Index + 1}`, `/services/${this.ID}/update?version=${this.Version.Index}`,
{ {
Name: this.Spec.Name, Name: this.Spec.Name,
TaskTemplate: this.Spec.TaskTemplate, TaskTemplate: this.Spec.TaskTemplate,
@ -162,7 +164,7 @@ export class DockerService {
Object.assign(this, dockerData); Object.assign(this, dockerData);
} }
public async updateFromRegistry() { public async needsUpdate(): Promise<boolean> {
// TODO: implement digest based update recognition // TODO: implement digest based update recognition
await this.reReadFromDockerEngine(); await this.reReadFromDockerEngine();
@ -173,7 +175,15 @@ export class DockerService {
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version); const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version); const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version);
if (imageVersion.greaterThan(serviceVersion)) { if (imageVersion.greaterThan(serviceVersion)) {
console.log('service needs to be updated'); 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()) {
this.update(); this.update();
} }
} }

View File

@ -2,6 +2,7 @@ import * as interfaces from './';
export interface ISecretCreationDescriptor { export interface ISecretCreationDescriptor {
name: string; name: string;
version: string;
contentArg: any; contentArg: any;
labels: interfaces.TLabels; labels: interfaces.TLabels;
} }

View File

@ -1,11 +1,12 @@
import * as interfaces from './'; import * as interfaces from './';
import { DockerNetwork } from '../docker.classes.network'; import { DockerNetwork } from '../docker.classes.network';
import { DockerSecret } from '../docker.classes.secret'; import { DockerSecret } from '../docker.classes.secret';
import { DockerImage } from '../docker.classes.image';
export interface IServiceCreationDescriptor { export interface IServiceCreationDescriptor {
Name: string; name: string;
Image: string; image: DockerImage;
Labels: interfaces.TLabels; labels: interfaces.TLabels;
networks: DockerNetwork[]; networks: DockerNetwork[];
networkAlias: string; networkAlias: string;
secrets: DockerSecret[]; secrets: DockerSecret[];