From 20d3b5288c76342411b5d484b404941e8246b652 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Mon, 7 Apr 2025 13:55:38 -0600 Subject: [PATCH] sdk tweaks (#2858) * sdk tweaks * beta.20 * alpha.18 --- .../SystemForEmbassy/polyfillEffects.ts | 37 +++++++------------ core/Cargo.lock | 2 +- core/startos/Cargo.toml | 2 +- core/startos/src/version/mod.rs | 12 ++++-- core/startos/src/version/v0_3_6_alpha_18.rs | 36 ++++++++++++++++++ image-recipe/build.sh | 6 +-- sdk/base/lib/interfaces/Host.ts | 12 ------ sdk/package/lib/StartSdk.ts | 29 +++++++++++---- sdk/package/lib/inits/setupInit.ts | 10 +++++ sdk/package/lib/inits/setupInstall.ts | 18 +++++++-- sdk/package/lib/mainFn/Daemons.ts | 2 +- sdk/package/lib/util/SubContainer.ts | 22 +++++++++++ sdk/package/package-lock.json | 4 +- sdk/package/package.json | 2 +- web/package-lock.json | 4 +- web/package.json | 2 +- 16 files changed, 139 insertions(+), 61 deletions(-) create mode 100644 core/startos/src/version/v0_3_6_alpha_18.rs diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts index 0099bea92..88e9d7ae6 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts @@ -9,6 +9,7 @@ import { Manifest } from "./matchManifest" import { DockerProcedureContainer } from "./DockerProcedureContainer" import * as cp from "child_process" import { Effects } from "../../../Models/Effects" +import { Mounts } from "@start9labs/start-sdk/package/lib/mainFn/Mounts" export const execFile = promisify(cp.execFile) export const polyfillEffects = ( effects: Effects, @@ -111,7 +112,7 @@ export const polyfillEffects = ( effects, { imageId: manifest.main.image }, commands, - {}, + { mounts: Mounts.of() }, commands.join(" "), ) .then((x: any) => ({ @@ -168,17 +169,12 @@ export const polyfillEffects = ( { imageId: manifest.main.image }, commands, { - mounts: [ - { - mountpoint: "/drive", - options: { - type: "volume", - id: input.volumeId, - subpath: null, - readonly: false, - }, - }, - ], + mounts: Mounts.of().addVolume( + input.volumeId, + null, + "/drive", + false, + ), }, commands.join(" "), ) @@ -210,17 +206,12 @@ export const polyfillEffects = ( { imageId: manifest.main.image }, commands, { - mounts: [ - { - mountpoint: "/drive", - options: { - type: "volume", - id: input.volumeId, - subpath: null, - readonly: false, - }, - }, - ], + mounts: Mounts.of().addVolume( + input.volumeId, + null, + "/drive", + false, + ), }, commands.join(" "), ) diff --git a/core/Cargo.lock b/core/Cargo.lock index 7ec339ded..d7b4f3cf4 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -5952,7 +5952,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "start-os" -version = "0.3.6-alpha.17" +version = "0.3.6-alpha.18" dependencies = [ "aes 0.7.5", "async-acme", diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index e0bace2af..f6ae4b880 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.3.6-alpha.17" # VERSION_BUMP +version = "0.3.6-alpha.18" # VERSION_BUMP license = "MIT" [lib] diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index 087f64e2f..c9791b1d1 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -37,8 +37,9 @@ mod v0_3_6_alpha_14; mod v0_3_6_alpha_15; mod v0_3_6_alpha_16; mod v0_3_6_alpha_17; +mod v0_3_6_alpha_18; -pub type Current = v0_3_6_alpha_17::Version; // VERSION_BUMP +pub type Current = v0_3_6_alpha_18::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -140,7 +141,8 @@ enum Version { V0_3_6_alpha_14(Wrapper), V0_3_6_alpha_15(Wrapper), V0_3_6_alpha_16(Wrapper), - V0_3_6_alpha_17(Wrapper), // VERSION_BUMP + V0_3_6_alpha_17(Wrapper), + V0_3_6_alpha_18(Wrapper), // VERSION_BUMP Other(exver::Version), } @@ -181,7 +183,8 @@ impl Version { Self::V0_3_6_alpha_14(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_15(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_16(v) => DynVersion(Box::new(v.0)), - Self::V0_3_6_alpha_17(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP + Self::V0_3_6_alpha_17(v) => DynVersion(Box::new(v.0)), + Self::V0_3_6_alpha_18(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -214,7 +217,8 @@ impl Version { Version::V0_3_6_alpha_14(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_15(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_16(Wrapper(x)) => x.semver(), - Version::V0_3_6_alpha_17(Wrapper(x)) => x.semver(), // VERSION_BUMP + Version::V0_3_6_alpha_17(Wrapper(x)) => x.semver(), + Version::V0_3_6_alpha_18(Wrapper(x)) => x.semver(), // VERSION_BUMP Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_3_6_alpha_18.rs b/core/startos/src/version/v0_3_6_alpha_18.rs new file mode 100644 index 000000000..2d2c7ad32 --- /dev/null +++ b/core/startos/src/version/v0_3_6_alpha_18.rs @@ -0,0 +1,36 @@ +use exver::{PreReleaseSegment, VersionRange}; + +use super::v0_3_5::V0_3_0_COMPAT; +use super::{v0_3_6_alpha_17, VersionT}; +use crate::prelude::*; + +lazy_static::lazy_static! { + static ref V0_3_6_alpha_18: exver::Version = exver::Version::new( + [0, 3, 6], + [PreReleaseSegment::String("alpha".into()), 18.into()] + ); +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Version; + +impl VersionT for Version { + type Previous = v0_3_6_alpha_17::Version; + type PreUpRes = (); + + async fn pre_up(self) -> Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_3_6_alpha_18.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + Ok(()) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/image-recipe/build.sh b/image-recipe/build.sh index 8dc4a57d8..d5c820591 100755 --- a/image-recipe/build.sh +++ b/image-recipe/build.sh @@ -61,7 +61,7 @@ PLATFORM_CONFIG_EXTRAS=() if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then PLATFORM_CONFIG_EXTRAS+=( --firmware-binary false ) PLATFORM_CONFIG_EXTRAS+=( --firmware-chroot false ) - PLATFORM_CONFIG_EXTRAS+=( --linux-packages linux-image-6.6.51+rpt ) + PLATFORM_CONFIG_EXTRAS+=( --linux-packages linux-image-6.12.20+rpt ) PLATFORM_CONFIG_EXTRAS+=( --linux-flavours "rpi-v8 rpi-2712" ) elif [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then PLATFORM_CONFIG_EXTRAS+=( --linux-flavours rockchip64 ) @@ -206,8 +206,8 @@ if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then echo "Configuring raspi kernel '\$v'" extract-ikconfig "/usr/lib/modules/\$v/kernel/kernel/configs.ko.xz" > /boot/config-\$v done - mkinitramfs -c gzip -o /boot/initramfs8 6.6.74-v8+ - mkinitramfs -c gzip -o /boot/initramfs_2712 6.6.74-v8-16k+ + mkinitramfs -c gzip -o /boot/initramfs8 6.12.20-v8+ + mkinitramfs -c gzip -o /boot/initramfs_2712 6.12.20-v8-16k+ fi useradd --shell /bin/bash -G startos -m start9 diff --git a/sdk/base/lib/interfaces/Host.ts b/sdk/base/lib/interfaces/Host.ts index 53419357f..be9525f1c 100644 --- a/sdk/base/lib/interfaces/Host.ts +++ b/sdk/base/lib/interfaces/Host.ts @@ -33,18 +33,6 @@ export const knownProtocols = { secure: { ssl: false }, defaultPort: 22, }, - bitcoin: { - secure: { ssl: false }, - defaultPort: 8333, - }, - lightning: { - secure: { ssl: true }, - defaultPort: 9735, - }, - grpc: { - secure: { ssl: true }, - defaultPort: 50051, - }, dns: { secure: { ssl: false }, defaultPort: 53, diff --git a/sdk/package/lib/StartSdk.ts b/sdk/package/lib/StartSdk.ts index 799adcb3c..3da6732e5 100644 --- a/sdk/package/lib/StartSdk.ts +++ b/sdk/package/lib/StartSdk.ts @@ -47,7 +47,12 @@ import { GetSystemSmtp } from "./util" import { nullIfEmpty } from "./util" import { getServiceInterface, getServiceInterfaces } from "./util" import { getStore } from "./store/getStore" -import { CommandOptions, MountOptions, SubContainer } from "./util/SubContainer" +import { + CommandOptions, + ExitError, + MountOptions, + SubContainer, +} from "./util/SubContainer" import { splitCommand } from "./util" import { Mounts } from "./mainFn/Mounts" import { setupDependencies } from "../../base/lib/dependencies/setupDependencies" @@ -72,7 +77,7 @@ import * as actions from "../../base/lib/actions" import { setupInit } from "./inits/setupInit" import * as fs from "node:fs/promises" -export const OSVersion = testTypeVersion("0.3.6-alpha.17") +export const OSVersion = testTypeVersion("0.3.6-alpha.18") // prettier-ignore type AnyNeverCond = @@ -286,7 +291,7 @@ export class StartSdk { }, command: T.CommandType, options: CommandOptions & { - mounts?: { mountpoint: string; options: MountOptions }[] + mounts: Mounts }, /** * A name to use to refer to the ephemeral subcontainer for debugging purposes @@ -583,7 +588,10 @@ export class StartSdk { }) * ``` */ - setupInstall: (fn: InstallFn) => Install.of(fn), + setupInstall: ( + fn: InstallFn, + preFn?: InstallFn, + ) => Install.of(fn, preFn), /** * @description Use this function to determine how this service will be hosted and served. The function executes on service install, service update, and inputSpec save. * @@ -1132,7 +1140,7 @@ export async function runCommand( image: { imageId: keyof Manifest["images"] & T.ImageId; sharedRun?: boolean }, command: T.CommandType, options: CommandOptions & { - mounts?: { mountpoint: string; options: MountOptions }[] + mounts: Mounts }, name?: string, ): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> { @@ -1150,7 +1158,7 @@ export async function runCommand( return SubContainer.with( effects, image, - options.mounts || [], + options.mounts.build(), name || commands .map((c) => { @@ -1161,6 +1169,13 @@ export async function runCommand( } }) .join(" "), - (subcontainer) => subcontainer.exec(commands), + async (subcontainer) => { + const res = await subcontainer.exec(commands) + if (res.exitCode || res.exitSignal) { + throw new ExitError(commands[0], res) + } else { + return res + } + }, ) } diff --git a/sdk/package/lib/inits/setupInit.ts b/sdk/package/lib/inits/setupInit.ts index 8d30f5b1f..21cfd1641 100644 --- a/sdk/package/lib/inits/setupInit.ts +++ b/sdk/package/lib/inits/setupInit.ts @@ -3,6 +3,7 @@ import { ExtendedVersion } from "../../../base/lib/exver" import { UpdateServiceInterfaces } from "../../../base/lib/interfaces/setupInterfaces" import { ExposedStorePaths } from "../../../base/lib/types" import * as T from "../../../base/lib/types" +import { StorePath } from "../util" import { VersionGraph } from "../version/VersionGraph" import { Install } from "./setupInstall" import { Uninstall } from "./setupUninstall" @@ -16,6 +17,7 @@ export function setupInit( effects: T.Effects }) => Promise, actions: Actions, + initStore: Store, exposedStore: ExposedStorePaths, ): { packageInit: T.ExpectedExports.packageInit @@ -53,6 +55,14 @@ export function setupInit( } }, containerInit: async (opts) => { + const prev = await opts.effects.getDataVersion() + if (!prev) { + await opts.effects.store.set({ + path: "" as StorePath, + value: initStore, + }) + await install.preInstall(opts) + } await setServiceInterfaces({ ...opts, }) diff --git a/sdk/package/lib/inits/setupInstall.ts b/sdk/package/lib/inits/setupInstall.ts index 38a96a00b..708367e20 100644 --- a/sdk/package/lib/inits/setupInstall.ts +++ b/sdk/package/lib/inits/setupInstall.ts @@ -4,11 +4,15 @@ export type InstallFn = (opts: { effects: T.Effects }) => Promise export class Install { - private constructor(readonly fn: InstallFn) {} + private constructor( + readonly fn: InstallFn, + readonly preFn?: InstallFn, + ) {} static of( fn: InstallFn, + preFn?: InstallFn, ) { - return new Install(fn) + return new Install(fn, preFn) } async install({ effects }: Parameters[0]) { @@ -16,10 +20,18 @@ export class Install { effects, }) } + + async preInstall({ effects }: Parameters[0]) { + this.preFn && + (await this.preFn({ + effects, + })) + } } export function setupInstall( fn: InstallFn, + preFn?: InstallFn, ) { - return Install.of(fn) + return Install.of(fn, preFn) } diff --git a/sdk/package/lib/mainFn/Daemons.ts b/sdk/package/lib/mainFn/Daemons.ts index d471394c7..9732d6e7a 100644 --- a/sdk/package/lib/mainFn/Daemons.ts +++ b/sdk/package/lib/mainFn/Daemons.ts @@ -172,7 +172,7 @@ export class Daemons daemon, daemonIndex, options.requires - .map((x) => this.ids.indexOf(id as any)) + .map((x) => this.ids.indexOf(x)) .filter((x) => x >= 0) .map((id) => this.healthDaemons[id]), id, diff --git a/sdk/package/lib/util/SubContainer.ts b/sdk/package/lib/util/SubContainer.ts index 912c3112a..13d91535e 100644 --- a/sdk/package/lib/util/SubContainer.ts +++ b/sdk/package/lib/util/SubContainer.ts @@ -467,3 +467,25 @@ export type MountOptionsBackup = { function wait(time: number) { return new Promise((resolve) => setTimeout(resolve, time)) } + +export class ExitError extends Error { + constructor( + readonly command: string, + readonly result: { + exitCode: number | null + exitSignal: T.Signals | null + stdout: string | Buffer + stderr: string | Buffer + }, + ) { + let message: string + if (result.exitCode) { + message = `${command} failed with exit code ${result.exitCode}: ${result.stderr}` + } else if (result.exitSignal) { + message = `${command} terminated with signal ${result.exitSignal}: ${result.stderr}` + } else { + message = `${command} succeeded: ${result.stdout}` + } + super(message) + } +} diff --git a/sdk/package/package-lock.json b/sdk/package/package-lock.json index e6eee8cac..4641278c2 100644 --- a/sdk/package/package-lock.json +++ b/sdk/package/package-lock.json @@ -1,12 +1,12 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.19", + "version": "0.3.6-beta.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.19", + "version": "0.3.6-beta.20", "license": "MIT", "dependencies": { "@iarna/toml": "^2.2.5", diff --git a/sdk/package/package.json b/sdk/package/package.json index 69d2c1f97..55a3d29d7 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -1,6 +1,6 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.19", + "version": "0.3.6-beta.20", "description": "Software development kit to facilitate packaging services for StartOS", "main": "./package/lib/index.js", "types": "./package/lib/index.d.ts", diff --git a/web/package-lock.json b/web/package-lock.json index b7eb9b040..a53fcb035 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.17", + "version": "0.3.6-alpha.18", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.3.6-alpha.17", + "version": "0.3.6-alpha.18", "license": "MIT", "dependencies": { "@angular/animations": "^14.1.0", diff --git a/web/package.json b/web/package.json index 622124743..3f617db14 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.17", + "version": "0.3.6-alpha.18", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT",