Feat/implement rest of poly effects (#2587)

* feat: Add the implementation of the rest of the polyfillEffects

* chore: Add in the rsync

* chore: Add in the changes needed to indicate that the service does not need config

* fix: Vaultwarden sets, starts, stops, uninstalls

* chore: Update the polyFilleffect and add two more

* Update MainLoop.ts

* chore: Add in the set config of the deps on the config set
This commit is contained in:
Jade
2024-04-04 09:09:59 -06:00
committed by GitHub
parent 3b9298ed2b
commit 6bc8027644
8 changed files with 272 additions and 81 deletions

View File

@@ -25,6 +25,7 @@ import {
anyOf,
deferred,
Parser,
array,
} from "ts-matches"
import { HostSystemStartOs } from "../../HostSystemStartOs"
import { JsonPath, unNestPath } from "../../../Models/JsonPath"
@@ -41,6 +42,48 @@ const MANIFEST_LOCATION = "/usr/lib/startos/package/embassyManifest.json"
const EMBASSY_JS_LOCATION = "/usr/lib/startos/package/embassy.js"
const EMBASSY_POINTER_PATH_PREFIX = "/embassyConfig"
const matchSetResult = object(
{
"depends-on": dictionary([string, array(string)]),
dependsOn: dictionary([string, array(string)]),
signal: literals(
"SIGTERM",
"SIGHUP",
"SIGINT",
"SIGQUIT",
"SIGILL",
"SIGTRAP",
"SIGABRT",
"SIGBUS",
"SIGFPE",
"SIGKILL",
"SIGUSR1",
"SIGSEGV",
"SIGUSR2",
"SIGPIPE",
"SIGALRM",
"SIGSTKFLT",
"SIGCHLD",
"SIGCONT",
"SIGSTOP",
"SIGTSTP",
"SIGTTIN",
"SIGTTOU",
"SIGURG",
"SIGXCPU",
"SIGXFSZ",
"SIGVTALRM",
"SIGPROF",
"SIGWINCH",
"SIGIO",
"SIGPWR",
"SIGSYS",
"SIGINFO",
),
},
["depends-on", "dependsOn"],
)
export type PackagePropertiesV2 = {
[name: string]: PackagePropertyObject | PackagePropertyString
}
@@ -120,6 +163,7 @@ const matchProperties = object({
data: matchPackageProperties,
})
const DEFAULT_REGISTRY = "https://registry.start9.com"
export class SystemForEmbassy implements System {
currentRunning: MainLoop | undefined
static async of(manifestLocation: string = MANIFEST_LOCATION) {
@@ -383,7 +427,7 @@ export class SystemForEmbassy implements System {
private async setConfig(
effects: HostSystemStartOs,
newConfigWithoutPointers: unknown,
): Promise<T.SetResult> {
): Promise<void> {
const newConfig = structuredClone(newConfigWithoutPointers)
await updateConfig(
effects,
@@ -391,45 +435,76 @@ export class SystemForEmbassy implements System {
newConfig,
)
const setConfigValue = this.manifest.config?.set
if (!setConfigValue) return { signal: "SIGTERM", "depends-on": {} }
if (!setConfigValue) return
if (setConfigValue.type === "docker") {
const container = await DockerProcedureContainer.of(
effects,
setConfigValue,
this.manifest.volumes,
)
return JSON.parse(
(
await container.exec([
setConfigValue.entrypoint,
...setConfigValue.args,
JSON.stringify(newConfig),
])
).stdout.toString(),
const answer = matchSetResult.unsafeCast(
JSON.parse(
(
await container.exec([
setConfigValue.entrypoint,
...setConfigValue.args,
JSON.stringify(newConfig),
])
).stdout.toString(),
),
)
const dependsOn = answer["depends-on"] ?? answer.dependsOn ?? {}
await this.setConfigSetConfig(effects, dependsOn)
return
} else if (setConfigValue.type === "script") {
const moduleCode = await this.moduleCode
const method = moduleCode.setConfig
if (!method) throw new Error("Expecting that the method setConfig exists")
return await method(
new PolyfillEffects(effects, this.manifest),
newConfig as U.Config,
).then((x): T.SetResult => {
if ("result" in x)
return {
"depends-on": x.result["depends-on"],
signal: x.result.signal === "SIGEMT" ? "SIGTERM" : x.result.signal,
}
if ("error" in x) throw new Error("Error getting config: " + x.error)
throw new Error("Error getting config: " + x["error-code"][1])
})
} else {
return {
"depends-on": {},
signal: "SIGTERM",
}
const answer = matchSetResult.unsafeCast(
await method(
new PolyfillEffects(effects, this.manifest),
newConfig as U.Config,
).then((x): T.SetResult => {
if ("result" in x)
return {
dependsOn: x.result["depends-on"],
signal:
x.result.signal === "SIGEMT" ? "SIGTERM" : x.result.signal,
}
if ("error" in x) throw new Error("Error getting config: " + x.error)
throw new Error("Error getting config: " + x["error-code"][1])
}),
)
const dependsOn = answer["depends-on"] ?? answer.dependsOn ?? {}
await this.setConfigSetConfig(effects, dependsOn)
return
}
}
private async setConfigSetConfig(
effects: HostSystemStartOs,
dependsOn: { [x: string]: readonly string[] },
) {
await effects.setDependencies({
dependencies: Object.entries(dependsOn).flatMap(([key, value]) => {
const dependency = this.manifest.dependencies?.[key]
if (!dependency) return []
const versionSpec = dependency.version
const registryUrl = DEFAULT_REGISTRY
const kind = "running"
return [
{
id: key,
versionSpec,
registryUrl,
kind,
healthChecks: [...value],
},
]
}),
})
}
private async migration(
effects: HostSystemStartOs,
fromVersion: string,