Bugfix/alpha.13 (#3053)

* bugfixes for alpha.13

* minor fixes

* version bump

* start-tunnel workflow

* sdk beta 44

* defaultFilter

* fix reset-password on tunnel auth

* explicitly rebuild types

* fix typo

* ubuntu-latest runner

* add cleanup steps

* fix env on attach
This commit is contained in:
Aiden McClelland
2025-11-19 22:48:49 -07:00
committed by GitHub
parent ad0632892e
commit e3e0b85e0c
36 changed files with 361 additions and 160 deletions

94
.github/workflows/start-tunnel.yaml vendored Normal file
View File

@@ -0,0 +1,94 @@
name: Debian-based ISO and SquashFS
on:
workflow_call:
workflow_dispatch:
inputs:
environment:
type: choice
description: Environment
options:
- NONE
- dev
- unstable
- dev-unstable
runner:
type: choice
description: Runner
options:
- standard
- fast
arch:
type: choice
description: Architecture
options:
- ALL
- x86_64
- aarch64
- riscv64
push:
branches:
- master
- next/*
pull_request:
branches:
- master
- next/*
env:
NODEJS_VERSION: "24.11.0"
ENVIRONMENT: '${{ fromJson(format(''["{0}", ""]'', github.event.inputs.environment || ''dev''))[github.event.inputs.environment == ''NONE''] }}'
jobs:
compile:
name: Compile Base Binaries
strategy:
fail-fast: true
matrix:
arch: >-
${{
fromJson('{
"x86_64": ["x86_64"],
"aarch64": ["aarch64"],
"riscv64": ["riscv64"],
"ALL": ["x86_64", "aarch64", "riscv64"]
}')[github.event.inputs.platform || 'ALL']
}}
runs-on: ${{ fromJson('["ubuntu-22.04", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps:
- run: |
sudo mount -t tmpfs tmpfs .
if: ${{ github.event.inputs.runner == 'fast' }}
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODEJS_VERSION }}
- name: Set up docker QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure sccache
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Make
run: make ARCH=${{ matrix.arch }} compiled-${{ matrix.arch }}.tar
env:
PLATFORM: ${{ matrix.arch }}
SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v4
with:
name: start-tunnel_${{ matrix.arch }}.deb
path: start-tunnel-*_${{ matrix.arch }}.deb

View File

@@ -67,8 +67,13 @@ jobs:
"ALL": ["x86_64", "aarch64"]
}')[github.event.inputs.platform || 'ALL']
}}
runs-on: ${{ fromJson('["ubuntu-22.04", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
runs-on: ${{ fromJson('["ubuntu-latest", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps:
- name: Cleaning up unnecessary files
run: |
sudo apt-get remove --purge -y google-chrome-stable firefox mono-devel
sudo apt-get autoremove -y
sudo apt-get clean
- run: |
sudo mount -t tmpfs tmpfs .
if: ${{ github.event.inputs.runner == 'fast' }}
@@ -134,7 +139,7 @@ jobs:
${{
fromJson(
format(
'["ubuntu-22.04", "{0}"]',
'["ubuntu-latest", "{0}"]',
fromJson('{
"x86_64": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204",
@@ -267,7 +272,7 @@ jobs:
index:
if: ${{ github.event.inputs.deploy != '' && github.event.inputs.deploy != 'NONE' }}
needs: [image]
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- run: >-
curl "https://${{

View File

@@ -40,7 +40,6 @@ STARTOS_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_
fi')
REGISTRY_TARGETS := core/target/$(RUST_ARCH)-unknown-linux-musl/$(PROFILE)/registrybox core/startos/start-registryd.service
TUNNEL_TARGETS := core/target/$(RUST_ARCH)-unknown-linux-musl/$(PROFILE)/tunnelbox core/startos/start-tunneld.service
REBUILD_TYPES = 1
ifeq ($(REMOTE),)
mkdir = mkdir -p $1
@@ -63,7 +62,7 @@ endif
.DELETE_ON_ERROR:
.PHONY: all metadata install clean format cli uis ui reflash deb $(IMAGE_TYPE) squashfs wormhole wormhole-deb test test-core test-sdk test-container-runtime registry install-registry tunnel install-tunnel
.PHONY: all metadata install clean format cli uis ui reflash deb $(IMAGE_TYPE) squashfs wormhole wormhole-deb test test-core test-sdk test-container-runtime registry install-registry tunnel install-tunnel ts-bindings
all: $(STARTOS_TARGETS)
@@ -277,10 +276,9 @@ container-runtime/node_modules/.package-lock.json: container-runtime/package-loc
npm --prefix container-runtime ci
touch container-runtime/node_modules/.package-lock.json
sdk/base/lib/osBindings/index.ts: $(shell if [ "$(REBUILD_TYPES)" -ne 0 ]; then echo core/startos/bindings/index.ts; fi)
ts-bindings: core/startos/bindings/index.ts
mkdir -p sdk/base/lib/osBindings
rsync -ac --delete core/startos/bindings/ sdk/base/lib/osBindings/
touch sdk/base/lib/osBindings/index.ts
core/startos/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
rm -rf core/startos/bindings

View File

@@ -25,5 +25,5 @@ apply_rule PREROUTING -p tcp -d $sip --dport $sport -j DNAT --to-destination $di
apply_rule OUTPUT -p tcp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
if [ "$UNDO" = 1 ]; then
conntrack -D -p tcp -d $sip --dport $sport
conntrack -D -p tcp -d $sip --dport $sport || true # conntrack returns exit 1 if no connections are active
fi

View File

@@ -38,7 +38,7 @@
},
"../sdk/dist": {
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.43",
"version": "0.4.0-beta.44",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^3.0.0",

View File

@@ -158,6 +158,8 @@ export class RpcListener {
this.unixSocketServer.listen(SOCKET_PATH)
console.log("Listening on %s", SOCKET_PATH)
this.unixSocketServer.on("connection", (s) => {
let id: IdType = null
const captureId = <X>(x: X) => {

2
core/Cargo.lock generated
View File

@@ -7908,7 +7908,7 @@ dependencies = [
[[package]]
name = "start-os"
version = "0.4.0-alpha.13"
version = "0.4.0-alpha.14"
dependencies = [
"aes 0.7.5",
"arti-client",

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -5,4 +5,4 @@ if tty -s; then
USE_TTY="-it"
fi
alias 'rust-zig-builder'='docker run '"$USE_TTY"' --rm -e "RUSTFLAGS=$RUSTFLAGS" -e "CFLAGS=-D_FORTIFY_SOURCE=2" -e "CXXFLAGS=-D_FORTIFY_SOURCE=2" -e SCCACHE_GHA_ENABLED -e SCCACHE_GHA_VERSION -e ACTIONS_RESULTS_URL -e ACTIONS_RUNTIME_TOKEN -v "$HOME/.cargo/registry":/usr/local/cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$HOME/.cache/sccache":/root/.cache/sccache -v "$(pwd)":/workdir -w /workdir -P start9/cargo-zigbuild'
alias 'rust-zig-builder'='docker run '"$USE_TTY"' --rm -e "RUSTFLAGS=$RUSTFLAGS" -e "AWS_LC_SYS_CMAKE_TOOLCHAIN_FILE_riscv64gc_unknown_linux_musl=/root/cmake-overrides/toolchain-riscv64-musl-clang.cmake" -e SCCACHE_GHA_ENABLED -e SCCACHE_GHA_VERSION -e ACTIONS_RESULTS_URL -e ACTIONS_RUNTIME_TOKEN -v "$HOME/.cargo/registry":/usr/local/cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$HOME/.cache/sccache":/root/.cache/sccache -v "$(pwd)":/workdir -w /workdir -P start9/cargo-zigbuild'

View File

@@ -12,7 +12,7 @@ if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..."
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi

View File

@@ -15,7 +15,7 @@ license = "MIT"
name = "start-os"
readme = "README.md"
repository = "https://github.com/Start9Labs/start-os"
version = "0.4.0-alpha.13" # VERSION_BUMP
version = "0.4.0-alpha.14" # VERSION_BUMP
[lib]
name = "startos"

View File

@@ -260,11 +260,7 @@ impl NetworkInterfaceInfo {
}
pub fn secure(&self) -> bool {
self.secure.unwrap_or_else(|| {
self.ip_info.as_ref().map_or(false, |ip_info| {
ip_info.device_type == Some(NetworkInterfaceType::Wireguard)
}) && !self.public()
})
self.secure.unwrap_or(false)
}
}

View File

@@ -366,6 +366,7 @@ impl LxcContainer {
}
tokio::time::sleep(Duration::from_millis(100)).await;
}
tracing::info!("Connected to socket in {:?}", started.elapsed());
Ok(UnixRpcClient::new(sock_path))
}
}

View File

@@ -649,16 +649,6 @@ async fn torctl(
.invoke(ErrorKind::Tor)
.await?;
let logs = journalctl(
LogSource::Unit(SYSTEMD_UNIT),
Some(0),
None,
Some("0"),
false,
true,
)
.await?;
let mut tcp_stream = None;
for _ in 0..60 {
if let Ok(conn) = TcpStream::connect(tor_control).await {
@@ -720,7 +710,7 @@ async fn torctl(
ErrorKind::Tor,
));
}
Ok((connection, logs))
Ok(connection)
};
let pre_handler = async {
while let Some(command) = recv.recv().await {
@@ -745,7 +735,7 @@ async fn torctl(
Ok(())
};
let (mut connection, mut logs) = tokio::select! {
let mut connection = tokio::select! {
res = bootstrap => res?,
res = pre_handler => return res,
};
@@ -851,6 +841,16 @@ async fn torctl(
Ok(())
};
let log_parser = async {
loop {
let mut logs = journalctl(
LogSource::Unit(SYSTEMD_UNIT),
Some(0),
None,
Some("0"),
false,
true,
)
.await?;
while let Some(log) = logs.try_next().await? {
for (regex, severity) in &*LOG_REGEXES {
if regex.is_match(&log.message) {
@@ -865,7 +865,11 @@ async fn torctl(
.and_then(|mut tor_socks| async move {
tokio::time::timeout(
Duration::from_secs(30),
socks5_impl::client::connect(&mut tor_socks, (addr, 80), None)
socks5_impl::client::connect(
&mut tor_socks,
(addr, 80),
None,
)
.map_err(|e| Error::new(e, ErrorKind::Tor)),
)
.map_err(|e| Error::new(e, ErrorKind::Tor))
@@ -889,8 +893,7 @@ async fn torctl(
}
}
}
// Err(Error::new(eyre!("Log stream terminated"), ErrorKind::Tor))
Ok(())
}
};
let health_checker = async {
let mut last_success = Instant::now();
@@ -960,7 +963,8 @@ impl TorControl {
_thread: tokio::spawn(async move {
let wipe_state = AtomicBool::new(false);
let mut health_timeout = Duration::from_secs(STARTING_HEALTH_TIMEOUT);
while let Err(e) = torctl(
loop {
if let Err(e) = torctl(
tor_control,
tor_socks,
&mut recv,
@@ -970,10 +974,12 @@ impl TorControl {
)
.await
{
tracing::error!("{e}: Restarting tor");
tracing::error!("TorControl : {e}");
tracing::debug!("{e:?}");
}
tracing::info!("TorControl is shut down.")
tracing::info!("Restarting Tor");
tokio::time::sleep(Duration::from_secs(1)).await;
}
})
.into(),
send,

View File

@@ -106,7 +106,9 @@ pub struct ExecParams {
#[arg(long)]
pty_size: Option<TermSize>,
#[arg(short, long)]
env: Option<PathBuf>,
env: Vec<String>,
#[arg(long)]
env_file: Option<PathBuf>,
#[arg(short, long)]
workdir: Option<PathBuf>,
#[arg(short, long)]
@@ -119,6 +121,7 @@ impl ExecParams {
fn exec(&self) -> Result<(), Error> {
let ExecParams {
env,
env_file,
workdir,
user,
chroot,
@@ -131,14 +134,15 @@ impl ExecParams {
ErrorKind::InvalidRequest,
));
};
let env_string = if let Some(env) = &env {
std::fs::read_to_string(env)
let env_string = if let Some(env_file) = &env_file {
std::fs::read_to_string(env_file)
.with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("read {env:?}")))?
} else {
Default::default()
};
let env = env_string
.lines()
.chain(env.iter().map(|l| l.as_str()))
.map(|l| l.trim())
.filter_map(|l| l.split_once("="))
.collect::<BTreeMap<_, _>>();
@@ -199,6 +203,7 @@ pub fn launch(
force_stderr_tty,
pty_size,
env,
env_file,
workdir,
user,
chroot,
@@ -294,8 +299,11 @@ pub fn launch(
let (pty, pts) = pty_process::open().with_kind(ErrorKind::Filesystem)?;
let mut cmd = pty_process::Command::new("/usr/bin/start-container");
cmd = cmd.arg("subcontainer").arg("launch-init");
if let Some(env) = env {
cmd = cmd.arg("--env").arg(env);
for env in env {
cmd = cmd.arg("-e").arg(env)
}
if let Some(env_file) = env_file {
cmd = cmd.arg("--env-file").arg(env_file);
}
if let Some(workdir) = workdir {
cmd = cmd.arg("--workdir").arg(workdir);
@@ -349,8 +357,11 @@ pub fn launch(
} else {
let mut cmd = StdCommand::new("/usr/bin/start-container");
cmd.arg("subcontainer").arg("launch-init");
if let Some(env) = env {
cmd.arg("--env").arg(env);
for env in env {
cmd.arg("-e").arg(env);
}
if let Some(env_file) = env_file {
cmd.arg("--env-file").arg(env_file);
}
if let Some(workdir) = workdir {
cmd.arg("--workdir").arg(workdir);
@@ -441,6 +452,7 @@ pub fn exec(
force_stderr_tty,
pty_size,
env,
env_file,
workdir,
user,
chroot,
@@ -544,8 +556,11 @@ pub fn exec(
let (pty, pts) = pty_process::open().with_kind(ErrorKind::Filesystem)?;
let mut cmd = pty_process::Command::new("/usr/bin/start-container");
cmd = cmd.arg("subcontainer").arg("exec-command");
if let Some(env) = env {
cmd = cmd.arg("--env").arg(env);
for env in env {
cmd = cmd.arg("-e").arg(env);
}
if let Some(env_file) = env_file {
cmd = cmd.arg("--env-file").arg(env_file);
}
if let Some(workdir) = workdir {
cmd = cmd.arg("--workdir").arg(workdir);
@@ -599,8 +614,11 @@ pub fn exec(
} else {
let mut cmd = StdCommand::new("/usr/bin/start-container");
cmd.arg("subcontainer").arg("exec-command");
if let Some(env) = env {
cmd.arg("--env").arg(env);
for env in env {
cmd.arg("-e").arg(env);
}
if let Some(env_file) = env_file {
cmd.arg("--env-file").arg(env_file);
}
if let Some(workdir) = workdir {
cmd.arg("--workdir").arg(workdir);

View File

@@ -885,7 +885,7 @@ pub async fn attach(
.arg("start-container")
.arg("subcontainer")
.arg("exec")
.arg("--env")
.arg("--env-file")
.arg(
Path::new("/media/startos/images")
.join(image_id)

View File

@@ -43,7 +43,7 @@ use crate::util::rpc_client::UnixRpcClient;
use crate::volume::data_dir;
use crate::{ARCH, DATA_DIR, PACKAGE_DATA};
const RPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
const RPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Debug)]
pub struct ServiceState {

View File

@@ -117,6 +117,8 @@ impl ServiceMap {
match Service::load(ctx, id, disposition).await {
Ok(s) => *service = s.into(),
Err(e) => {
tracing::error!("Error loading service: {e}");
tracing::debug!("{e:?}");
let e = ErrorData::from(e);
ctx.db
.mutate(|db| {

View File

@@ -3,7 +3,7 @@ use imbl::HashMap;
use imbl_value::InternedString;
use itertools::Itertools;
use patch_db::HasModel;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -113,27 +113,12 @@ impl AuthContext for TunnelContext {
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct SignerInfo {
pub name: InternedString,
}
pub fn auth_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
.subcommand(
"login",
from_fn_async(crate::auth::login_impl::<TunnelContext>)
.with_metadata("login", Value::Bool(true))
.no_cli(),
)
.subcommand(
"logout",
from_fn_async(crate::auth::logout::<TunnelContext>)
.with_metadata("get_session", Value::Bool(true))
.no_display()
.with_about("Log out of current auth session")
.with_call_remote::<CliContext>(),
)
crate::auth::auth::<C, TunnelContext>()
.subcommand("set-password", from_fn_async(set_password_rpc).no_cli())
.subcommand(
"set-password",
@@ -173,19 +158,15 @@ pub fn auth_api<C: Context>() -> ParentHandler<C> {
.with_display_serializable()
.with_custom_display_fn(|HandlerArgs { params, .. }, res| {
use prettytable::*;
if let Some(format) = params.format {
return display_serializable(format, res);
}
let mut table = Table::new();
table.add_row(row![bc => "NAME", "KEY"]);
for (key, info) in res {
table.add_row(row![info.name, key]);
}
table.print_tty(false)?;
Ok(())
})
.with_about("List authorized keys")
@@ -194,7 +175,7 @@ pub fn auth_api<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct AddKeyParams {
pub name: InternedString,
@@ -216,7 +197,7 @@ pub async fn add_key(
.result
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct RemoveKeyParams {
pub key: AnyVerifyingKey,
@@ -240,7 +221,7 @@ pub async fn list_keys(ctx: TunnelContext) -> Result<HashMap<AnyVerifyingKey, Si
ctx.db.peek().await.into_auth_pubkeys().de()
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct SetPasswordParams {
pub password: String,
}

View File

@@ -53,8 +53,9 @@ mod v0_4_0_alpha_10;
mod v0_4_0_alpha_11;
mod v0_4_0_alpha_12;
mod v0_4_0_alpha_13;
mod v0_4_0_alpha_14;
pub type Current = v0_4_0_alpha_13::Version; // VERSION_BUMP
pub type Current = v0_4_0_alpha_14::Version; // VERSION_BUMP
impl Current {
#[instrument(skip(self, db))]
@@ -169,7 +170,8 @@ enum Version {
V0_4_0_alpha_10(Wrapper<v0_4_0_alpha_10::Version>),
V0_4_0_alpha_11(Wrapper<v0_4_0_alpha_11::Version>),
V0_4_0_alpha_12(Wrapper<v0_4_0_alpha_12::Version>),
V0_4_0_alpha_13(Wrapper<v0_4_0_alpha_13::Version>), // VERSION_BUMP
V0_4_0_alpha_13(Wrapper<v0_4_0_alpha_13::Version>),
V0_4_0_alpha_14(Wrapper<v0_4_0_alpha_14::Version>), // VERSION_BUMP
Other(exver::Version),
}
@@ -225,7 +227,8 @@ impl Version {
Self::V0_4_0_alpha_10(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_11(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_12(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_13(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
Self::V0_4_0_alpha_13(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_14(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
Self::Other(v) => {
return Err(Error::new(
eyre!("unknown version {v}"),
@@ -273,7 +276,8 @@ impl Version {
Version::V0_4_0_alpha_10(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_11(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_12(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_13(Wrapper(x)) => x.semver(), // VERSION_BUMP
Version::V0_4_0_alpha_13(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_14(Wrapper(x)) => x.semver(), // VERSION_BUMP
Version::Other(x) => x.clone(),
}
}

View File

@@ -4,7 +4,7 @@ use exver::{PreReleaseSegment, VersionRange};
use imbl_value::InternedString;
use super::v0_3_5::V0_3_0_COMPAT;
use super::{VersionT, v0_4_0_alpha_11};
use super::{v0_4_0_alpha_11, VersionT};
use crate::net::tor::TorSecretKey;
use crate::prelude::*;
@@ -75,7 +75,10 @@ impl VersionT for Version {
}
fix_host(&mut db["public"]["serverInfo"]["network"]["host"])?;
db["private"]["keyStore"]["localCerts"] = db["private"]["keyStore"]["local_certs"].clone();
if db["private"]["keyStore"]["localCerts"].is_null() {
db["private"]["keyStore"]["localCerts"] =
db["private"]["keyStore"]["local_certs"].clone();
}
Ok(Value::Null)
}

View File

@@ -0,0 +1,37 @@
use exver::{PreReleaseSegment, VersionRange};
use super::v0_3_5::V0_3_0_COMPAT;
use super::{VersionT, v0_4_0_alpha_13};
use crate::prelude::*;
lazy_static::lazy_static! {
static ref V0_4_0_alpha_14: exver::Version = exver::Version::new(
[0, 4, 0],
[PreReleaseSegment::String("alpha".into()), 14.into()]
);
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Version;
impl VersionT for Version {
type Previous = v0_4_0_alpha_13::Version;
type PreUpRes = ();
async fn pre_up(self) -> Result<Self::PreUpRes, Error> {
Ok(())
}
fn semver(self) -> exver::Version {
V0_4_0_alpha_14.clone()
}
fn compat(self) -> &'static VersionRange {
&V0_3_0_COMPAT
}
#[instrument(skip_all)]
fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result<Value, Error> {
Ok(Value::Null)
}
fn down(self, _db: &mut Value) -> Result<(), Error> {
Ok(())
}
}

View File

@@ -1,3 +1,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AnyVerifyingKey } from "./AnyVerifyingKey"
import type { ContactInfo } from "./ContactInfo"
export type SignerInfo = { name: string }
export type SignerInfo = {
name: string
contact: Array<ContactInfo>
keys: Array<AnyVerifyingKey>
}

View File

@@ -3,7 +3,7 @@ import { knownProtocols } from "../interfaces/Host"
import { AddressInfo, Host, Hostname, HostnameInfo } from "../types"
import { Effects } from "../Effects"
import { DropGenerator, DropPromise } from "./Drop"
import { IPV6_LINK_LOCAL } from "./ip"
import { IpAddress, IPV6_LINK_LOCAL } from "./ip"
export type UrlString = string
export type HostId = string
@@ -17,7 +17,15 @@ export const getHostname = (url: string): Hostname | null => {
return last
}
type FilterKinds = "onion" | "local" | "domain" | "ip" | "ipv4" | "ipv6"
type FilterKinds =
| "onion"
| "local"
| "domain"
| "ip"
| "ipv4"
| "ipv6"
| "localhost"
| "link-local"
export type Filter = {
visibility?: "public" | "private"
kind?: FilterKinds | FilterKinds[]
@@ -72,6 +80,12 @@ type FilterReturnTy<F extends Filter> = F extends {
: Exclude<HostnameInfo, FilterReturnTy<E>>
: HostnameInfo
const defaultFilter = {
exclude: {
kind: ["localhost", "link-local"] as ("localhost" | "link-local")[],
},
}
type Formats = "hostname-info" | "urlstring" | "url"
type FormatReturnTy<
F extends Filter,
@@ -92,8 +106,11 @@ export type Filled = {
sslUrl: UrlString | null
}
filter: <F extends Filter, Format extends Formats = "urlstring">(
filter: F,
filter: <
F extends Filter = typeof defaultFilter,
Format extends Formats = "urlstring",
>(
filter?: F,
format?: Format,
) => FormatReturnTy<F, Format>[]
@@ -215,7 +232,13 @@ function filterRec(
h.kind === "ip" &&
h.hostname.kind === "domain") ||
(kind.has("ipv4") && h.kind === "ip" && h.hostname.kind === "ipv4") ||
(kind.has("ipv6") && h.kind === "ip" && h.hostname.kind === "ipv6")),
(kind.has("ipv6") && h.kind === "ip" && h.hostname.kind === "ipv6") ||
(kind.has("localhost") &&
["localhost", "127.0.0.1", "[::1]"].includes(h.hostname.value)) ||
(kind.has("link-local") &&
h.kind === "ip" &&
h.hostname.kind === "ipv6" &&
IPV6_LINK_LOCAL.contains(IpAddress.parse(h.hostname.value)))),
)
}
@@ -239,11 +262,14 @@ export const filledAddress = (
...addressInfo,
hostnames,
toUrls,
filter: <F extends Filter, Format extends Formats = "urlstring">(
filter: F,
filter: <
F extends Filter = typeof defaultFilter,
Format extends Formats = "urlstring",
>(
filter?: F,
format?: Format,
) => {
const filtered = filterRec(hostnames, filter, false)
const filtered = filterRec(hostnames, filter ?? defaultFilter, false)
let res: FormatReturnTy<F, Format>[] = filtered as any
if (format === "hostname-info") return res
const urls = filtered.flatMap(toUrlArray)

View File

@@ -61,7 +61,7 @@ import {
} from "../../base/lib/inits"
import { DropGenerator } from "../../base/lib/util/Drop"
export const OSVersion = testTypeVersion("0.4.0-alpha.13")
export const OSVersion = testTypeVersion("0.4.0-alpha.14")
// prettier-ignore
type AnyNeverCond<T extends any[], Then, Else> =

View File

@@ -410,12 +410,17 @@ export class SubContainerOwned<
workdir = options.cwd
delete options.cwd
}
if (options?.env) {
for (let [k, v] of Object.entries(options.env)) {
extra.push(`--env=${k}=${v}`)
}
}
const child = cp.spawn(
"start-container",
[
"subcontainer",
"exec",
`--env=/media/startos/images/${this.imageId}.env`,
`--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`,
`--workdir=${workdir}`,
...extra,
@@ -530,6 +535,11 @@ export class SubContainerOwned<
workdir = options.cwd
delete options.cwd
}
if (options?.env) {
for (let [k, v] of Object.entries(options.env)) {
extra.push(`--env=${k}=${v}`)
}
}
await this.killLeader()
this.leaderExited = false
this.leader = cp.spawn(
@@ -537,7 +547,7 @@ export class SubContainerOwned<
[
"subcontainer",
"launch",
`--env=/media/startos/images/${this.imageId}.env`,
`--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`,
`--workdir=${workdir}`,
...extra,
@@ -574,12 +584,17 @@ export class SubContainerOwned<
workdir = options.cwd
delete options.cwd
}
if (options?.env) {
for (let [k, v] of Object.entries(options.env)) {
extra.push(`--env=${k}=${v}`)
}
}
return cp.spawn(
"start-container",
[
"subcontainer",
"exec",
`--env=/media/startos/images/${this.imageId}.env`,
`--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`,
`--workdir=${workdir}`,
...extra,

View File

@@ -1,12 +1,12 @@
{
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.43",
"version": "0.4.0-beta.44",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.43",
"version": "0.4.0-beta.44",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^3.0.0",
@@ -98,6 +98,7 @@
"integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.0",
@@ -1643,6 +1644,7 @@
"integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.20.0"
}
@@ -1944,6 +1946,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001669",
"electron-to-chromium": "^1.5.41",
@@ -3053,6 +3056,7 @@
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -4157,6 +4161,7 @@
"integrity": "sha512-n7chtCbEoGYRwZZ0i/O3t1cPr6o+d9Xx4Zwy2LYfzv0vjchMBU0tO+qYYyvZloBPcgRgzYvALzGWHe609JjEpg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"commander": "^10.0.0",
"source-map-generator": "0.8.0"
@@ -4833,6 +4838,7 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -4953,6 +4959,7 @@
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

View File

@@ -1,6 +1,6 @@
{
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.43",
"version": "0.4.0-beta.44",
"description": "Software development kit to facilitate packaging services for StartOS",
"main": "./package/lib/index.js",
"types": "./package/lib/index.d.ts",

4
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "startos-ui",
"version": "0.4.0-alpha.13",
"version": "0.4.0-alpha.14",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "startos-ui",
"version": "0.4.0-alpha.13",
"version": "0.4.0-alpha.14",
"license": "MIT",
"dependencies": {
"@angular/animations": "^20.3.0",

View File

@@ -1,6 +1,6 @@
{
"name": "startos-ui",
"version": "0.4.0-alpha.13",
"version": "0.4.0-alpha.14",
"author": "Start9 Labs, Inc",
"homepage": "https://start9.com/",
"license": "MIT",

View File

@@ -110,7 +110,7 @@ export namespace Mock {
squashfs: {
aarch64: {
publishedAt: '2025-04-21T20:58:48.140749883Z',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.13/startos-0.4.0-alpha.13-33ae46f~dev_aarch64.squashfs',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64.squashfs',
commitment: {
hash: '4elBFVkd/r8hNadKmKtLIs42CoPltMvKe2z3LRqkphk=',
size: 1343500288,
@@ -122,7 +122,7 @@ export namespace Mock {
},
'aarch64-nonfree': {
publishedAt: '2025-04-21T21:07:00.249285116Z',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.13/startos-0.4.0-alpha.13-33ae46f~dev_aarch64-nonfree.squashfs',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64-nonfree.squashfs',
commitment: {
hash: 'MrCEi4jxbmPS7zAiGk/JSKlMsiuKqQy6RbYOxlGHOIQ=',
size: 1653075968,
@@ -134,7 +134,7 @@ export namespace Mock {
},
raspberrypi: {
publishedAt: '2025-04-21T21:16:12.933319237Z',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.13/startos-0.4.0-alpha.13-33ae46f~dev_raspberrypi.squashfs',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_raspberrypi.squashfs',
commitment: {
hash: '/XTVQRCqY3RK544PgitlKu7UplXjkmzWoXUh2E4HCw0=',
size: 1490731008,
@@ -146,7 +146,7 @@ export namespace Mock {
},
x86_64: {
publishedAt: '2025-04-21T21:14:20.246908903Z',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.13/startos-0.4.0-alpha.13-33ae46f~dev_x86_64.squashfs',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64.squashfs',
commitment: {
hash: '/6romKTVQGSaOU7FqSZdw0kFyd7P+NBSYNwM3q7Fe44=',
size: 1411657728,
@@ -158,7 +158,7 @@ export namespace Mock {
},
'x86_64-nonfree': {
publishedAt: '2025-04-21T21:15:17.955265284Z',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.13/startos-0.4.0-alpha.13-33ae46f~dev_x86_64-nonfree.squashfs',
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64-nonfree.squashfs',
commitment: {
hash: 'HCRq9sr/0t85pMdrEgNBeM4x11zVKHszGnD1GDyZbSE=',
size: 1731035136,
@@ -385,7 +385,7 @@ export namespace Mock {
docsUrl: 'https://bitcoin.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -420,7 +420,7 @@ export namespace Mock {
docsUrl: 'https://bitcoinknots.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -465,7 +465,7 @@ export namespace Mock {
docsUrl: 'https://bitcoin.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -500,7 +500,7 @@ export namespace Mock {
docsUrl: 'https://bitcoinknots.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -547,7 +547,7 @@ export namespace Mock {
docsUrl: 'https://lightning.engineering/',
releaseNotes: 'Upstream release to 0.17.5',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: LND_ICON,
sourceVersion: null,
@@ -595,7 +595,7 @@ export namespace Mock {
docsUrl: 'https://lightning.engineering/',
releaseNotes: 'Upstream release to 0.17.4',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: LND_ICON,
sourceVersion: null,
@@ -647,7 +647,7 @@ export namespace Mock {
docsUrl: 'https://bitcoin.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -682,7 +682,7 @@ export namespace Mock {
docsUrl: 'https://bitcoinknots.org',
releaseNotes: 'Even better support for Bitcoin and wallets!',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: BTC_ICON,
sourceVersion: null,
@@ -727,7 +727,7 @@ export namespace Mock {
docsUrl: 'https://lightning.engineering/',
releaseNotes: 'Upstream release and minor fixes.',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: LND_ICON,
sourceVersion: null,
@@ -775,7 +775,7 @@ export namespace Mock {
marketingSite: '',
releaseNotes: 'Upstream release and minor fixes.',
osVersion: '0.3.6',
sdkVersion: '0.4.0-beta.43',
sdkVersion: '0.4.0-beta.44',
gitHash: 'fakehash',
icon: PROXY_ICON,
sourceVersion: null,