vscodeserver + minio

This commit is contained in:
Andras Bacsai
2022-10-18 14:34:10 +02:00
parent 12a1aeb0f8
commit f1ea01e709
5 changed files with 161 additions and 144 deletions

View File

@@ -1,4 +1,4 @@
import { decrypt, encrypt, generatePassword, prisma } from "./lib/common";
import { decrypt, encrypt, prisma } from "./lib/common";
import { includeServices } from "./lib/services/common";
@@ -10,36 +10,27 @@ export async function migrateServicesToNewTemplate() {
if (service.type === 'plausibleanalytics' && service.plausibleAnalytics) await plausibleAnalytics(service)
if (service.type === 'fider' && service.fider) await fider(service)
if (service.type === 'minio' && service.minio) await minio(service)
if (service.type === 'vscode' && service.vscodeserver) await vscodeserver(service)
}
} catch (error) {
console.log(error)
}
}
async function migrateSettings(settings: any[], service: any) {
for (const setting of settings) {
if (!setting) continue;
const [name, value] = setting.split('@@@')
console.log('Migrating setting', name, value)
await prisma.serviceSetting.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSetting.create({ data: { name, value, service: { connect: { id: service.id } } } })
}
}
async function migrateSecrets(secrets: any[], service: any) {
for (const secret of secrets) {
if (!secret) continue;
const [name, value] = secret.split('@@@')
console.log('Migrating secret', name, value)
await prisma.serviceSecret.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSecret.create({ data: { name, value, service: { connect: { id: service.id } } } })
}
}
async function createVolumes(volumes: any[], service: any) {
for (const volume of volumes) {
const [volumeName, path, containerId] = volume.split('@@@')
await prisma.servicePersistentStorage.findFirst({ where: { volumeName, serviceId: service.id } }) || await prisma.servicePersistentStorage.create({ data: { volumeName, path, containerId, predefined: true, service: { connect: { id: service.id } } } })
}
async function vscodeserver(service: any) {
const { password } = service.minio
const secrets = [
`PASSWORD@@@${password}`,
]
await migrateSecrets(secrets, service);
// Remove old service data
// await prisma.service.update({ where: { id: service.id }, data: { vscodeserver: { delete: true } } })
}
async function minio(service: any) {
const { rootUser, rootUserPassword, apiFqdn } = service.fider
const { rootUser, rootUserPassword, apiFqdn } = service.minio
const secrets = [
`MINIO_ROOT_PASSWORD@@@${rootUserPassword}`,
@@ -55,7 +46,6 @@ async function minio(service: any) {
// Remove old service data
// await prisma.service.update({ where: { id: service.id }, data: { minio: { delete: true } } })
}
async function fider(service: any) {
const { postgresqlUser, postgresqlPassword, postgresqlDatabase, jwtSecret, emailNoreply, emailMailgunApiKey, emailMailgunDomain, emailMailgunRegion, emailSmtpHost, emailSmtpPort, emailSmtpUser, emailSmtpPassword, emailSmtpEnableStartTls } = service.fider
@@ -83,7 +73,7 @@ async function fider(service: any) {
await migrateSecrets(secrets, service);
// Remove old service data
await prisma.service.update({ where: { id: service.id }, data: { fider: { delete: true } } })
// await prisma.service.update({ where: { id: service.id }, data: { fider: { delete: true } } })
}
async function plausibleAnalytics(service: any) {
@@ -114,5 +104,28 @@ async function plausibleAnalytics(service: any) {
await createVolumes(volumes, service);
// Remove old service data
await prisma.service.update({ where: { id: service.id }, data: { plausibleAnalytics: { delete: true } } })
// await prisma.service.update({ where: { id: service.id }, data: { plausibleAnalytics: { delete: true } } })
}
async function migrateSettings(settings: any[], service: any) {
for (const setting of settings) {
if (!setting) continue;
const [name, value] = setting.split('@@@')
console.log('Migrating setting', name, value)
await prisma.serviceSetting.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSetting.create({ data: { name, value, service: { connect: { id: service.id } } } })
}
}
async function migrateSecrets(secrets: any[], service: any) {
for (const secret of secrets) {
if (!secret) continue;
const [name, value] = secret.split('@@@')
console.log('Migrating secret', name, value)
await prisma.serviceSecret.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSecret.create({ data: { name, value, service: { connect: { id: service.id } } } })
}
}
async function createVolumes(volumes: any[], service: any) {
for (const volume of volumes) {
const [volumeName, path, containerId] = volume.split('@@@')
await prisma.servicePersistentStorage.findFirst({ where: { volumeName, serviceId: service.id } }) || await prisma.servicePersistentStorage.create({ data: { volumeName, path, containerId, predefined: true, service: { connect: { id: service.id } } } })
}
}

View File

@@ -1,4 +1,41 @@
export default [
{
"templateVersion": "1.0.0",
"serviceDefaultVersion": "4.7.1",
"name": "codeserver",
"displayName": "Code Server",
"description": "code-server by Coder is VS Code running on a remote server, accessible through the browser.",
"services": {
"$$id": {
"name": "Code Server",
"documentation": "Taken from https://github.com/coder/code-server/. ",
"depends_on": [],
"image": "codercom/code-server:$$core_version",
"volumes": [
"$$id-config-data:/home/coder/.local/share/code-server",
"$$id-vscodeserver-data:/home/coder",
"$$id-keys-directory:/root/.ssh",
"$$id-theme-and-plugin-directory:/root/.local/share/code-server"
],
"environment": [
"PASSWORD=$$secret_password",
],
"ports": [
"8080"
]
}
},
"variables": [
{
"id": "$$secret_password",
"name": "PASSWORD",
"label": "Password",
"defaultValue": "$$generate_password",
"description": ""
}
]
},
{
"templateVersion": "1.0.0",
"serviceDefaultVersion": "RELEASE.2022-10-15T19-57-03Z",
@@ -20,8 +57,7 @@ export default [
"MINIO_BROWSER_REDIRECT_URL=$$config_minio_browser_redirect_url",
"MINIO_DOMAIN=$$config_minio_domain",
"MINIO_ROOT_USER=$$config_minio_root_user",
"MINIO_ROOT_PASSWORD=$$secret_minio_root_user_password",
"MINIO_REGION_NAME=$$config_minio_region_name",
"MINIO_ROOT_PASSWORD=$$secret_minio_root_user_password"
],
"ports": [
"9001",
@@ -33,9 +69,12 @@ export default [
{
"id": "$$config_server_url",
"name": "MINIO_SERVER_URL",
"label": "Server URL",
"label": "Server/Console URL",
"defaultValue": "",
"description": "",
"extras": {
"required": true
}
},
{
"id": "$$config_browser_redirect_url",
@@ -64,14 +103,7 @@ export default [
"label": "Root User Password",
"defaultValue": "$$generate_password",
"description": "",
},
{
"id": "$$config_minio_region_name",
"name": "MINIO_REGION_NAME",
"label": "Region Name",
"defaultValue": "us-east-1",
"description": "",
},
}
]
},
{

View File

@@ -128,10 +128,10 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
const label = foundTemplate.variables.find(v => v.name === envKey)?.label
const description = foundTemplate.variables.find(v => v.name === envKey)?.description
const defaultValue = foundTemplate.variables.find(v => v.name === envKey)?.defaultValue
const isVisibleOnUI = foundTemplate.variables.find(v => v.name === envKey)?.extras?.isVisibleOnUI
if (envValue.startsWith('$$config') || isVisibleOnUI) {
const extras = foundTemplate.variables.find(v => v.name === envKey)?.extras
if (envValue.startsWith('$$config')) {
parsedTemplate[realKey].environment.push(
{ name: envKey, value: envValue, label, description, defaultValue }
{ name: envKey, value: envValue, label, description, defaultValue, extras }
)
}
@@ -155,6 +155,8 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
const { name, value } = setting
if (service.fqdn && value === '$$generate_fqdn') {
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, service.fqdn))
} else if (service.fqdn && value === '$$generate_domain') {
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, getDomain(service.fqdn)))
} else {
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, value))

View File

@@ -359,12 +359,12 @@ export async function traefikConfiguration(request, reply) {
let otherNakedDomain = null;
let otherIsHttps = null;
let otherIsWWW = null;
if (type === 'minio' && service.minio.apiFqdn) {
otherDomain = getDomain(service.minio.apiFqdn);
if (type === 'minio') {
const domain = service.serviceSetting.find((a) => a.name === 'MINIO_SERVER_URL')?.value
otherDomain = getDomain(domain);
otherNakedDomain = otherDomain.replace(/^www\./, '');
otherIsHttps = service.minio.apiFqdn.startsWith('https://');
otherIsWWW = service.minio.apiFqdn.includes('www.');
otherIsHttps = domain.startsWith('https://');
otherIsWWW = domain.includes('www.');
}
data.services.push({
id,
@@ -480,46 +480,42 @@ export async function traefikOtherConfiguration(request: FastifyRequest<TraefikO
} else if (type === 'http') {
const service = await prisma.service.findFirst({
where: { id },
include: { minio: true }
include: { serviceSetting: true }
});
if (service) {
if (service.type === 'minio') {
if (service?.minio?.apiFqdn) {
const {
minio: { apiFqdn }
} = service;
const domain = getDomain(apiFqdn);
const isHttps = apiFqdn.startsWith('https://');
traefik = {
[type]: {
routers: {
[id]: {
entrypoints: [type],
rule: `Host(\`${domain}\`)`,
service: id
}
},
services: {
[id]: {
loadbalancer: {
servers: [{ url: `http://${id}:${privatePort}` }]
}
const domainSetting = service.serviceSetting.find((a) => a.name === 'MINIO_SERVER_URL')?.value
const domain = getDomain(domainSetting);
const isHttps = domainSetting.startsWith('https://');
traefik = {
[type]: {
routers: {
[id]: {
entrypoints: [type],
rule: `Host(\`${domain}\`)`,
service: id
}
},
services: {
[id]: {
loadbalancer: {
servers: [{ url: `http://${id}:${privatePort}` }]
}
}
}
};
if (isHttps) {
if (isDev) {
traefik[type].routers[id].tls = {
domains: {
main: `${domain}`
}
};
} else {
traefik[type].routers[id].tls = {
certresolver: 'letsencrypt'
};
}
}
};
if (isHttps) {
if (isDev) {
traefik[type].routers[id].tls = {
domains: {
main: `${domain}`
}
};
} else {
traefik[type].routers[id].tls = {
certresolver: 'letsencrypt'
};
}
}
} else {
@@ -758,11 +754,18 @@ export async function remoteTraefikConfiguration(request: FastifyRequest<OnlyId>
let otherIsHttps = null;
let otherIsWWW = null;
if (type === 'minio' && service.minio.apiFqdn) {
otherDomain = getDomain(service.minio.apiFqdn);
// if (type === 'minio' && service.minio.apiFqdn) {
// otherDomain = getDomain(service.minio.apiFqdn);
// otherNakedDomain = otherDomain.replace(/^www\./, '');
// otherIsHttps = service.minio.apiFqdn.startsWith('https://');
// otherIsWWW = service.minio.apiFqdn.includes('www.');
// }
if (type === 'minio') {
const domain = service.serviceSetting.find((a) => a.name === 'MINIO_SERVER_URL')?.value
otherDomain = getDomain(domain);
otherNakedDomain = otherDomain.replace(/^www\./, '');
otherIsHttps = service.minio.apiFqdn.startsWith('https://');
otherIsWWW = service.minio.apiFqdn.includes('www.');
otherIsHttps = domain.startsWith('https://');
otherIsWWW = domain.includes('www.');
}
data.services.push({
id,