mirror of
https://github.com/caprover/caprover
synced 2026-08-03 22:30:56 +00:00
Dockerregistry converted
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
const CaptainConstants = require('../utils/CaptainConstants');
|
||||
const Logger = require('../utils/Logger');
|
||||
const EnvVars = require('../utils/EnvVars');
|
||||
const fs = require('fs-extra');
|
||||
const uuid = require('uuid/v4');
|
||||
const ApiStatusCodes = require('../api/ApiStatusCodes');
|
||||
const bcrypt = require('bcryptjs');
|
||||
"use strict";
|
||||
const CaptainConstants = require("../utils/CaptainConstants");
|
||||
const Logger = require("../utils/Logger");
|
||||
const fs = require("fs-extra");
|
||||
const ApiStatusCodes = require("../api/ApiStatusCodes");
|
||||
const bcrypt = require("bcryptjs");
|
||||
class DockerRegistry {
|
||||
constructor(dockerApi, dataStore, certbotManager, loadBalancerManager, captainManager) {
|
||||
this.dockerApi = dockerApi;
|
||||
@@ -12,11 +11,15 @@ class DockerRegistry {
|
||||
this.certbotManager = certbotManager;
|
||||
this.loadBalancerManager = loadBalancerManager;
|
||||
this.captainManager = captainManager;
|
||||
// this.dockerApi = dockerApi;
|
||||
// this.dataStore = dataStore;
|
||||
// this.certbotManager = certbotManager;
|
||||
// this.loadBalancerManager = loadBalancerManager;
|
||||
// this.captainManager = captainManager;
|
||||
}
|
||||
enableLocalDockerRegistry() {
|
||||
const self = this;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
return self.dataStore.setHasLocalRegistry(true);
|
||||
});
|
||||
}
|
||||
@@ -28,9 +31,11 @@ class DockerRegistry {
|
||||
})
|
||||
.then(function (rootHasSsl) {
|
||||
if (!rootHasSsl) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, 'Root must have SSL before enabling ssl for docker registry.');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, "Root must have SSL before enabling ssl for docker registry.");
|
||||
}
|
||||
return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain + '.' + self.dataStore.getRootDomain());
|
||||
return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
self.dataStore.getRootDomain());
|
||||
})
|
||||
.then(function () {
|
||||
return self.dataStore.setHasRegistrySsl(true);
|
||||
@@ -44,9 +49,11 @@ class DockerRegistry {
|
||||
}
|
||||
getLocalRegistryDomainAndPort() {
|
||||
const self = this;
|
||||
return CaptainConstants.registrySubDomain + '.' +
|
||||
return (CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
self.dataStore.getRootDomain() +
|
||||
':' + CaptainConstants.registrySubDomainPort;
|
||||
":" +
|
||||
CaptainConstants.registrySubDomainPort);
|
||||
}
|
||||
ensureDockerRegistryRunningOnThisNode() {
|
||||
const dockerApi = this.dockerApi;
|
||||
@@ -54,72 +61,86 @@ class DockerRegistry {
|
||||
const myNodeId = this.captainManager.getMyNodeId();
|
||||
const captainSalt = this.captainManager.getCaptainSalt();
|
||||
function createRegistryServiceOnNode() {
|
||||
return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [{
|
||||
protocol: 'tcp',
|
||||
return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [
|
||||
{
|
||||
protocol: "tcp",
|
||||
containerPort: 5000,
|
||||
hostPort: CaptainConstants.registrySubDomainPort
|
||||
}], myNodeId, [{
|
||||
containerPath: '/cert-files',
|
||||
hostPath: CaptainConstants.letsEncryptEtcPath
|
||||
hostPort: CaptainConstants.registrySubDomainPort,
|
||||
},
|
||||
], myNodeId, [
|
||||
{
|
||||
containerPath: "/cert-files",
|
||||
hostPath: CaptainConstants.letsEncryptEtcPath,
|
||||
},
|
||||
{
|
||||
containerPath: '/var/lib/registry',
|
||||
hostPath: CaptainConstants.registryPathOnHost
|
||||
containerPath: "/var/lib/registry",
|
||||
hostPath: CaptainConstants.registryPathOnHost,
|
||||
},
|
||||
{
|
||||
containerPath: '/etc/auth',
|
||||
hostPath: CaptainConstants.registryAuthPathOnHost
|
||||
}
|
||||
], [{
|
||||
key: 'REGISTRY_HTTP_TLS_CERTIFICATE',
|
||||
value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/fullchain.pem'
|
||||
}, {
|
||||
key: 'REGISTRY_HTTP_TLS_KEY',
|
||||
value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/privkey.pem'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH',
|
||||
value: 'htpasswd'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH_HTPASSWD_REALM',
|
||||
value: 'Registry Realm'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH_HTPASSWD_PATH',
|
||||
value: '/etc/auth'
|
||||
}]);
|
||||
containerPath: "/etc/auth",
|
||||
hostPath: CaptainConstants.registryAuthPathOnHost,
|
||||
},
|
||||
], [
|
||||
{
|
||||
key: "REGISTRY_HTTP_TLS_CERTIFICATE",
|
||||
value: "/cert-files/live/" +
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
dataStore.getRootDomain() +
|
||||
"/fullchain.pem",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_HTTP_TLS_KEY",
|
||||
value: "/cert-files/live/" +
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
dataStore.getRootDomain() +
|
||||
"/privkey.pem",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH",
|
||||
value: "htpasswd",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH_HTPASSWD_REALM",
|
||||
value: "Registry Realm",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH_HTPASSWD_PATH",
|
||||
value: "/etc/auth",
|
||||
},
|
||||
], undefined);
|
||||
}
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
let authContent = CaptainConstants.captainRegistryUsername + ':' +
|
||||
const authContent = CaptainConstants.captainRegistryUsername +
|
||||
":" +
|
||||
bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5));
|
||||
return fs.outputFile(CaptainConstants.registryAuthPathOnHost, authContent);
|
||||
})
|
||||
.then(function () {
|
||||
return dockerApi
|
||||
.isServiceRunningByName(CaptainConstants.registryServiceName);
|
||||
return dockerApi.isServiceRunningByName(CaptainConstants.registryServiceName);
|
||||
})
|
||||
.then(function (isRunning) {
|
||||
if (isRunning) {
|
||||
Logger.d('Captain Registry is already running.. ');
|
||||
return dockerApi
|
||||
.getNodeIdByServiceName(CaptainConstants.registryServiceName);
|
||||
Logger.d("Captain Registry is already running.. ");
|
||||
return dockerApi.getNodeIdByServiceName(CaptainConstants.registryServiceName);
|
||||
}
|
||||
else {
|
||||
Logger.d('No Captain Registry service is running. Creating one...');
|
||||
return createRegistryServiceOnNode(myNodeId)
|
||||
.then(function () {
|
||||
Logger.d("No Captain Registry service is running. Creating one...");
|
||||
return createRegistryServiceOnNode().then(function () {
|
||||
return myNodeId;
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(function (nodeId) {
|
||||
if (nodeId !== myNodeId) {
|
||||
Logger.d('Captain Registry is running on a different node. Removing...');
|
||||
Logger.d("Captain Registry is running on a different node. Removing...");
|
||||
return dockerApi
|
||||
.removeServiceByName(CaptainConstants.registryServiceName)
|
||||
.then(function () {
|
||||
Logger.d('Creating Registry on this node...');
|
||||
return createRegistryServiceOnNode(myNodeId)
|
||||
.then(function () {
|
||||
Logger.d("Creating Registry on this node...");
|
||||
return createRegistryServiceOnNode().then(function () {
|
||||
return true;
|
||||
});
|
||||
});
|
||||
@@ -132,9 +153,9 @@ class DockerRegistry {
|
||||
updateRegistryAuthHeader(username, password, domain, currentVersion) {
|
||||
const self = this;
|
||||
const dockerApi = this.dockerApi;
|
||||
let nextVersion = null;
|
||||
let secretName = null;
|
||||
let userEmailAddress;
|
||||
let nextVersion = undefined;
|
||||
let secretName = undefined;
|
||||
let userEmailAddress = undefined;
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return self.dataStore.getUserEmailAddress();
|
||||
@@ -148,15 +169,17 @@ class DockerRegistry {
|
||||
})
|
||||
.then(function (versionSaved) {
|
||||
nextVersion = versionSaved + 1;
|
||||
secretName = CaptainConstants.captainRegistryAuthHeaderSecretPrefix + nextVersion;
|
||||
secretName =
|
||||
CaptainConstants.captainRegistryAuthHeaderSecretPrefix +
|
||||
nextVersion;
|
||||
if (!username || !password || !domain) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'user, pass and domain are all required');
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "user, pass and domain are all required");
|
||||
}
|
||||
return dockerApi.checkIfSecretExist(secretName);
|
||||
})
|
||||
.then(function (secretExist) {
|
||||
if (secretExist) {
|
||||
Logger.d('WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated.');
|
||||
Logger.d("WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated.");
|
||||
return self.updateRegistryAuthHeader(username, password, domain, nextVersion);
|
||||
}
|
||||
else {
|
||||
@@ -164,11 +187,12 @@ class DockerRegistry {
|
||||
.ensureSecret(secretName, JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
email: userEmailAddress || CaptainConstants.defaultEmail,
|
||||
serveraddress: domain
|
||||
email: userEmailAddress ||
|
||||
CaptainConstants.defaultEmail,
|
||||
serveraddress: domain,
|
||||
}))
|
||||
.then(function () {
|
||||
Logger.d('Updating EnvVars to update docker registry auth.');
|
||||
Logger.d("Updating EnvVars to update docker registry auth.");
|
||||
return self.dataStore.setRegistryAuthSecretVersion(nextVersion);
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,245 +0,0 @@
|
||||
const CaptainConstants = require('../utils/CaptainConstants');
|
||||
const Logger = require('../utils/Logger');
|
||||
const EnvVars = require('../utils/EnvVars');
|
||||
const fs = require('fs-extra');
|
||||
const uuid = require('uuid/v4');
|
||||
const ApiStatusCodes = require('../api/ApiStatusCodes');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
class DockerRegistry {
|
||||
|
||||
constructor(dockerApi, dataStore, certbotManager, loadBalancerManager, captainManager) {
|
||||
this.dockerApi = dockerApi;
|
||||
this.dataStore = dataStore;
|
||||
this.certbotManager = certbotManager;
|
||||
this.loadBalancerManager = loadBalancerManager;
|
||||
this.captainManager = captainManager;
|
||||
}
|
||||
|
||||
enableLocalDockerRegistry() {
|
||||
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
return self.dataStore.setHasLocalRegistry(true);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
enableRegistrySsl() {
|
||||
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
return self.dataStore.getHasRootSsl();
|
||||
})
|
||||
.then(function (rootHasSsl) {
|
||||
|
||||
if (!rootHasSsl) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, 'Root must have SSL before enabling ssl for docker registry.');
|
||||
}
|
||||
|
||||
return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain + '.' + self.dataStore.getRootDomain());
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return self.dataStore.setHasRegistrySsl(true);
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return self.loadBalancerManager.rePopulateNginxConfigFile(self.dataStore);
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return self.loadBalancerManager.sendReloadSignal();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getLocalRegistryDomainAndPort() {
|
||||
|
||||
const self = this;
|
||||
|
||||
return CaptainConstants.registrySubDomain + '.' +
|
||||
self.dataStore.getRootDomain() +
|
||||
':' + CaptainConstants.registrySubDomainPort;
|
||||
}
|
||||
|
||||
ensureDockerRegistryRunningOnThisNode() {
|
||||
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
|
||||
const myNodeId = this.captainManager.getMyNodeId();
|
||||
const captainSalt = this.captainManager.getCaptainSalt();
|
||||
|
||||
|
||||
function createRegistryServiceOnNode() {
|
||||
|
||||
return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [{
|
||||
protocol: 'tcp',
|
||||
containerPort: 5000,
|
||||
hostPort: CaptainConstants.registrySubDomainPort
|
||||
}], myNodeId, [{
|
||||
containerPath: '/cert-files',
|
||||
hostPath: CaptainConstants.letsEncryptEtcPath
|
||||
},
|
||||
{
|
||||
containerPath: '/var/lib/registry',
|
||||
hostPath: CaptainConstants.registryPathOnHost
|
||||
},
|
||||
{
|
||||
containerPath: '/etc/auth',
|
||||
hostPath: CaptainConstants.registryAuthPathOnHost
|
||||
}
|
||||
], [{
|
||||
key: 'REGISTRY_HTTP_TLS_CERTIFICATE',
|
||||
value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/fullchain.pem'
|
||||
}, {
|
||||
key: 'REGISTRY_HTTP_TLS_KEY',
|
||||
value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/privkey.pem'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH',
|
||||
value: 'htpasswd'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH_HTPASSWD_REALM',
|
||||
value: 'Registry Realm'
|
||||
}, {
|
||||
key: 'REGISTRY_AUTH_HTPASSWD_PATH',
|
||||
value: '/etc/auth'
|
||||
}]);
|
||||
|
||||
}
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
let authContent = CaptainConstants.captainRegistryUsername + ':' +
|
||||
bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5));
|
||||
|
||||
return fs.outputFile(CaptainConstants.registryAuthPathOnHost, authContent);
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
return dockerApi
|
||||
.isServiceRunningByName(CaptainConstants.registryServiceName);
|
||||
|
||||
})
|
||||
.then(function (isRunning) {
|
||||
|
||||
if (isRunning) {
|
||||
|
||||
Logger.d('Captain Registry is already running.. ');
|
||||
|
||||
return dockerApi
|
||||
.getNodeIdByServiceName(CaptainConstants.registryServiceName);
|
||||
|
||||
} else {
|
||||
|
||||
Logger.d('No Captain Registry service is running. Creating one...');
|
||||
|
||||
return createRegistryServiceOnNode(myNodeId)
|
||||
.then(function () {
|
||||
return myNodeId;
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
.then(function (nodeId) {
|
||||
|
||||
if (nodeId !== myNodeId) {
|
||||
|
||||
Logger.d('Captain Registry is running on a different node. Removing...');
|
||||
|
||||
return dockerApi
|
||||
.removeServiceByName(CaptainConstants.registryServiceName)
|
||||
.then(function () {
|
||||
|
||||
Logger.d('Creating Registry on this node...');
|
||||
|
||||
return createRegistryServiceOnNode(myNodeId)
|
||||
.then(function () {
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
updateRegistryAuthHeader(username, password, domain, currentVersion) {
|
||||
|
||||
const self = this;
|
||||
const dockerApi = this.dockerApi;
|
||||
|
||||
let nextVersion = null;
|
||||
|
||||
let secretName = null;
|
||||
|
||||
let userEmailAddress;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function () {
|
||||
|
||||
return self.dataStore.getUserEmailAddress();
|
||||
|
||||
})
|
||||
.then(function (emailAddress) {
|
||||
|
||||
userEmailAddress = emailAddress;
|
||||
|
||||
if (currentVersion) {
|
||||
return currentVersion
|
||||
}
|
||||
|
||||
return self.dataStore.getRegistryAuthSecretVersion();
|
||||
|
||||
})
|
||||
.then(function (versionSaved) {
|
||||
|
||||
nextVersion = versionSaved + 1;
|
||||
secretName = CaptainConstants.captainRegistryAuthHeaderSecretPrefix + nextVersion;
|
||||
|
||||
if (!username || !password || !domain) {
|
||||
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'user, pass and domain are all required');
|
||||
}
|
||||
|
||||
return dockerApi.checkIfSecretExist(secretName);
|
||||
|
||||
})
|
||||
.then(function (secretExist) {
|
||||
|
||||
if (secretExist) {
|
||||
Logger.d('WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated.');
|
||||
return self.updateRegistryAuthHeader(username, password, domain, nextVersion);
|
||||
} else {
|
||||
return dockerApi
|
||||
.ensureSecret(secretName, JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
email: userEmailAddress || CaptainConstants.defaultEmail,
|
||||
serveraddress: domain
|
||||
}))
|
||||
.then(function () {
|
||||
Logger.d('Updating EnvVars to update docker registry auth.');
|
||||
return self.dataStore.setRegistryAuthSecretVersion(nextVersion);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = DockerRegistry;
|
||||
@@ -0,0 +1,287 @@
|
||||
import CaptainConstants = require("../utils/CaptainConstants");
|
||||
import Logger = require("../utils/Logger");
|
||||
import EnvVars = require("../utils/EnvVars");
|
||||
import fs = require("fs-extra");
|
||||
import uuid = require("uuid/v4");
|
||||
import ApiStatusCodes = require("../api/ApiStatusCodes");
|
||||
import bcrypt = require("bcryptjs");
|
||||
import DockerApi = require("../docker/DockerApi");
|
||||
import DataStore = require("../datastore/DataStoreImpl");
|
||||
import CertbotManager = require("../user/CertbotManager");
|
||||
import LoadBalancerManager = require("../user/LoadBalancerManager");
|
||||
import CaptainManager = require("../user/CaptainManager");
|
||||
|
||||
class DockerRegistry {
|
||||
constructor(
|
||||
private dockerApi: DockerApi,
|
||||
private dataStore: DataStore,
|
||||
private certbotManager: CertbotManager,
|
||||
private loadBalancerManager: LoadBalancerManager,
|
||||
private captainManager: CaptainManager
|
||||
) {
|
||||
// this.dockerApi = dockerApi;
|
||||
// this.dataStore = dataStore;
|
||||
// this.certbotManager = certbotManager;
|
||||
// this.loadBalancerManager = loadBalancerManager;
|
||||
// this.captainManager = captainManager;
|
||||
}
|
||||
|
||||
enableLocalDockerRegistry() {
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve().then(function() {
|
||||
return self.dataStore.setHasLocalRegistry(true);
|
||||
});
|
||||
}
|
||||
|
||||
enableRegistrySsl() {
|
||||
const self = this;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function() {
|
||||
return self.dataStore.getHasRootSsl();
|
||||
})
|
||||
.then(function(rootHasSsl) {
|
||||
if (!rootHasSsl) {
|
||||
throw ApiStatusCodes.createError(
|
||||
ApiStatusCodes.ILLEGAL_OPERATION,
|
||||
"Root must have SSL before enabling ssl for docker registry."
|
||||
);
|
||||
}
|
||||
|
||||
return self.certbotManager.enableSsl(
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
self.dataStore.getRootDomain()
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
return self.dataStore.setHasRegistrySsl(true);
|
||||
})
|
||||
.then(function() {
|
||||
return self.loadBalancerManager.rePopulateNginxConfigFile(
|
||||
self.dataStore
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
return self.loadBalancerManager.sendReloadSignal();
|
||||
});
|
||||
}
|
||||
|
||||
getLocalRegistryDomainAndPort() {
|
||||
const self = this;
|
||||
|
||||
return (
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
self.dataStore.getRootDomain() +
|
||||
":" +
|
||||
CaptainConstants.registrySubDomainPort
|
||||
);
|
||||
}
|
||||
|
||||
ensureDockerRegistryRunningOnThisNode() {
|
||||
const dockerApi = this.dockerApi;
|
||||
const dataStore = this.dataStore;
|
||||
|
||||
const myNodeId = this.captainManager.getMyNodeId();
|
||||
const captainSalt = this.captainManager.getCaptainSalt();
|
||||
|
||||
function createRegistryServiceOnNode() {
|
||||
return dockerApi.createServiceOnNodeId(
|
||||
CaptainConstants.registryImageName,
|
||||
CaptainConstants.registryServiceName,
|
||||
[
|
||||
{
|
||||
protocol: "tcp",
|
||||
containerPort: 5000,
|
||||
hostPort: CaptainConstants.registrySubDomainPort,
|
||||
},
|
||||
],
|
||||
myNodeId,
|
||||
[
|
||||
{
|
||||
containerPath: "/cert-files",
|
||||
hostPath: CaptainConstants.letsEncryptEtcPath,
|
||||
},
|
||||
{
|
||||
containerPath: "/var/lib/registry",
|
||||
hostPath: CaptainConstants.registryPathOnHost,
|
||||
},
|
||||
{
|
||||
containerPath: "/etc/auth",
|
||||
hostPath: CaptainConstants.registryAuthPathOnHost,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
key: "REGISTRY_HTTP_TLS_CERTIFICATE",
|
||||
value:
|
||||
"/cert-files/live/" +
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
dataStore.getRootDomain() +
|
||||
"/fullchain.pem",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_HTTP_TLS_KEY",
|
||||
value:
|
||||
"/cert-files/live/" +
|
||||
CaptainConstants.registrySubDomain +
|
||||
"." +
|
||||
dataStore.getRootDomain() +
|
||||
"/privkey.pem",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH",
|
||||
value: "htpasswd",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH_HTPASSWD_REALM",
|
||||
value: "Registry Realm",
|
||||
},
|
||||
{
|
||||
key: "REGISTRY_AUTH_HTPASSWD_PATH",
|
||||
value: "/etc/auth",
|
||||
},
|
||||
]
|
||||
, undefined);
|
||||
}
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function() {
|
||||
const authContent =
|
||||
CaptainConstants.captainRegistryUsername +
|
||||
":" +
|
||||
bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5));
|
||||
|
||||
return fs.outputFile(
|
||||
CaptainConstants.registryAuthPathOnHost,
|
||||
authContent
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
return dockerApi.isServiceRunningByName(
|
||||
CaptainConstants.registryServiceName
|
||||
);
|
||||
})
|
||||
.then(function(isRunning) {
|
||||
if (isRunning) {
|
||||
Logger.d("Captain Registry is already running.. ");
|
||||
|
||||
return dockerApi.getNodeIdByServiceName(
|
||||
CaptainConstants.registryServiceName
|
||||
);
|
||||
} else {
|
||||
Logger.d(
|
||||
"No Captain Registry service is running. Creating one..."
|
||||
);
|
||||
|
||||
return createRegistryServiceOnNode().then(
|
||||
function() {
|
||||
return myNodeId;
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
.then(function(nodeId) {
|
||||
if (nodeId !== myNodeId) {
|
||||
Logger.d(
|
||||
"Captain Registry is running on a different node. Removing..."
|
||||
);
|
||||
|
||||
return dockerApi
|
||||
.removeServiceByName(
|
||||
CaptainConstants.registryServiceName
|
||||
)
|
||||
.then(function() {
|
||||
Logger.d("Creating Registry on this node...");
|
||||
|
||||
return createRegistryServiceOnNode().then(
|
||||
function() {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateRegistryAuthHeader(username: string, password: string, domain: string, currentVersion: number): Promise<any> {
|
||||
const self = this;
|
||||
const dockerApi = this.dockerApi;
|
||||
|
||||
let nextVersion: number|undefined = undefined;
|
||||
|
||||
let secretName: string|undefined = undefined;
|
||||
|
||||
let userEmailAddress: string|undefined = undefined;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(function() {
|
||||
return self.dataStore.getUserEmailAddress();
|
||||
})
|
||||
.then(function(emailAddress) {
|
||||
userEmailAddress = emailAddress;
|
||||
|
||||
if (currentVersion) {
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
return self.dataStore.getRegistryAuthSecretVersion();
|
||||
})
|
||||
.then(function(versionSaved) {
|
||||
nextVersion = versionSaved + 1;
|
||||
secretName =
|
||||
CaptainConstants.captainRegistryAuthHeaderSecretPrefix +
|
||||
nextVersion;
|
||||
|
||||
if (!username || !password || !domain) {
|
||||
throw ApiStatusCodes.createError(
|
||||
ApiStatusCodes.STATUS_ERROR_GENERIC,
|
||||
"user, pass and domain are all required"
|
||||
);
|
||||
}
|
||||
|
||||
return dockerApi.checkIfSecretExist(secretName);
|
||||
})
|
||||
.then(function(secretExist) {
|
||||
if (secretExist) {
|
||||
Logger.d(
|
||||
"WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated."
|
||||
);
|
||||
return self.updateRegistryAuthHeader(
|
||||
username,
|
||||
password,
|
||||
domain,
|
||||
nextVersion!
|
||||
);
|
||||
} else {
|
||||
return dockerApi
|
||||
.ensureSecret(
|
||||
secretName,
|
||||
JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
email:
|
||||
userEmailAddress ||
|
||||
CaptainConstants.defaultEmail,
|
||||
serveraddress: domain,
|
||||
})
|
||||
)
|
||||
.then(function() {
|
||||
Logger.d(
|
||||
"Updating EnvVars to update docker registry auth."
|
||||
);
|
||||
return self.dataStore.setRegistryAuthSecretVersion(
|
||||
nextVersion
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export = DockerRegistry;
|
||||
Reference in New Issue
Block a user