mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
More svc effect handlers (#2610)
* complete get_primary_url fn * complete clear_network_interfaces fn * formatting * complete remove_address fn * get_system_smtp wip * complete get_system_smtp and set_system_smtp * add SetSystemSmtpParams struct * add set_system_smtp subcommand * Remove 'Copy' implementation from `HostAddress` Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> * Refactor `get_host_primary` fn and clone resulting `HostAddress` Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> * misc fixes and debug info * seed hosts with a tor address --------- Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
@@ -28,7 +28,7 @@ import { DependencyConfig, Update } from "./dependencies/DependencyConfig"
|
||||
import { BackupSet, Backups } from "./backup/Backups"
|
||||
import { smtpConfig } from "./config/configConstants"
|
||||
import { Daemons } from "./mainFn/Daemons"
|
||||
import { healthCheck } from "./health/HealthCheck"
|
||||
import { healthCheck, HealthCheckParams } from "./health/HealthCheck"
|
||||
import { checkPortListening } from "./health/checkFns/checkPortListening"
|
||||
import { checkWebUrl, runHealthScript } from "./health/checkFns"
|
||||
import { List } from "./config/builder/list"
|
||||
@@ -78,6 +78,7 @@ import { Checker, EmVer } from "./emverLite/mod"
|
||||
import { ExposedStorePaths } from "./store/setupExposeStore"
|
||||
import { PathBuilder, extractJsonPath, pathBuilder } from "./store/PathBuilder"
|
||||
import { checkAllDependencies } from "./dependencies/dependencies"
|
||||
import { health } from "."
|
||||
|
||||
// prettier-ignore
|
||||
type AnyNeverCond<T extends any[], Then, Else> =
|
||||
@@ -186,13 +187,13 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
||||
nullIfEmpty,
|
||||
runCommand: async <A extends string>(
|
||||
effects: Effects,
|
||||
imageId: Manifest["images"][number],
|
||||
image: { id: Manifest["images"][number]; sharedRun?: boolean },
|
||||
command: ValidIfNoStupidEscape<A> | [string, ...string[]],
|
||||
options: CommandOptions & {
|
||||
mounts?: { path: string; options: MountOptions }[]
|
||||
},
|
||||
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> => {
|
||||
return runCommand<Manifest>(effects, imageId, command, options)
|
||||
return runCommand<Manifest>(effects, image, command, options)
|
||||
},
|
||||
|
||||
createAction: <
|
||||
@@ -264,7 +265,9 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
||||
)
|
||||
},
|
||||
HealthCheck: {
|
||||
of: healthCheck,
|
||||
of(o: HealthCheckParams<Manifest>) {
|
||||
return healthCheck<Manifest>(o)
|
||||
},
|
||||
},
|
||||
Dependency: {
|
||||
of(data: Dependency["data"]) {
|
||||
@@ -740,14 +743,14 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
||||
|
||||
export async function runCommand<Manifest extends SDKManifest>(
|
||||
effects: Effects,
|
||||
imageId: Manifest["images"][number],
|
||||
image: { id: Manifest["images"][number]; sharedRun?: boolean },
|
||||
command: string | [string, ...string[]],
|
||||
options: CommandOptions & {
|
||||
mounts?: { path: string; options: MountOptions }[]
|
||||
},
|
||||
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> {
|
||||
const commands = splitCommand(command)
|
||||
const overlay = await Overlay.of(effects, imageId)
|
||||
const overlay = await Overlay.of(effects, image)
|
||||
try {
|
||||
for (let mount of options.mounts || []) {
|
||||
await overlay.mount(mount.options, mount.path)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { InterfaceReceipt } from "../interfaces/interfaceReceipt"
|
||||
import { Daemon, Effects } from "../types"
|
||||
import { Daemon, Effects, SDKManifest } from "../types"
|
||||
import { CheckResult } from "./checkFns/CheckResult"
|
||||
import { HealthReceipt } from "./HealthReceipt"
|
||||
import { Trigger } from "../trigger"
|
||||
@@ -9,16 +9,23 @@ import { once } from "../util/once"
|
||||
import { Overlay } from "../util/Overlay"
|
||||
import { object, unknown } from "ts-matches"
|
||||
|
||||
export function healthCheck(o: {
|
||||
export type HealthCheckParams<Manifest extends SDKManifest> = {
|
||||
effects: Effects
|
||||
name: string
|
||||
imageId: string
|
||||
image: {
|
||||
id: Manifest["images"][number]
|
||||
sharedRun?: boolean
|
||||
}
|
||||
trigger?: Trigger
|
||||
fn(overlay: Overlay): Promise<CheckResult> | CheckResult
|
||||
onFirstSuccess?: () => unknown | Promise<unknown>
|
||||
}) {
|
||||
}
|
||||
|
||||
export function healthCheck<Manifest extends SDKManifest>(
|
||||
o: HealthCheckParams<Manifest>,
|
||||
) {
|
||||
new Promise(async () => {
|
||||
const overlay = await Overlay.of(o.effects, o.imageId)
|
||||
const overlay = await Overlay.of(o.effects, o.image)
|
||||
try {
|
||||
let currentValue: TriggerInput = {
|
||||
hadSuccess: false,
|
||||
|
||||
@@ -23,7 +23,7 @@ type Daemon<
|
||||
> = {
|
||||
id: "" extends Id ? never : Id
|
||||
command: ValidIfNoStupidEscape<Command> | [string, ...string[]]
|
||||
imageId: Manifest["images"][number]
|
||||
image: { id: Manifest["images"][number]; sharedRun?: boolean }
|
||||
mounts: Mounts<Manifest>
|
||||
env?: Record<string, string>
|
||||
ready: {
|
||||
@@ -40,7 +40,7 @@ export const runDaemon =
|
||||
<Manifest extends SDKManifest>() =>
|
||||
async <A extends string>(
|
||||
effects: Effects,
|
||||
imageId: Manifest["images"][number],
|
||||
image: { id: Manifest["images"][number]; sharedRun?: boolean },
|
||||
command: ValidIfNoStupidEscape<A> | [string, ...string[]],
|
||||
options: CommandOptions & {
|
||||
mounts?: { path: string; options: MountOptions }[]
|
||||
@@ -48,7 +48,7 @@ export const runDaemon =
|
||||
},
|
||||
): Promise<DaemonReturned> => {
|
||||
const commands = splitCommand(command)
|
||||
const overlay = options.overlay || (await Overlay.of(effects, imageId))
|
||||
const overlay = options.overlay || (await Overlay.of(effects, image))
|
||||
for (let mount of options.mounts || []) {
|
||||
await overlay.mount(mount.options, mount.path)
|
||||
}
|
||||
@@ -183,9 +183,9 @@ export class Daemons<Manifest extends SDKManifest, Ids extends string> {
|
||||
daemon.requires?.map((id) => daemonsStarted[id]) ?? [],
|
||||
)
|
||||
daemonsStarted[daemon.id] = requiredPromise.then(async () => {
|
||||
const { command, imageId } = daemon
|
||||
const { command, image } = daemon
|
||||
|
||||
const child = runDaemon<Manifest>()(effects, imageId, command, {
|
||||
const child = runDaemon<Manifest>()(effects, image, command, {
|
||||
env: daemon.env,
|
||||
mounts: daemon.mounts.build(),
|
||||
})
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { Callback } from "./Callback"
|
||||
import type { HostId } from "./HostId"
|
||||
|
||||
export type GetPrimaryUrlParams = {
|
||||
packageId: string | null
|
||||
serviceInterfaceId: string
|
||||
callback: Callback
|
||||
hostId: HostId
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ServiceInterfaceId } from "./ServiceInterfaceId"
|
||||
|
||||
export type RemoveAddressParams = { id: string }
|
||||
export type RemoveAddressParams = { id: ServiceInterfaceId }
|
||||
|
||||
@@ -28,4 +28,5 @@ export type ServerInfo = {
|
||||
ntpSynced: boolean
|
||||
zram: boolean
|
||||
governor: Governor | null
|
||||
smtp: string | null
|
||||
}
|
||||
|
||||
3
sdk/lib/osBindings/SetSystemSmtpParams.ts
Normal file
3
sdk/lib/osBindings/SetSystemSmtpParams.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type SetSystemSmtpParams = { smtp: string }
|
||||
@@ -113,6 +113,7 @@ export { SetDependenciesParams } from "./SetDependenciesParams"
|
||||
export { SetHealth } from "./SetHealth"
|
||||
export { SetMainStatus } from "./SetMainStatus"
|
||||
export { SetStoreParams } from "./SetStoreParams"
|
||||
export { SetSystemSmtpParams } from "./SetSystemSmtpParams"
|
||||
export { SignAssetParams } from "./SignAssetParams"
|
||||
export { SignatureInfo } from "./SignatureInfo"
|
||||
export { Signature } from "./Signature"
|
||||
|
||||
@@ -12,10 +12,19 @@ export class Overlay {
|
||||
readonly rootfs: string,
|
||||
readonly guid: string,
|
||||
) {}
|
||||
static async of(effects: T.Effects, imageId: string) {
|
||||
static async of(
|
||||
effects: T.Effects,
|
||||
image: { id: string; sharedRun?: boolean },
|
||||
) {
|
||||
const { id: imageId, sharedRun } = image
|
||||
const [rootfs, guid] = await effects.createOverlayedImage({ imageId })
|
||||
|
||||
for (const dirPart of ["dev", "sys", "proc", "run"] as const) {
|
||||
const shared = ["dev", "sys", "proc"]
|
||||
if (!!sharedRun) {
|
||||
shared.push("run")
|
||||
}
|
||||
|
||||
for (const dirPart of shared) {
|
||||
await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true })
|
||||
await execFile("mount", [
|
||||
"--rbind",
|
||||
|
||||
Reference in New Issue
Block a user