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"] "ALL": ["x86_64", "aarch64"]
}')[github.event.inputs.platform || 'ALL'] }')[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: 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: | - run: |
sudo mount -t tmpfs tmpfs . sudo mount -t tmpfs tmpfs .
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
@@ -134,7 +139,7 @@ jobs:
${{ ${{
fromJson( fromJson(
format( format(
'["ubuntu-22.04", "{0}"]', '["ubuntu-latest", "{0}"]',
fromJson('{ fromJson('{
"x86_64": "buildjet-8vcpu-ubuntu-2204", "x86_64": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204", "x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204",
@@ -267,7 +272,7 @@ jobs:
index: index:
if: ${{ github.event.inputs.deploy != '' && github.event.inputs.deploy != 'NONE' }} if: ${{ github.event.inputs.deploy != '' && github.event.inputs.deploy != 'NONE' }}
needs: [image] needs: [image]
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- run: >- - run: >-
curl "https://${{ curl "https://${{

View File

@@ -40,7 +40,6 @@ STARTOS_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_
fi') fi')
REGISTRY_TARGETS := core/target/$(RUST_ARCH)-unknown-linux-musl/$(PROFILE)/registrybox core/startos/start-registryd.service 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 TUNNEL_TARGETS := core/target/$(RUST_ARCH)-unknown-linux-musl/$(PROFILE)/tunnelbox core/startos/start-tunneld.service
REBUILD_TYPES = 1
ifeq ($(REMOTE),) ifeq ($(REMOTE),)
mkdir = mkdir -p $1 mkdir = mkdir -p $1
@@ -63,7 +62,7 @@ endif
.DELETE_ON_ERROR: .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) all: $(STARTOS_TARGETS)
@@ -277,10 +276,9 @@ container-runtime/node_modules/.package-lock.json: container-runtime/package-loc
npm --prefix container-runtime ci npm --prefix container-runtime ci
touch container-runtime/node_modules/.package-lock.json 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 mkdir -p sdk/base/lib/osBindings
rsync -ac --delete core/startos/bindings/ 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) core/startos/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
rm -rf core/startos/bindings 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 apply_rule OUTPUT -p tcp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
if [ "$UNDO" = 1 ]; then 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 fi

View File

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

View File

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

2
core/Cargo.lock generated
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,4 +5,4 @@ if tty -s; then
USE_TTY="-it" USE_TTY="-it"
fi 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" BUILD_FLAGS="--release"
else else
if [ "$PROFILE" != "debug"]; then if [ "$PROFILE" != "debug"]; then
>&2 echo "Unknonw profile $PROFILE: falling back to debug..." >&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug PROFILE=debug
fi fi
fi fi

View File

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

View File

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

View File

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

View File

@@ -649,16 +649,6 @@ async fn torctl(
.invoke(ErrorKind::Tor) .invoke(ErrorKind::Tor)
.await?; .await?;
let logs = journalctl(
LogSource::Unit(SYSTEMD_UNIT),
Some(0),
None,
Some("0"),
false,
true,
)
.await?;
let mut tcp_stream = None; let mut tcp_stream = None;
for _ in 0..60 { for _ in 0..60 {
if let Ok(conn) = TcpStream::connect(tor_control).await { if let Ok(conn) = TcpStream::connect(tor_control).await {
@@ -720,7 +710,7 @@ async fn torctl(
ErrorKind::Tor, ErrorKind::Tor,
)); ));
} }
Ok((connection, logs)) Ok(connection)
}; };
let pre_handler = async { let pre_handler = async {
while let Some(command) = recv.recv().await { while let Some(command) = recv.recv().await {
@@ -745,7 +735,7 @@ async fn torctl(
Ok(()) Ok(())
}; };
let (mut connection, mut logs) = tokio::select! { let mut connection = tokio::select! {
res = bootstrap => res?, res = bootstrap => res?,
res = pre_handler => return res, res = pre_handler => return res,
}; };
@@ -851,46 +841,59 @@ async fn torctl(
Ok(()) Ok(())
}; };
let log_parser = async { let log_parser = async {
while let Some(log) = logs.try_next().await? { loop {
for (regex, severity) in &*LOG_REGEXES { let mut logs = journalctl(
if regex.is_match(&log.message) { LogSource::Unit(SYSTEMD_UNIT),
let (check, wipe_state) = match severity { Some(0),
ErrorLogSeverity::Fatal { wipe_state } => (false, *wipe_state), None,
ErrorLogSeverity::Unknown { wipe_state } => (true, *wipe_state), Some("0"),
}; false,
let addr = hck_key.public().get_onion_address().to_string(); true,
if !check )
|| TcpStream::connect(tor_socks) .await?;
.map_err(|e| Error::new(e, ErrorKind::Tor)) while let Some(log) = logs.try_next().await? {
.and_then(|mut tor_socks| async move { for (regex, severity) in &*LOG_REGEXES {
tokio::time::timeout( if regex.is_match(&log.message) {
Duration::from_secs(30), let (check, wipe_state) = match severity {
socks5_impl::client::connect(&mut tor_socks, (addr, 80), None) ErrorLogSeverity::Fatal { wipe_state } => (false, *wipe_state),
.map_err(|e| Error::new(e, ErrorKind::Tor)), ErrorLogSeverity::Unknown { wipe_state } => (true, *wipe_state),
) };
let addr = hck_key.public().get_onion_address().to_string();
if !check
|| TcpStream::connect(tor_socks)
.map_err(|e| Error::new(e, ErrorKind::Tor)) .map_err(|e| Error::new(e, ErrorKind::Tor))
.await? .and_then(|mut tor_socks| async move {
}) tokio::time::timeout(
.await Duration::from_secs(30),
.with_ctx(|_| (ErrorKind::Tor, "Tor is confirmed to be down")) socks5_impl::client::connect(
.log_err() &mut tor_socks,
.is_some() (addr, 80),
{ None,
if wipe_state { )
Command::new("systemctl") .map_err(|e| Error::new(e, ErrorKind::Tor)),
.arg("stop") )
.arg("tor") .map_err(|e| Error::new(e, ErrorKind::Tor))
.invoke(ErrorKind::Tor) .await?
.await?; })
tokio::fs::remove_dir_all("/var/lib/tor").await?; .await
.with_ctx(|_| (ErrorKind::Tor, "Tor is confirmed to be down"))
.log_err()
.is_some()
{
if wipe_state {
Command::new("systemctl")
.arg("stop")
.arg("tor")
.invoke(ErrorKind::Tor)
.await?;
tokio::fs::remove_dir_all("/var/lib/tor").await?;
}
return Err(Error::new(eyre!("{}", log.message), ErrorKind::Tor));
} }
return Err(Error::new(eyre!("{}", log.message), ErrorKind::Tor));
} }
} }
} }
} }
// Err(Error::new(eyre!("Log stream terminated"), ErrorKind::Tor))
Ok(())
}; };
let health_checker = async { let health_checker = async {
let mut last_success = Instant::now(); let mut last_success = Instant::now();
@@ -960,20 +963,23 @@ impl TorControl {
_thread: tokio::spawn(async move { _thread: tokio::spawn(async move {
let wipe_state = AtomicBool::new(false); let wipe_state = AtomicBool::new(false);
let mut health_timeout = Duration::from_secs(STARTING_HEALTH_TIMEOUT); let mut health_timeout = Duration::from_secs(STARTING_HEALTH_TIMEOUT);
while let Err(e) = torctl( loop {
tor_control, if let Err(e) = torctl(
tor_socks, tor_control,
&mut recv, tor_socks,
&mut thread_services, &mut recv,
&wipe_state, &mut thread_services,
&mut health_timeout, &wipe_state,
) &mut health_timeout,
.await )
{ .await
tracing::error!("{e}: Restarting tor"); {
tracing::debug!("{e:?}"); tracing::error!("TorControl : {e}");
tracing::debug!("{e:?}");
}
tracing::info!("Restarting Tor");
tokio::time::sleep(Duration::from_secs(1)).await;
} }
tracing::info!("TorControl is shut down.")
}) })
.into(), .into(),
send, send,

View File

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

View File

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

View File

@@ -43,7 +43,7 @@ use crate::util::rpc_client::UnixRpcClient;
use crate::volume::data_dir; use crate::volume::data_dir;
use crate::{ARCH, DATA_DIR, PACKAGE_DATA}; 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)] #[derive(Debug)]
pub struct ServiceState { pub struct ServiceState {

View File

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

View File

@@ -3,7 +3,7 @@ use imbl::HashMap;
use imbl_value::InternedString; use imbl_value::InternedString;
use itertools::Itertools; use itertools::Itertools;
use patch_db::HasModel; 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 serde::{Deserialize, Serialize};
use ts_rs::TS; use ts_rs::TS;
@@ -113,27 +113,12 @@ impl AuthContext for TunnelContext {
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS, Parser)] #[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS, Parser)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[model = "Model<Self>"] #[model = "Model<Self>"]
#[ts(export)]
pub struct SignerInfo { pub struct SignerInfo {
pub name: InternedString, pub name: InternedString,
} }
pub fn auth_api<C: Context>() -> ParentHandler<C> { pub fn auth_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new() crate::auth::auth::<C, TunnelContext>()
.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>(),
)
.subcommand("set-password", from_fn_async(set_password_rpc).no_cli()) .subcommand("set-password", from_fn_async(set_password_rpc).no_cli())
.subcommand( .subcommand(
"set-password", "set-password",
@@ -173,19 +158,15 @@ pub fn auth_api<C: Context>() -> ParentHandler<C> {
.with_display_serializable() .with_display_serializable()
.with_custom_display_fn(|HandlerArgs { params, .. }, res| { .with_custom_display_fn(|HandlerArgs { params, .. }, res| {
use prettytable::*; use prettytable::*;
if let Some(format) = params.format { if let Some(format) = params.format {
return display_serializable(format, res); return display_serializable(format, res);
} }
let mut table = Table::new(); let mut table = Table::new();
table.add_row(row![bc => "NAME", "KEY"]); table.add_row(row![bc => "NAME", "KEY"]);
for (key, info) in res { for (key, info) in res {
table.add_row(row![info.name, key]); table.add_row(row![info.name, key]);
} }
table.print_tty(false)?; table.print_tty(false)?;
Ok(()) Ok(())
}) })
.with_about("List authorized keys") .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")] #[serde(rename_all = "camelCase")]
pub struct AddKeyParams { pub struct AddKeyParams {
pub name: InternedString, pub name: InternedString,
@@ -216,7 +197,7 @@ pub async fn add_key(
.result .result
} }
#[derive(Debug, Deserialize, Serialize, Parser)] #[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RemoveKeyParams { pub struct RemoveKeyParams {
pub key: AnyVerifyingKey, 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() ctx.db.peek().await.into_auth_pubkeys().de()
} }
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct SetPasswordParams { pub struct SetPasswordParams {
pub password: String, 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_11;
mod v0_4_0_alpha_12; mod v0_4_0_alpha_12;
mod v0_4_0_alpha_13; 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 { impl Current {
#[instrument(skip(self, db))] #[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_10(Wrapper<v0_4_0_alpha_10::Version>),
V0_4_0_alpha_11(Wrapper<v0_4_0_alpha_11::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_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), 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_10(v) => DynVersion(Box::new(v.0)),
Self::V0_4_0_alpha_11(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_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) => { Self::Other(v) => {
return Err(Error::new( return Err(Error::new(
eyre!("unknown version {v}"), 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_10(Wrapper(x)) => x.semver(),
Version::V0_4_0_alpha_11(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_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(), Version::Other(x) => x.clone(),
} }
} }

View File

@@ -4,7 +4,7 @@ use exver::{PreReleaseSegment, VersionRange};
use imbl_value::InternedString; use imbl_value::InternedString;
use super::v0_3_5::V0_3_0_COMPAT; 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::net::tor::TorSecretKey;
use crate::prelude::*; use crate::prelude::*;
@@ -75,7 +75,10 @@ impl VersionT for Version {
} }
fix_host(&mut db["public"]["serverInfo"]["network"]["host"])?; 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) 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. // 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 { AddressInfo, Host, Hostname, HostnameInfo } from "../types"
import { Effects } from "../Effects" import { Effects } from "../Effects"
import { DropGenerator, DropPromise } from "./Drop" import { DropGenerator, DropPromise } from "./Drop"
import { IPV6_LINK_LOCAL } from "./ip" import { IpAddress, IPV6_LINK_LOCAL } from "./ip"
export type UrlString = string export type UrlString = string
export type HostId = string export type HostId = string
@@ -17,7 +17,15 @@ export const getHostname = (url: string): Hostname | null => {
return last return last
} }
type FilterKinds = "onion" | "local" | "domain" | "ip" | "ipv4" | "ipv6" type FilterKinds =
| "onion"
| "local"
| "domain"
| "ip"
| "ipv4"
| "ipv6"
| "localhost"
| "link-local"
export type Filter = { export type Filter = {
visibility?: "public" | "private" visibility?: "public" | "private"
kind?: FilterKinds | FilterKinds[] kind?: FilterKinds | FilterKinds[]
@@ -72,6 +80,12 @@ type FilterReturnTy<F extends Filter> = F extends {
: Exclude<HostnameInfo, FilterReturnTy<E>> : Exclude<HostnameInfo, FilterReturnTy<E>>
: HostnameInfo : HostnameInfo
const defaultFilter = {
exclude: {
kind: ["localhost", "link-local"] as ("localhost" | "link-local")[],
},
}
type Formats = "hostname-info" | "urlstring" | "url" type Formats = "hostname-info" | "urlstring" | "url"
type FormatReturnTy< type FormatReturnTy<
F extends Filter, F extends Filter,
@@ -92,8 +106,11 @@ export type Filled = {
sslUrl: UrlString | null sslUrl: UrlString | null
} }
filter: <F extends Filter, Format extends Formats = "urlstring">( filter: <
filter: F, F extends Filter = typeof defaultFilter,
Format extends Formats = "urlstring",
>(
filter?: F,
format?: Format, format?: Format,
) => FormatReturnTy<F, Format>[] ) => FormatReturnTy<F, Format>[]
@@ -215,7 +232,13 @@ function filterRec(
h.kind === "ip" && h.kind === "ip" &&
h.hostname.kind === "domain") || h.hostname.kind === "domain") ||
(kind.has("ipv4") && h.kind === "ip" && h.hostname.kind === "ipv4") || (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, ...addressInfo,
hostnames, hostnames,
toUrls, toUrls,
filter: <F extends Filter, Format extends Formats = "urlstring">( filter: <
filter: F, F extends Filter = typeof defaultFilter,
Format extends Formats = "urlstring",
>(
filter?: F,
format?: Format, format?: Format,
) => { ) => {
const filtered = filterRec(hostnames, filter, false) const filtered = filterRec(hostnames, filter ?? defaultFilter, false)
let res: FormatReturnTy<F, Format>[] = filtered as any let res: FormatReturnTy<F, Format>[] = filtered as any
if (format === "hostname-info") return res if (format === "hostname-info") return res
const urls = filtered.flatMap(toUrlArray) const urls = filtered.flatMap(toUrlArray)

View File

@@ -61,7 +61,7 @@ import {
} from "../../base/lib/inits" } from "../../base/lib/inits"
import { DropGenerator } from "../../base/lib/util/Drop" 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 // prettier-ignore
type AnyNeverCond<T extends any[], Then, Else> = type AnyNeverCond<T extends any[], Then, Else> =

View File

@@ -410,12 +410,17 @@ export class SubContainerOwned<
workdir = options.cwd workdir = options.cwd
delete 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( const child = cp.spawn(
"start-container", "start-container",
[ [
"subcontainer", "subcontainer",
"exec", "exec",
`--env=/media/startos/images/${this.imageId}.env`, `--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`, `--user=${user}`,
`--workdir=${workdir}`, `--workdir=${workdir}`,
...extra, ...extra,
@@ -530,6 +535,11 @@ export class SubContainerOwned<
workdir = options.cwd workdir = options.cwd
delete 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() await this.killLeader()
this.leaderExited = false this.leaderExited = false
this.leader = cp.spawn( this.leader = cp.spawn(
@@ -537,7 +547,7 @@ export class SubContainerOwned<
[ [
"subcontainer", "subcontainer",
"launch", "launch",
`--env=/media/startos/images/${this.imageId}.env`, `--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`, `--user=${user}`,
`--workdir=${workdir}`, `--workdir=${workdir}`,
...extra, ...extra,
@@ -574,12 +584,17 @@ export class SubContainerOwned<
workdir = options.cwd workdir = options.cwd
delete 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( return cp.spawn(
"start-container", "start-container",
[ [
"subcontainer", "subcontainer",
"exec", "exec",
`--env=/media/startos/images/${this.imageId}.env`, `--env-file=/media/startos/images/${this.imageId}.env`,
`--user=${user}`, `--user=${user}`,
`--workdir=${workdir}`, `--workdir=${workdir}`,
...extra, ...extra,

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@start9labs/start-sdk", "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", "description": "Software development kit to facilitate packaging services for StartOS",
"main": "./package/lib/index.js", "main": "./package/lib/index.js",
"types": "./package/lib/index.d.ts", "types": "./package/lib/index.d.ts",

4
web/package-lock.json generated
View File

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

View File

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

View File

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