Compare commits

..

74 Commits

Author SHA1 Message Date
Aiden McClelland
4ba55860dd Merge branch 'feat/preferred-port-design' into sdk-comments 2026-02-24 14:28:56 -07:00
Aiden McClelland
3974c09369 feat(core): refactor hostname to ServerHostnameInfo with name/hostname pair
- Rename Hostname to ServerHostnameInfo, add name + hostname fields
- Add set_hostname_rpc for changing hostname at runtime
- Migrate alpha_20: generate serverInfo.name from hostname, delete ui.name
- Extract gateway.rs helpers to fix rustfmt nesting depth issue
- Add i18n key for hostname validation error
- Update SDK bindings
2026-02-24 14:18:53 -07:00
Matt Hill
f0b41a3a4c Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into sdk-comments 2026-02-24 10:28:00 -07:00
Matt Hill
86ecc4cc99 frontend support for setting and changing hostname 2026-02-24 10:27:22 -07:00
Matt Hill
d1162272f0 clean up prefill flow 2026-02-24 07:19:56 -07:00
Matt Hill
13ac469ed0 Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into sdk-comments 2026-02-23 18:14:06 -07:00
Matt Hill
5294e8f444 minor cleanup from patch-db audit 2026-02-23 18:13:33 -07:00
Aiden McClelland
b7da7cd59f fix(core): preserve plugin URLs across binding updates
BindInfo::update was replacing addresses with a new DerivedAddressInfo
that cleared the available set, wiping plugin-exported URLs whenever
bind() was called. Also simplify update_addresses plugin preservation
to use retain in place rather than collecting into a separate set.
2026-02-23 17:56:15 -07:00
Matt Hill
c196f250f6 Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into sdk-comments 2026-02-23 17:00:23 -07:00
Matt Hill
bee8a0f9d8 send prefill for tasks and hide operations to hidden fields 2026-02-23 16:59:21 -07:00
Matt Hill
8213e45b85 Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into sdk-comments 2026-02-23 14:26:49 -07:00
Matt Hill
e9b9925c0e rework smtp 2026-02-23 14:25:51 -07:00
Aiden McClelland
0724989792 feat(core): allow setting server hostname 2026-02-23 13:35:34 -07:00
Matt Hill
804560d43c add comments to everything potentially consumer facing 2026-02-21 20:40:45 -07:00
Aiden McClelland
31352a72c3 chore: migrate from ts-matches to zod across all TypeScript packages 2026-02-20 16:24:35 -07:00
Aiden McClelland
c7a4f0f9cb feat: tor hidden service key migration 2026-02-20 16:10:42 -07:00
Aiden McClelland
7879668c40 chore: remove completed TODO 2026-02-20 16:09:19 -07:00
Matt Hill
6a01b5eab1 frontend start-tunnel updates 2026-02-20 13:33:18 -07:00
Aiden McClelland
80cb2d9ba5 feat: add getOutboundGateway effect and simplify VersionGraph init/uninit
Add getOutboundGateway effect across core, container-runtime, and SDK
to let services query their effective outbound gateway with callback
support. Remove preInstall/uninstall hooks from VersionGraph as they
are no longer needed.
2026-02-20 13:26:45 -07:00
Aiden McClelland
8c1a452742 chore: replace OTA updates TODO with UI TODO for MattDHill 2026-02-19 23:28:20 -07:00
Aiden McClelland
135afd0251 fix: publish script dpkg-name, s3cfg fallback, and --reinstall for apply 2026-02-19 23:26:16 -07:00
Aiden McClelland
35f3274f29 feat: OTA updates for start-tunnel via apt repository (untested)
- Add apt repo publish script (build/apt/publish-deb.sh) for S3-hosted repo
- Add apt source config and GPG key placeholder (apt/)
- Add tunnel.update.check and tunnel.update.apply RPC endpoints
- Wire up update API in tunnel frontend (api service + mock)
- Uses systemd-run --scope to survive service restart during update
2026-02-19 22:38:39 -07:00
Aiden McClelland
9af5b87c92 chore: remove completed URL plugins TODO 2026-02-19 21:40:36 -07:00
Aiden McClelland
66b5bc1897 fix: propagate host locale into LXC containers and write locale.conf 2026-02-19 21:39:37 -07:00
Aiden McClelland
7909941b70 feat: builder-style InputSpec API, prefill plumbing, and port forward fix
- Add addKey() and add() builder methods to InputSpec with InputSpecTools
- Move OuterType to last generic param on Value, List, and all dynamic methods
- Plumb prefill through getActionInput end-to-end (core → container-runtime → SDK)
- Filter port_forwards to enabled addresses only
- Bump SDK to 0.4.0-beta.50
2026-02-19 16:44:44 -07:00
Aiden McClelland
4527046f2e feat: NAT hairpinning, DNS static servers, clear service error on install
- Add POSTROUTING MASQUERADE rules for container and host hairpin NAT
- Allow bridge subnet containers to reach private forwards via LAN IPs
- Pass bridge_subnet env var from forward.rs to forward-port script
- Use DB-configured static DNS servers in resolver with DB watcher
- Fall back to resolv.conf servers when no static servers configured
- Clear service error state when install/update completes successfully
- Remove completed TODO items
2026-02-19 15:27:52 -07:00
Matt Hill
5a292e6e2a show table even when no addresses 2026-02-19 12:01:34 -07:00
Matt Hill
84149be3c1 touch up URL plugins table 2026-02-19 11:41:41 -07:00
Aiden McClelland
d562466fc4 feat: split row_actions into remove_action and overflow_actions for URL plugins 2026-02-18 18:18:53 -07:00
Aiden McClelland
9c3053f103 feat: implement URL plugins with table/row actions and prefill support
- Add URL plugin effects (register, export_url, clear_urls) in core
- Add PluginHostnameInfo, HostnameMetadata::Plugin, and plugin registration types
- Implement plugin URL table in web UI with tableAction button and rowAction overflow menus
- Thread urlPluginMetadata (packageId, hostId, interfaceId, internalPort) as prefill to actions
- Add prefill support to PackageActionData so metadata passes through form dialogs
- Add i18n translations for plugin error messages
- Clean up plugin URLs on package uninstall
2026-02-18 17:51:13 -07:00
Matt Hill
dce975410f interface row clickable again, bu now with a chevron! 2026-02-18 17:11:57 -07:00
Matt Hill
783ce4b3b6 version instead of os query param 2026-02-18 14:41:03 -07:00
Aiden McClelland
675a03bdc5 chore: add TODOs for URL plugins, NAT hairpinning, and start-tunnel OTA updates 2026-02-17 23:41:39 -07:00
Matt Hill
485fced691 round out dns check, dns server check, port forward check, and gateway port forwards 2026-02-17 23:31:47 -07:00
Aiden McClelland
a22707c1cb chore: add TODO to clear service error state on install/update 2026-02-17 19:05:19 -07:00
Aiden McClelland
74e10ec473 chore: add createTask decoupling TODO 2026-02-17 19:03:35 -07:00
Aiden McClelland
e25e0f0c12 chore: bump sdk version to 0.4.0-beta.49 2026-02-17 18:59:41 -07:00
Aiden McClelland
4cae00cb33 refactor: rename manifest metadata fields and improve error display
Rename wrapperRepo→packageRepo, marketingSite→marketingUrl,
docsUrl→docsUrls (array), remove supportSite. Add display_src/display_dbg
helpers to Error. Fix DepInfo description type to LocaleString. Update
web UI, SDK bindings, tests, and fixtures to match. Clean up cli_attach
error handling and remove dead commented code.
2026-02-17 18:40:50 -07:00
Aiden McClelland
313b2df540 feat: add check-dns gateway endpoint and fix per-interface routing tables
Add a `check-dns` RPC endpoint that verifies whether a gateway's DNS
is properly configured for private domain resolution. Uses a three-tier
check: direct match (DNS == server IP), TXT challenge probe (DNS on
LAN), or failure (DNS off-subnet).

Fix per-interface routing tables to clone all non-default routes from
the main table instead of only the interface's own subnets. This
preserves LAN reachability when the priority-75 catch-all overrides
default routing. Filter out status-only flags (linkdown, dead) that
are invalid for `ip route add`.
2026-02-17 16:22:24 -07:00
Aiden McClelland
5fbc73755d fix: replace .status() with .invoke() for iptables/ip commands
Using .status() leaks stderr directly to system logs, causing noisy
iptables error messages. Switch all networking CLI invocations to use
.invoke() which captures stderr properly. For check-then-act patterns
(iptables -C), use .invoke().await.is_err() instead of
.status().await.map_or(false, |s| s.success()).
2026-02-17 14:12:29 -07:00
Aiden McClelland
bc4478b0b9 refactor: manifest wraps PackageMetadata, move dependency_metadata to PackageVersionInfo
Manifest now embeds PackageMetadata via #[serde(flatten)] instead of
duplicating ~14 fields. icon and dependency_metadata moved from
PackageMetadata to PackageVersionInfo since they are registry-enrichment
data loaded from the S9PK archive. merge_with now returns errors on
metadata/icon/dependency_metadata mismatches instead of silently ignoring
them.
2026-02-17 14:12:14 -07:00
Aiden McClelland
68141112b7 feat: per-service and default outbound gateway routing
Add set-outbound-gateway RPC for packages and set-default-outbound RPC
for the server, with policy routing enforcement via ip rules. Fix
connmark restore to skip packets with existing fwmarks, add bridge
subnet routes to per-interface tables, and fix squashfs path in
update-image-local.sh.
2026-02-17 12:52:24 -07:00
Aiden McClelland
ccafb599a6 chore: update bindings and use typed params for outbound gateway API 2026-02-17 12:31:35 -07:00
Aiden McClelland
52272feb3e fix: switch BackgroundJobRunner from Vec to FuturesUnordered
BackgroundJobRunner stored active jobs in a Vec<BoxFuture> and polled
ALL of them on every wakeup — O(n) per poll. Since this runs in the
same tokio::select! as the WebServer accept loop, polling overhead from
active connections directly delayed acceptance of new connections.

FuturesUnordered only polls woken futures — O(woken) instead of O(n).
2026-02-16 22:02:59 -07:00
Aiden McClelland
1abad93646 fix: add TLS handshake timeout and fix accept loop deadlock
Two issues in TlsListener::poll_accept:

1. No timeout on TLS handshakes: LazyConfigAcceptor waits indefinitely
   for ClientHello. Attackers that complete TCP handshake but never send
   TLS data create zombie futures in `in_progress` that never complete.
   Fix: wrap the entire handshake in tokio::time::timeout(15s).

2. Missing waker on new-connection pending path: when a TCP connection
   is accepted and the TLS handshake is pending, poll_accept returned
   Pending without calling wake_by_ref(). Since the TcpListener returned
   Ready (not Pending), no waker was registered for it. With edge-
   triggered epoll and no other wakeup source, the task sleeps forever
   and remaining connections in the kernel accept queue are never
   drained. Fix: add cx.waker().wake_by_ref() so the task immediately
   re-polls and continues draining the accept queue.
2026-02-16 21:52:12 -07:00
Aiden McClelland
c9468dda02 fix: include public gateways for IP-based addresses in vhost targets
The server hostname vhost construction only collected private IPs,
always setting public to empty. Public IP addresses (Ipv4/Ipv6 metadata
with public=true) were never added to the vhost target's public gateway
set, causing the vhost filter to reject public traffic for IP-based
addresses.
2026-02-16 19:45:10 -07:00
Aiden McClelland
6a1b1627c5 chore: reserialize db on equal version, update bindings and docs
- Run de/ser roundtrip in pre_init even when db version matches, ensuring
  all #[serde(default)] fields are populated before any typed access
- Add patchdb.md documentation for TypedDbWatch patterns
- Update TS bindings for CheckPortParams, CheckPortRes, ifconfigUrl
- Update CLAUDE.md docs with patchdb and component-level references
2026-02-16 19:27:48 -07:00
Aiden McClelland
cfbace1d91 fix: add CONNMARK restore-mark to mangle OUTPUT chain
The CONNMARK --restore-mark rule was only in PREROUTING, which handles
forwarded packets. Locally-bound listeners (e.g. vhost) generate replies
through the OUTPUT chain, where the fwmark was never restored. This
caused response packets to route via the default table instead of back
through the originating interface.
2026-02-16 19:22:07 -07:00
Matt Hill
d97ab59bab update bindings for API types, add ARCHITECTURE (#3124)
* update binding for API types, add ARCHITECTURE

* translations
2026-02-16 16:23:28 +01:00
Aiden McClelland
3518eccc87 feat: add port_forwards field to Host for tracking gateway forwarding rules 2026-02-14 16:40:21 -07:00
Matt Hill
2f19188dae looking good 2026-02-14 16:37:04 -07:00
Aiden McClelland
3a63f3b840 feat: add mdns hostname metadata variant and fix vhost routing
- Add HostnameMetadata::Mdns variant to distinguish mDNS from private domains
- Mark mDNS addresses as private (public: false) since mDNS is local-only
- Fall back to null SNI entry when hostname not found in vhost mapping
- Simplify public detection in ProxyTarget filter
- Pass hostname to update_addresses for mDNS domain name generation
2026-02-14 15:34:48 -07:00
Matt Hill
098d9275f4 new service interfacee page 2026-02-14 12:24:16 -07:00
Matt Hill
d5c74bc22e re-arrange (#3123) 2026-02-14 08:15:50 -07:00
Aiden McClelland
49d4da03ca feat: refactor NetService to watch DB and reconcile network state
- NetService sync task now uses PatchDB DbWatch instead of being called
  directly after DB mutations
- Read gateways from DB instead of network interface context when
  updating host addresses
- gateway sync updates all host addresses in the DB
- Add Watch<u64> channel for callers to wait on sync completion
- Fix ts-rs codegen bug with #[ts(skip)] on flattened Plugin field
- Update SDK getServiceInterface.ts for new HostnameInfo shape
- Remove unnecessary HTTPS redirect in static_server.rs
- Fix tunnel/api.rs to filter for WAN IPv4 address
2026-02-13 16:21:57 -07:00
Aiden McClelland
3765465618 chore: update ts bindings for preferred port design 2026-02-13 14:23:48 -07:00
Aiden McClelland
61f820d09e Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into feat/preferred-port-design 2026-02-13 13:39:25 -07:00
Aiden McClelland
db7f3341ac wip refactor 2026-02-12 14:51:33 -07:00
Matt Hill
4decf9335c fix license display in marketplace 2026-02-12 13:07:19 -07:00
Matt Hill
339e5f799a build ts types and fix i18n 2026-02-12 11:32:29 -07:00
Aiden McClelland
89d3e0cf35 Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/start-os into feat/preferred-port-design 2026-02-12 10:51:32 -07:00
Aiden McClelland
638ed27599 feat: replace SourceFilter with IpNet, add policy routing, remove MASQUERADE 2026-02-12 10:51:26 -07:00
Matt Hill
da75b8498e Merge branch 'next/major' of github.com:Start9Labs/start-os into feat/preferred-port-design 2026-02-12 08:28:36 -07:00
Matt Hill
8ef4ecf5ac outbound gateway support (#3120)
* Multiple (#3111)

* fix alerts i18n, fix status display, better, remove usb media, hide shutdown for install complete

* trigger chnage detection for localize pipe and round out implementing localize pipe for consistency even though not needed

* Fix PackageInfoShort to handle LocaleString on releaseNotes (#3112)

* Fix PackageInfoShort to handle LocaleString on releaseNotes

* fix: filter by target_version in get_matching_models and pass otherVersions from install

* chore: add exver documentation for ai agents

* frontend plus some be types

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2026-02-12 08:27:09 -07:00
Aiden McClelland
2a54625f43 feat: replace InterfaceFilter with ForwardRequirements, add WildcardListener, complete alpha.20 bump
- Replace DynInterfaceFilter with ForwardRequirements for per-IP forward
  precision with source-subnet iptables filtering for private forwards
- Add WildcardListener (binds [::]:port) to replace the per-gateway
  NetworkInterfaceListener/SelfContainedNetworkInterfaceListener/
  UpgradableListener infrastructure
- Update forward-port script with src_subnet and excluded_src env vars
- Remove unused filter types and listener infrastructure from gateway.rs
- Add availablePorts migration (IdPool -> BTreeMap<u16, bool>) to alpha.20
- Complete version bump to 0.4.0-alpha.20 in SDK and web
2026-02-11 18:10:27 -07:00
Aiden McClelland
4e638fb58e feat: implement preferred port allocation and per-address enable/disable
- Add AvailablePorts::try_alloc() with SSL tracking (BTreeMap<u16, bool>)
- Add DerivedAddressInfo on BindInfo with private_disabled/public_enabled/possible sets
- Add Bindings wrapper with Map impl for patchdb indexed access
- Flatten HostAddress from single-variant enum to struct
- Replace set-gateway-enabled RPC with set-address-enabled
- Remove hostname_info from Host; computed addresses now in BindInfo.addresses.possible
- Compute possible addresses inline in NetServiceData::update()
- Update DB migration, SDK types, frontend, and container-runtime
2026-02-10 17:38:51 -07:00
Aiden McClelland
73274ef6e0 docs: update TODO.md with DerivedAddressInfo design, remove completed tor task 2026-02-10 14:45:50 -07:00
Aiden McClelland
e1915bf497 chore: format RPCSpec.md markdown table 2026-02-10 13:38:40 -07:00
Aiden McClelland
8204074bdf chore: flatten HostnameInfo from enum to struct
HostnameInfo only had one variant (Ip) after removing Tor. Flatten it
into a plain struct with fields gateway, public, hostname. Remove all
kind === 'ip' type guards and narrowing across SDK, frontend, and
container runtime. Update DB migration to strip the kind field.
2026-02-10 13:38:12 -07:00
Aiden McClelland
2ee403e7de chore: remove tor from startos core
Tor is being moved from a built-in OS feature to a service. This removes
the Arti-based Tor client, onion address management, hidden service
creation, and all related code from the core backend, frontend, and SDK.

- Delete core/src/net/tor/ module (~2060 lines)
- Remove OnionAddress, TorSecretKey, TorController from all consumers
- Remove HostnameInfo::Onion and HostAddress::Onion variants
- Remove onion CRUD RPC endpoints and tor subcommand
- Remove tor key handling from account and backup/restore
- Remove ~12 tor-related Cargo dependencies (arti-client, torut, etc.)
- Remove tor UI components, API methods, mock data, and routes
- Remove OnionHostname and tor patterns/regexes from SDK
- Add v0_4_0_alpha_20 database migration to strip onion data
- Bump version to 0.4.0-alpha.20
2026-02-10 13:28:24 -07:00
Aiden McClelland
1974dfd66f docs: move address enable/disable to overflow menu, add SSL indicator, defer UI placement decisions 2026-02-09 13:29:49 -07:00
Aiden McClelland
2e03a95e47 docs: overhaul interfaces page design with view/manage split and per-address controls 2026-02-09 13:10:57 -07:00
Aiden McClelland
8f809dab21 docs: add user-controlled public/private and port forward mapping to design 2026-02-08 11:17:43 -07:00
Aiden McClelland
c0b2cbe1c8 docs: update preferred external port design in TODO 2026-02-06 09:30:35 -07:00
1003 changed files with 18455 additions and 34742 deletions

View File

@@ -47,18 +47,18 @@ runs:
sudo rm -rf /usr/share/swift sudo rm -rf /usr/share/swift
sudo rm -rf "$AGENT_TOOLSDIRECTORY" sudo rm -rf "$AGENT_TOOLSDIRECTORY"
# Some runners lack /opt/hostedtoolcache, which setup-python and setup-qemu expect # BuildJet runners lack /opt/hostedtoolcache, which setup-python and setup-qemu expect
- name: Ensure hostedtoolcache exists - name: Ensure hostedtoolcache exists
shell: bash shell: bash
run: sudo mkdir -p /opt/hostedtoolcache && sudo chown $USER:$USER /opt/hostedtoolcache run: sudo mkdir -p /opt/hostedtoolcache && sudo chown $USER:$USER /opt/hostedtoolcache
- name: Set up Python - name: Set up Python
if: inputs.setup-python == 'true' if: inputs.setup-python == 'true'
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: "3.x" python-version: "3.x"
- uses: actions/setup-node@v6 - uses: actions/setup-node@v4
with: with:
node-version: ${{ inputs.nodejs-version }} node-version: ${{ inputs.nodejs-version }}
cache: npm cache: npm
@@ -66,15 +66,15 @@ runs:
- name: Set up Docker QEMU - name: Set up Docker QEMU
if: inputs.setup-docker == 'true' if: inputs.setup-docker == 'true'
uses: docker/setup-qemu-action@v4 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
if: inputs.setup-docker == 'true' if: inputs.setup-docker == 'true'
uses: docker/setup-buildx-action@v4 uses: docker/setup-buildx-action@v3
- name: Configure sccache - name: Configure sccache
if: inputs.setup-sccache == 'true' if: inputs.setup-sccache == 'true'
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
script: | script: |
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || ''); core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');

View File

@@ -63,12 +63,12 @@ jobs:
"ALL": ["x86_64-unknown-linux-musl", "x86_64-apple-darwin", "aarch64-unknown-linux-musl", "aarch64-apple-darwin", "riscv64gc-unknown-linux-musl"] "ALL": ["x86_64-unknown-linux-musl", "x86_64-apple-darwin", "aarch64-unknown-linux-musl", "aarch64-apple-darwin", "riscv64gc-unknown-linux-musl"]
}')[github.event.inputs.platform || 'ALL'] }')[github.event.inputs.platform || 'ALL']
}} }}
runs-on: ${{ fromJson('["ubuntu-latest", "ubuntu-24.04-32-cores"]')[github.event.inputs.runner == 'fast'] }} runs-on: ${{ fromJson('["ubuntu-latest", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps: steps:
- name: Mount tmpfs - name: Mount tmpfs
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
run: sudo mount -t tmpfs tmpfs . run: sudo mount -t tmpfs tmpfs .
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: ./.github/actions/setup-build - uses: ./.github/actions/setup-build
@@ -82,7 +82,7 @@ jobs:
SCCACHE_GHA_ENABLED: on SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0 SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: start-cli_${{ matrix.triple }} name: start-cli_${{ matrix.triple }}
path: core/target/${{ matrix.triple }}/release/start-cli path: core/target/${{ matrix.triple }}/release/start-cli

View File

@@ -59,12 +59,12 @@ jobs:
"ALL": ["x86_64", "aarch64", "riscv64"] "ALL": ["x86_64", "aarch64", "riscv64"]
}')[github.event.inputs.platform || 'ALL'] }')[github.event.inputs.platform || 'ALL']
}} }}
runs-on: ${{ fromJson('["ubuntu-latest", "ubuntu-24.04-32-cores"]')[github.event.inputs.runner == 'fast'] }} runs-on: ${{ fromJson('["ubuntu-latest", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps: steps:
- name: Mount tmpfs - name: Mount tmpfs
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
run: sudo mount -t tmpfs tmpfs . run: sudo mount -t tmpfs tmpfs .
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: ./.github/actions/setup-build - uses: ./.github/actions/setup-build
@@ -78,7 +78,7 @@ jobs:
SCCACHE_GHA_ENABLED: on SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0 SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: start-registry_${{ matrix.arch }}.deb name: start-registry_${{ matrix.arch }}.deb
path: results/start-registry-*_${{ matrix.arch }}.deb path: results/start-registry-*_${{ matrix.arch }}.deb
@@ -89,7 +89,7 @@ jobs:
permissions: permissions:
contents: read contents: read
packages: write packages: write
runs-on: ${{ fromJson('["ubuntu-latest", "ubuntu-24.04-32-cores"]')[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 - name: Cleaning up unnecessary files
run: | run: |
@@ -102,13 +102,13 @@ jobs:
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
- name: Set up docker QEMU - name: Set up docker QEMU
uses: docker/setup-qemu-action@v4 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4 uses: docker/setup-buildx-action@v3
- name: "Login to GitHub Container Registry" - name: "Login to GitHub Container Registry"
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{github.actor}} username: ${{github.actor}}
@@ -116,14 +116,14 @@ jobs:
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v6 uses: docker/metadata-action@v5
with: with:
images: ghcr.io/Start9Labs/startos-registry images: ghcr.io/Start9Labs/startos-registry
tags: | tags: |
type=raw,value=${{ github.ref_name }} type=raw,value=${{ github.ref_name }}
- name: Download debian package - name: Download debian package
uses: actions/download-artifact@v8 uses: actions/download-artifact@v4
with: with:
pattern: start-registry_*.deb pattern: start-registry_*.deb
@@ -162,7 +162,7 @@ jobs:
ADD *.deb . ADD *.deb .
RUN apt-get update && apt-get install -y ./*_$(uname -m).deb && rm -rf *.deb /var/lib/apt/lists/* RUN apt-get install -y ./*_$(uname -m).deb && rm *.deb
VOLUME /var/lib/startos VOLUME /var/lib/startos

View File

@@ -59,12 +59,12 @@ jobs:
"ALL": ["x86_64", "aarch64", "riscv64"] "ALL": ["x86_64", "aarch64", "riscv64"]
}')[github.event.inputs.platform || 'ALL'] }')[github.event.inputs.platform || 'ALL']
}} }}
runs-on: ${{ fromJson('["ubuntu-latest", "ubuntu-24.04-32-cores"]')[github.event.inputs.runner == 'fast'] }} runs-on: ${{ fromJson('["ubuntu-latest", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps: steps:
- name: Mount tmpfs - name: Mount tmpfs
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
run: sudo mount -t tmpfs tmpfs . run: sudo mount -t tmpfs tmpfs .
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: ./.github/actions/setup-build - uses: ./.github/actions/setup-build
@@ -78,7 +78,7 @@ jobs:
SCCACHE_GHA_ENABLED: on SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0 SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: start-tunnel_${{ matrix.arch }}.deb name: start-tunnel_${{ matrix.arch }}.deb
path: results/start-tunnel-*_${{ matrix.arch }}.deb path: results/start-tunnel-*_${{ matrix.arch }}.deb

View File

@@ -25,13 +25,10 @@ on:
- ALL - ALL
- x86_64 - x86_64
- x86_64-nonfree - x86_64-nonfree
- x86_64-nvidia
- aarch64 - aarch64
- aarch64-nonfree - aarch64-nonfree
- aarch64-nvidia
# - raspberrypi # - raspberrypi
- riscv64 - riscv64
- riscv64-nonfree
deploy: deploy:
type: choice type: choice
description: Deploy description: Deploy
@@ -68,13 +65,10 @@ jobs:
fromJson('{ fromJson('{
"x86_64": ["x86_64"], "x86_64": ["x86_64"],
"x86_64-nonfree": ["x86_64"], "x86_64-nonfree": ["x86_64"],
"x86_64-nvidia": ["x86_64"],
"aarch64": ["aarch64"], "aarch64": ["aarch64"],
"aarch64-nonfree": ["aarch64"], "aarch64-nonfree": ["aarch64"],
"aarch64-nvidia": ["aarch64"],
"raspberrypi": ["aarch64"], "raspberrypi": ["aarch64"],
"riscv64": ["riscv64"], "riscv64": ["riscv64"],
"riscv64-nonfree": ["riscv64"],
"ALL": ["x86_64", "aarch64", "riscv64"] "ALL": ["x86_64", "aarch64", "riscv64"]
}')[github.event.inputs.platform || 'ALL'] }')[github.event.inputs.platform || 'ALL']
}} }}
@@ -89,9 +83,9 @@ jobs:
"riscv64": "ubuntu-latest" "riscv64": "ubuntu-latest"
}')[matrix.arch], }')[matrix.arch],
fromJson('{ fromJson('{
"x86_64": "amd64-fast", "x86_64": "buildjet-32vcpu-ubuntu-2204",
"aarch64": "aarch64-fast", "aarch64": "buildjet-32vcpu-ubuntu-2204-arm",
"riscv64": "amd64-fast" "riscv64": "buildjet-32vcpu-ubuntu-2204"
}')[matrix.arch] }')[matrix.arch]
) )
)[github.event.inputs.runner == 'fast'] )[github.event.inputs.runner == 'fast']
@@ -100,7 +94,7 @@ jobs:
- name: Mount tmpfs - name: Mount tmpfs
if: ${{ github.event.inputs.runner == 'fast' }} if: ${{ github.event.inputs.runner == 'fast' }}
run: sudo mount -t tmpfs tmpfs . run: sudo mount -t tmpfs tmpfs .
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: ./.github/actions/setup-build - uses: ./.github/actions/setup-build
@@ -114,7 +108,7 @@ jobs:
SCCACHE_GHA_ENABLED: on SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0 SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: compiled-${{ matrix.arch }}.tar name: compiled-${{ matrix.arch }}.tar
path: compiled-${{ matrix.arch }}.tar path: compiled-${{ matrix.arch }}.tar
@@ -124,13 +118,14 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# TODO: re-add "raspberrypi" to the platform list below
platform: >- platform: >-
${{ ${{
fromJson( fromJson(
format( format(
'[ '[
["{0}"], ["{0}"],
["x86_64", "x86_64-nonfree", "x86_64-nvidia", "aarch64", "aarch64-nonfree", "aarch64-nvidia", "raspberrypi", "riscv64", "riscv64-nonfree"] ["x86_64", "x86_64-nonfree", "aarch64", "aarch64-nonfree", "riscv64"]
]', ]',
github.event.inputs.platform || 'ALL' github.event.inputs.platform || 'ALL'
) )
@@ -144,24 +139,18 @@ jobs:
fromJson('{ fromJson('{
"x86_64": "ubuntu-latest", "x86_64": "ubuntu-latest",
"x86_64-nonfree": "ubuntu-latest", "x86_64-nonfree": "ubuntu-latest",
"x86_64-nvidia": "ubuntu-latest",
"aarch64": "ubuntu-24.04-arm", "aarch64": "ubuntu-24.04-arm",
"aarch64-nonfree": "ubuntu-24.04-arm", "aarch64-nonfree": "ubuntu-24.04-arm",
"aarch64-nvidia": "ubuntu-24.04-arm",
"raspberrypi": "ubuntu-24.04-arm", "raspberrypi": "ubuntu-24.04-arm",
"riscv64": "ubuntu-24.04-arm", "riscv64": "ubuntu-24.04-arm",
"riscv64-nonfree": "ubuntu-24.04-arm",
}')[matrix.platform], }')[matrix.platform],
fromJson('{ fromJson('{
"x86_64": "amd64-fast", "x86_64": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nonfree": "amd64-fast", "x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nvidia": "amd64-fast", "aarch64": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64": "aarch64-fast", "aarch64-nonfree": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64-nonfree": "aarch64-fast", "raspberrypi": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64-nvidia": "aarch64-fast", "riscv64": "buildjet-8vcpu-ubuntu-2204",
"raspberrypi": "aarch64-fast",
"riscv64": "amd64-fast",
"riscv64-nonfree": "amd64-fast",
}')[matrix.platform] }')[matrix.platform]
) )
)[github.event.inputs.runner == 'fast'] )[github.event.inputs.runner == 'fast']
@@ -172,13 +161,10 @@ jobs:
fromJson('{ fromJson('{
"x86_64": "x86_64", "x86_64": "x86_64",
"x86_64-nonfree": "x86_64", "x86_64-nonfree": "x86_64",
"x86_64-nvidia": "x86_64",
"aarch64": "aarch64", "aarch64": "aarch64",
"aarch64-nonfree": "aarch64", "aarch64-nonfree": "aarch64",
"aarch64-nvidia": "aarch64",
"raspberrypi": "aarch64", "raspberrypi": "aarch64",
"riscv64": "riscv64", "riscv64": "riscv64",
"riscv64-nonfree": "riscv64",
}')[matrix.platform] }')[matrix.platform]
}} }}
steps: steps:
@@ -203,19 +189,19 @@ jobs:
sudo rm -rf "$AGENT_TOOLSDIRECTORY" # Pre-cached tool cache (Go, Node, etc.) sudo rm -rf "$AGENT_TOOLSDIRECTORY" # Pre-cached tool cache (Go, Node, etc.)
if: ${{ github.event.inputs.runner != 'fast' }} if: ${{ github.event.inputs.runner != 'fast' }}
# Some runners lack /opt/hostedtoolcache, which setup-qemu expects # BuildJet runners lack /opt/hostedtoolcache, which setup-qemu expects
- name: Ensure hostedtoolcache exists - name: Ensure hostedtoolcache exists
run: sudo mkdir -p /opt/hostedtoolcache && sudo chown $USER:$USER /opt/hostedtoolcache run: sudo mkdir -p /opt/hostedtoolcache && sudo chown $USER:$USER /opt/hostedtoolcache
- name: Set up docker QEMU - name: Set up docker QEMU
uses: docker/setup-qemu-action@v4 uses: docker/setup-qemu-action@v3
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Download compiled artifacts - name: Download compiled artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v4
with: with:
name: compiled-${{ env.ARCH }}.tar name: compiled-${{ env.ARCH }}.tar
@@ -252,124 +238,19 @@ jobs:
run: PLATFORM=${{ matrix.platform }} make img run: PLATFORM=${{ matrix.platform }} make img
if: ${{ matrix.platform == 'raspberrypi' }} if: ${{ matrix.platform == 'raspberrypi' }}
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.platform }}.squashfs name: ${{ matrix.platform }}.squashfs
path: results/*.squashfs path: results/*.squashfs
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.platform }}.iso name: ${{ matrix.platform }}.iso
path: results/*.iso path: results/*.iso
if: ${{ matrix.platform != 'raspberrypi' }} if: ${{ matrix.platform != 'raspberrypi' }}
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.platform }}.img name: ${{ matrix.platform }}.img
path: results/*.img path: results/*.img
if: ${{ matrix.platform == 'raspberrypi' }} if: ${{ matrix.platform == 'raspberrypi' }}
deploy:
name: Deploy
needs: [image]
if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy != 'NONE'
runs-on: ubuntu-latest
env:
REGISTRY: >-
${{
fromJson('{
"alpha": "https://alpha-registry-x.start9.com",
"beta": "https://beta-registry.start9.com"
}')[github.event.inputs.deploy]
}}
S3_BUCKET: s3://startos-images
S3_CDN: https://startos-images.nyc3.cdn.digitaloceanspaces.com
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: web/package.json
- name: Determine version
id: version
run: |
VERSION=$(sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' web/package.json | head -1)
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Version: $VERSION"
- name: Download squashfs artifacts
uses: actions/download-artifact@v8
with:
pattern: "*.squashfs"
path: artifacts/
merge-multiple: true
- name: Download ISO artifacts
uses: actions/download-artifact@v8
with:
pattern: "*.iso"
path: artifacts/
merge-multiple: true
- name: Install start-cli
run: |
ARCH=$(uname -m)
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ASSET_NAME="start-cli_${ARCH}-${OS}"
DOWNLOAD_URL=$(curl -fsS \
-H "Authorization: token ${{ github.token }}" \
https://api.github.com/repos/Start9Labs/start-os/releases \
| jq -r '[.[].assets[] | select(.name=="'"$ASSET_NAME"'")] | first | .browser_download_url')
curl -fsSL \
-H "Authorization: token ${{ github.token }}" \
-H "Accept: application/octet-stream" \
"$DOWNLOAD_URL" -o /tmp/start-cli
sudo install -m 755 /tmp/start-cli /usr/local/bin/start-cli
echo "start-cli: $(start-cli --version)"
- name: Configure S3
run: |
sudo apt-get install -y -qq s3cmd > /dev/null
cat > ~/.s3cfg <<EOF
[default]
access_key = ${{ secrets.S3_ACCESS_KEY }}
secret_key = ${{ secrets.S3_SECRET_KEY }}
host_base = nyc3.digitaloceanspaces.com
host_bucket = %(bucket)s.nyc3.digitaloceanspaces.com
use_https = True
EOF
- name: Set up developer key
run: |
mkdir -p ~/.startos
printf '%s' "${{ secrets.DEV_KEY }}" > ~/.startos/developer.key.pem
- name: Upload to S3
run: |
VERSION="${{ steps.version.outputs.version }}"
cd artifacts
for file in *.iso *.squashfs; do
[ -f "$file" ] || continue
echo "Uploading $file..."
s3cmd put -P "$file" "${{ env.S3_BUCKET }}/v${VERSION}/$file"
done
- name: Register OS version
run: |
VERSION="${{ steps.version.outputs.version }}"
start-cli --registry="${{ env.REGISTRY }}" registry os version add \
"$VERSION" "v${VERSION}" '' ">=0.3.5 <=${VERSION}"
- name: Index assets in registry
run: |
VERSION="${{ steps.version.outputs.version }}"
cd artifacts
for file in *.squashfs *.iso; do
[ -f "$file" ] || continue
PLATFORM=$(echo "$file" | sed 's/.*_\([^.]*\)\.\(squashfs\|iso\)$/\1/')
echo "Indexing $file for platform $PLATFORM..."
start-cli --registry="${{ env.REGISTRY }}" registry os asset add \
--platform="$PLATFORM" \
--version="$VERSION" \
"$file" \
"${{ env.S3_CDN }}/v${VERSION}/$file"
done

View File

@@ -24,7 +24,7 @@ jobs:
if: github.event.pull_request.draft != true if: github.event.pull_request.draft != true
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: ./.github/actions/setup-build - uses: ./.github/actions/setup-build

2
.gitignore vendored
View File

@@ -22,5 +22,3 @@ secrets.db
tmp tmp
web/.i18n-checked web/.i18n-checked
docs/USER.md docs/USER.md
*.s9pk
/build/lib/migration-images

View File

@@ -5,7 +5,7 @@ StartOS is an open-source Linux distribution for running personal servers. It ma
## Tech Stack ## Tech Stack
- Backend: Rust (async/Tokio, Axum web framework) - Backend: Rust (async/Tokio, Axum web framework)
- Frontend: Angular 21 + TypeScript + Taiga UI 5 - Frontend: Angular 20 + TypeScript + TaigaUI
- Container runtime: Node.js/TypeScript with LXC - Container runtime: Node.js/TypeScript with LXC
- Database/State: Patch-DB (git submodule) - storage layer with reactive frontend sync - Database/State: Patch-DB (git submodule) - storage layer with reactive frontend sync
- API: JSON-RPC via rpc-toolkit (see `core/rpc-toolkit.md`) - API: JSON-RPC via rpc-toolkit (see `core/rpc-toolkit.md`)
@@ -30,7 +30,7 @@ StartOS is an open-source Linux distribution for running personal servers. It ma
- **`core/`** — Rust backend daemon. Produces a single binary `startbox` that is symlinked as `startd` (main daemon), `start-cli` (CLI), `start-container` (runs inside LXC containers), `registrybox` (package registry), and `tunnelbox` (VPN/tunnel). Handles all backend logic: RPC API, service lifecycle, networking (DNS, ACME, WiFi, Tor, WireGuard), backups, and database state management. See [core/ARCHITECTURE.md](core/ARCHITECTURE.md). - **`core/`** — Rust backend daemon. Produces a single binary `startbox` that is symlinked as `startd` (main daemon), `start-cli` (CLI), `start-container` (runs inside LXC containers), `registrybox` (package registry), and `tunnelbox` (VPN/tunnel). Handles all backend logic: RPC API, service lifecycle, networking (DNS, ACME, WiFi, Tor, WireGuard), backups, and database state management. See [core/ARCHITECTURE.md](core/ARCHITECTURE.md).
- **`web/`** — Angular 21 + TypeScript workspace using Taiga UI 5. Contains three applications (admin UI, setup wizard, VPN management) and two shared libraries (common components/services, marketplace). Communicates with the backend exclusively via JSON-RPC. See [web/ARCHITECTURE.md](web/ARCHITECTURE.md). - **`web/`** — Angular 20 + TypeScript workspace using Taiga UI. Contains three applications (admin UI, setup wizard, VPN management) and two shared libraries (common components/services, marketplace). Communicates with the backend exclusively via JSON-RPC. See [web/ARCHITECTURE.md](web/ARCHITECTURE.md).
- **`container-runtime/`** — Node.js runtime that runs inside each service's LXC container. Loads the service's JavaScript from its S9PK package and manages subcontainers. Communicates with the host daemon via JSON-RPC over Unix socket. See [container-runtime/CLAUDE.md](container-runtime/CLAUDE.md). - **`container-runtime/`** — Node.js runtime that runs inside each service's LXC container. Loads the service's JavaScript from its S9PK package and manages subcontainers. Communicates with the host daemon via JSON-RPC over Unix socket. See [container-runtime/CLAUDE.md](container-runtime/CLAUDE.md).

View File

@@ -11,14 +11,12 @@ Each major component has its own `CLAUDE.md` with detailed guidance: `core/`, `w
## Build & Development ## Build & Development
See [CONTRIBUTING.md](CONTRIBUTING.md) for: See [CONTRIBUTING.md](CONTRIBUTING.md) for:
- Environment setup and requirements - Environment setup and requirements
- Build commands and make targets - Build commands and make targets
- Testing and formatting commands - Testing and formatting commands
- Environment variables - Environment variables
**Quick reference:** **Quick reference:**
```bash ```bash
. ./devmode.sh # Enable dev mode . ./devmode.sh # Enable dev mode
make update-startbox REMOTE=start9@<ip> # Fastest iteration (binary + UI) make update-startbox REMOTE=start9@<ip> # Fastest iteration (binary + UI)
@@ -30,8 +28,6 @@ make test-core # Run Rust tests
- Always verify cross-layer changes using the order described in [ARCHITECTURE.md](ARCHITECTURE.md#cross-layer-verification) - Always verify cross-layer changes using the order described in [ARCHITECTURE.md](ARCHITECTURE.md#cross-layer-verification)
- Check component-level CLAUDE.md files for component-specific conventions. ALWAYS read it before operating on that component. - Check component-level CLAUDE.md files for component-specific conventions. ALWAYS read it before operating on that component.
- Follow existing patterns before inventing new ones - Follow existing patterns before inventing new ones
- Always use `make` recipes when they exist for testing builds rather than manually invoking build commands
- **Commit signing:** Never push unsigned commits. Before pushing, check all unpushed commits for signatures with `git log --show-signature @{upstream}..HEAD`. If any are unsigned, prompt the user to sign them with `git rebase --exec 'git commit --amend -S --no-edit' @{upstream}`.
## Supplementary Documentation ## Supplementary Documentation

View File

@@ -7,7 +7,7 @@ GIT_HASH_FILE := $(shell ./build/env/check-git-hash.sh)
VERSION_FILE := $(shell ./build/env/check-version.sh) VERSION_FILE := $(shell ./build/env/check-version.sh)
BASENAME := $(shell PROJECT=startos ./build/env/basename.sh) BASENAME := $(shell PROJECT=startos ./build/env/basename.sh)
PLATFORM := $(shell if [ -f $(PLATFORM_FILE) ]; then cat $(PLATFORM_FILE); else echo unknown; fi) PLATFORM := $(shell if [ -f $(PLATFORM_FILE) ]; then cat $(PLATFORM_FILE); else echo unknown; fi)
ARCH := $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo aarch64; elif [ "$(PLATFORM)" = "rockchip64" ]; then echo aarch64; else echo $(PLATFORM) | sed 's/-nonfree$$//g; s/-nvidia$$//g'; fi) ARCH := $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo aarch64; else echo $(PLATFORM) | sed 's/-nonfree$$//g'; fi)
RUST_ARCH := $(shell if [ "$(ARCH)" = "riscv64" ]; then echo riscv64gc; else echo $(ARCH); fi) RUST_ARCH := $(shell if [ "$(ARCH)" = "riscv64" ]; then echo riscv64gc; else echo $(ARCH); fi)
REGISTRY_BASENAME := $(shell PROJECT=start-registry PLATFORM=$(ARCH) ./build/env/basename.sh) REGISTRY_BASENAME := $(shell PROJECT=start-registry PLATFORM=$(ARCH) ./build/env/basename.sh)
TUNNEL_BASENAME := $(shell PROJECT=start-tunnel PLATFORM=$(ARCH) ./build/env/basename.sh) TUNNEL_BASENAME := $(shell PROJECT=start-tunnel PLATFORM=$(ARCH) ./build/env/basename.sh)
@@ -15,7 +15,7 @@ IMAGE_TYPE=$(shell if [ "$(PLATFORM)" = raspberrypi ]; then echo img; else echo
WEB_UIS := web/dist/raw/ui/index.html web/dist/raw/setup-wizard/index.html WEB_UIS := web/dist/raw/ui/index.html web/dist/raw/setup-wizard/index.html
COMPRESSED_WEB_UIS := web/dist/static/ui/index.html web/dist/static/setup-wizard/index.html COMPRESSED_WEB_UIS := web/dist/static/ui/index.html web/dist/static/setup-wizard/index.html
FIRMWARE_ROMS := build/lib/firmware/$(PLATFORM) $(shell jq --raw-output '.[] | select(.platform[] | contains("$(PLATFORM)")) | "./build/lib/firmware/$(PLATFORM)/" + .id + ".rom.gz"' build/lib/firmware.json) FIRMWARE_ROMS := build/lib/firmware/$(PLATFORM) $(shell jq --raw-output '.[] | select(.platform[] | contains("$(PLATFORM)")) | "./build/lib/firmware/$(PLATFORM)/" + .id + ".rom.gz"' build/lib/firmware.json)
BUILD_SRC := $(call ls-files, build/lib) build/lib/depends build/lib/conflicts $(FIRMWARE_ROMS) build/lib/migration-images/.done BUILD_SRC := $(call ls-files, build/lib) build/lib/depends build/lib/conflicts $(FIRMWARE_ROMS)
IMAGE_RECIPE_SRC := $(call ls-files, build/image-recipe/) IMAGE_RECIPE_SRC := $(call ls-files, build/image-recipe/)
STARTD_SRC := core/startd.service $(BUILD_SRC) STARTD_SRC := core/startd.service $(BUILD_SRC)
CORE_SRC := $(call ls-files, core) $(shell git ls-files --recurse-submodules patch-db) $(GIT_HASH_FILE) CORE_SRC := $(call ls-files, core) $(shell git ls-files --recurse-submodules patch-db) $(GIT_HASH_FILE)
@@ -89,7 +89,6 @@ clean:
rm -rf container-runtime/node_modules rm -rf container-runtime/node_modules
rm -f container-runtime/*.squashfs rm -f container-runtime/*.squashfs
(cd sdk && make clean) (cd sdk && make clean)
rm -rf build/lib/migration-images
rm -f env/*.txt rm -f env/*.txt
format: format:
@@ -106,10 +105,6 @@ test-sdk: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts
test-container-runtime: container-runtime/node_modules/.package-lock.json $(call ls-files, container-runtime/src) container-runtime/package.json container-runtime/tsconfig.json test-container-runtime: container-runtime/node_modules/.package-lock.json $(call ls-files, container-runtime/src) container-runtime/package.json container-runtime/tsconfig.json
cd container-runtime && npm test cd container-runtime && npm test
build/lib/migration-images/.done: build/save-migration-images.sh
ARCH=$(ARCH) ./build/save-migration-images.sh build/lib/migration-images
touch $@
install-cli: $(GIT_HASH_FILE) install-cli: $(GIT_HASH_FILE)
./core/build/build-cli.sh --install ./core/build/build-cli.sh --install
@@ -160,7 +155,7 @@ results/$(BASENAME).deb: debian/dpkg-build.sh $(call ls-files,debian/startos) $(
registry-deb: results/$(REGISTRY_BASENAME).deb registry-deb: results/$(REGISTRY_BASENAME).deb
results/$(REGISTRY_BASENAME).deb: debian/dpkg-build.sh $(call ls-files,debian/start-registry) $(REGISTRY_TARGETS) results/$(REGISTRY_BASENAME).deb: debian/dpkg-build.sh $(call ls-files,debian/start-registry) $(REGISTRY_TARGETS)
PROJECT=start-registry PLATFORM=$(ARCH) REQUIRES=debian DEPENDS=ca-certificates ./build/os-compat/run-compat.sh ./debian/dpkg-build.sh PROJECT=start-registry PLATFORM=$(ARCH) REQUIRES=debian ./build/os-compat/run-compat.sh ./debian/dpkg-build.sh
tunnel-deb: results/$(TUNNEL_BASENAME).deb tunnel-deb: results/$(TUNNEL_BASENAME).deb
@@ -193,9 +188,6 @@ install: $(STARTOS_TARGETS)
$(call mkdir,$(DESTDIR)/lib/systemd/system) $(call mkdir,$(DESTDIR)/lib/systemd/system)
$(call cp,core/startd.service,$(DESTDIR)/lib/systemd/system/startd.service) $(call cp,core/startd.service,$(DESTDIR)/lib/systemd/system/startd.service)
if /bin/bash -c '[[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]'; then \
sed -i '/^Environment=/a Environment=RUST_BACKTRACE=full' $(DESTDIR)/lib/systemd/system/startd.service; \
fi
$(call mkdir,$(DESTDIR)/usr/lib) $(call mkdir,$(DESTDIR)/usr/lib)
$(call rm,$(DESTDIR)/usr/lib/startos) $(call rm,$(DESTDIR)/usr/lib/startos)
@@ -255,10 +247,10 @@ update-deb: results/$(BASENAME).deb # better than update, but only available fro
update-squashfs: results/$(BASENAME).squashfs update-squashfs: results/$(BASENAME).squashfs
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs | head -c 32)) $(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs))
$(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}')) $(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}'))
$(call ssh,'sudo /usr/lib/startos/scripts/prune-images $(SQFS_SIZE)') $(call ssh,'/usr/lib/startos/scripts/prune-images $(SQFS_SIZE)')
$(call ssh,'sudo /usr/lib/startos/scripts/prune-boot') $(call ssh,'/usr/lib/startos/scripts/prune-boot')
$(call cp,results/$(BASENAME).squashfs,/media/startos/images/next.rootfs) $(call cp,results/$(BASENAME).squashfs,/media/startos/images/next.rootfs)
$(call ssh,'sudo CHECKSUM=$(SQFS_SUM) /usr/lib/startos/scripts/upgrade /media/startos/images/next.rootfs') $(call ssh,'sudo CHECKSUM=$(SQFS_SUM) /usr/lib/startos/scripts/upgrade /media/startos/images/next.rootfs')
@@ -291,10 +283,6 @@ core/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
rm -rf core/bindings rm -rf core/bindings
./core/build/build-ts.sh ./core/build/build-ts.sh
ls core/bindings/*.ts | sed 's/core\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/bindings/index.ts ls core/bindings/*.ts | sed 's/core\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/bindings/index.ts
if [ -d core/bindings/tunnel ]; then \
ls core/bindings/tunnel/*.ts | sed 's/core\/bindings\/tunnel\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' > core/bindings/tunnel/index.ts; \
echo 'export * as Tunnel from "./tunnel";' >> core/bindings/index.ts; \
fi
npm --prefix sdk/base exec -- prettier --config=./sdk/base/package.json -w './core/bindings/**/*.ts' npm --prefix sdk/base exec -- prettier --config=./sdk/base/package.json -w './core/bindings/**/*.ts'
touch core/bindings/index.ts touch core/bindings/index.ts

View File

@@ -52,7 +52,7 @@ The easiest path. [Buy a server](https://store.start9.com) from Start9 and plug
### Build your own ### Build your own
Follow the [install guide](https://docs.start9.com/start-os/installing.html) to install StartOS on your own hardware. . Reasons to go this route: Install StartOS on your own hardware. Follow one of the [DIY guides](https://start9.com/latest/diy). Reasons to go this route:
1. You already have compatible hardware 1. You already have compatible hardware
2. You want to save on shipping costs 2. You want to save on shipping costs

View File

@@ -23,7 +23,6 @@ fi
BUCKET="${S3_BUCKET:-start9-debs}" BUCKET="${S3_BUCKET:-start9-debs}"
ENDPOINT="${S3_ENDPOINT:-https://nyc3.digitaloceanspaces.com}" ENDPOINT="${S3_ENDPOINT:-https://nyc3.digitaloceanspaces.com}"
GPG_KEY_ID="${GPG_KEY_ID:-5259ADFC2D63C217}"
SUITE="${SUITE:-stable}" SUITE="${SUITE:-stable}"
COMPONENT="${COMPONENT:-main}" COMPONENT="${COMPONENT:-main}"
REPO_DIR="$(mktemp -d)" REPO_DIR="$(mktemp -d)"
@@ -99,7 +98,7 @@ for arch in amd64 arm64 riscv64; do
mkdir -p "$BINARY_DIR" mkdir -p "$BINARY_DIR"
( (
cd "$REPO_DIR" cd "$REPO_DIR"
dpkg-scanpackages --multiversion --arch "$arch" pool/ > "$BINARY_DIR/Packages" dpkg-scanpackages --arch "$arch" pool/ > "$BINARY_DIR/Packages"
gzip -k -f "$BINARY_DIR/Packages" gzip -k -f "$BINARY_DIR/Packages"
) )
echo "Generated Packages index for ${arch}" echo "Generated Packages index for ${arch}"

View File

@@ -11,7 +11,6 @@ cifs-utils
conntrack conntrack
cryptsetup cryptsetup
curl curl
dkms
dmidecode dmidecode
dnsutils dnsutils
dosfstools dosfstools
@@ -37,7 +36,6 @@ lvm2
lxc lxc
magic-wormhole magic-wormhole
man-db man-db
mokutil
ncdu ncdu
net-tools net-tools
network-manager network-manager

View File

@@ -12,10 +12,6 @@ fi
if [[ "$PLATFORM" =~ -nonfree$ ]]; then if [[ "$PLATFORM" =~ -nonfree$ ]]; then
FEATURES+=("nonfree") FEATURES+=("nonfree")
fi fi
if [[ "$PLATFORM" =~ -nvidia$ ]]; then
FEATURES+=("nonfree")
FEATURES+=("nvidia")
fi
feature_file_checker=' feature_file_checker='
/^#/ { next } /^#/ { next }

View File

@@ -4,4 +4,7 @@
+ firmware-iwlwifi + firmware-iwlwifi
+ firmware-libertas + firmware-libertas
+ firmware-misc-nonfree + firmware-misc-nonfree
+ firmware-realtek + firmware-realtek
+ nvidia-container-toolkit
# + nvidia-driver
# + nvidia-kernel-dkms

View File

@@ -1 +0,0 @@
+ nvidia-container-toolkit

View File

@@ -1,6 +1,5 @@
+ gdisk - grub-efi
+ parted + parted
+ u-boot-rpi
+ raspberrypi-net-mods + raspberrypi-net-mods
+ raspberrypi-sys-mods + raspberrypi-sys-mods
+ raspi-config + raspi-config

View File

@@ -23,8 +23,6 @@ RUN apt-get update && \
squashfs-tools \ squashfs-tools \
rsync \ rsync \
b3sum \ b3sum \
btrfs-progs \
gdisk \
dpkg-dev dpkg-dev

View File

@@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
set -e set -e
MAX_IMG_LEN=$((4 * 1024 * 1024 * 1024)) # 4GB
echo "==== StartOS Image Build ====" echo "==== StartOS Image Build ===="
@@ -33,11 +34,11 @@ fi
IMAGE_BASENAME=startos-${VERSION_FULL}_${IB_TARGET_PLATFORM} IMAGE_BASENAME=startos-${VERSION_FULL}_${IB_TARGET_PLATFORM}
BOOTLOADERS=grub-efi BOOTLOADERS=grub-efi
if [ "$IB_TARGET_PLATFORM" = "x86_64" ] || [ "$IB_TARGET_PLATFORM" = "x86_64-nonfree" ] || [ "$IB_TARGET_PLATFORM" = "x86_64-nvidia" ]; then if [ "$IB_TARGET_PLATFORM" = "x86_64" ] || [ "$IB_TARGET_PLATFORM" = "x86_64-nonfree" ]; then
IB_TARGET_ARCH=amd64 IB_TARGET_ARCH=amd64
QEMU_ARCH=x86_64 QEMU_ARCH=x86_64
BOOTLOADERS=grub-efi,syslinux BOOTLOADERS=grub-efi,syslinux
elif [ "$IB_TARGET_PLATFORM" = "aarch64" ] || [ "$IB_TARGET_PLATFORM" = "aarch64-nonfree" ] || [ "$IB_TARGET_PLATFORM" = "aarch64-nvidia" ] || [ "$IB_TARGET_PLATFORM" = "raspberrypi" ] || [ "$IB_TARGET_PLATFORM" = "rockchip64" ]; then elif [ "$IB_TARGET_PLATFORM" = "aarch64" ] || [ "$IB_TARGET_PLATFORM" = "aarch64-nonfree" ] || [ "$IB_TARGET_PLATFORM" = "raspberrypi" ] || [ "$IB_TARGET_PLATFORM" = "rockchip64" ]; then
IB_TARGET_ARCH=arm64 IB_TARGET_ARCH=arm64
QEMU_ARCH=aarch64 QEMU_ARCH=aarch64
elif [ "$IB_TARGET_PLATFORM" = "riscv64" ] || [ "$IB_TARGET_PLATFORM" = "riscv64-nonfree" ]; then elif [ "$IB_TARGET_PLATFORM" = "riscv64" ] || [ "$IB_TARGET_PLATFORM" = "riscv64-nonfree" ]; then
@@ -59,13 +60,9 @@ mkdir -p $prep_results_dir
cd $prep_results_dir cd $prep_results_dir
NON_FREE= NON_FREE=
if [[ "${IB_TARGET_PLATFORM}" =~ -nonfree$ ]] || [[ "${IB_TARGET_PLATFORM}" =~ -nvidia$ ]] || [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then if [[ "${IB_TARGET_PLATFORM}" =~ -nonfree$ ]] || [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
NON_FREE=1 NON_FREE=1
fi fi
NVIDIA=
if [[ "${IB_TARGET_PLATFORM}" =~ -nvidia$ ]]; then
NVIDIA=1
fi
IMAGE_TYPE=iso IMAGE_TYPE=iso
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ] || [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ] || [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
IMAGE_TYPE=img IMAGE_TYPE=img
@@ -104,7 +101,7 @@ lb config \
--iso-preparer "START9 LABS; HTTPS://START9.COM" \ --iso-preparer "START9 LABS; HTTPS://START9.COM" \
--iso-publisher "START9 LABS; HTTPS://START9.COM" \ --iso-publisher "START9 LABS; HTTPS://START9.COM" \
--backports true \ --backports true \
--bootappend-live "boot=live noautologin console=tty0" \ --bootappend-live "boot=live noautologin" \
--bootloaders $BOOTLOADERS \ --bootloaders $BOOTLOADERS \
--cache false \ --cache false \
--mirror-bootstrap "https://deb.debian.org/debian/" \ --mirror-bootstrap "https://deb.debian.org/debian/" \
@@ -131,15 +128,6 @@ ff02::1 ip6-allnodes
ff02::2 ip6-allrouters ff02::2 ip6-allrouters
EOT EOT
if [[ "${IB_OS_ENV}" =~ (^|-)dev($|-) ]]; then
mkdir -p config/includes.chroot/etc/ssh/sshd_config.d
echo "PasswordAuthentication yes" > config/includes.chroot/etc/ssh/sshd_config.d/dev-password-auth.conf
fi
# Installer marker file (used by installed GRUB to detect the live USB)
mkdir -p config/includes.binary
touch config/includes.binary/.startos-installer
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
mkdir -p config/includes.chroot mkdir -p config/includes.chroot
git clone --depth=1 --branch=stable https://github.com/raspberrypi/rpi-firmware.git config/includes.chroot/boot git clone --depth=1 --branch=stable https://github.com/raspberrypi/rpi-firmware.git config/includes.chroot/boot
@@ -180,13 +168,7 @@ sed -i -e '2i set timeout=5' config/bootloaders/grub-pc/config.cfg
mkdir -p config/archives mkdir -p config/archives
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
# Fetch the keyring package (not the old raspberrypi.gpg.key, which has curl -fsSL https://archive.raspberrypi.com/debian/raspberrypi.gpg.key | gpg --dearmor -o config/archives/raspi.key
# SHA1-only binding signatures that sqv on Trixie rejects).
KEYRING_DEB=$(mktemp)
curl -fsSL -o "$KEYRING_DEB" https://archive.raspberrypi.com/debian/pool/main/r/raspberrypi-archive-keyring/raspberrypi-archive-keyring_2025.1+rpt1_all.deb
dpkg-deb -x "$KEYRING_DEB" "$KEYRING_DEB.d"
cp "$KEYRING_DEB.d/usr/share/keyrings/raspberrypi-archive-keyring.gpg" config/archives/raspi.key
rm -rf "$KEYRING_DEB" "$KEYRING_DEB.d"
echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/raspi.key.gpg] https://archive.raspberrypi.com/debian/ ${IB_SUITE} main" > config/archives/raspi.list echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/raspi.key.gpg] https://archive.raspberrypi.com/debian/ ${IB_SUITE} main" > config/archives/raspi.list
fi fi
@@ -195,7 +177,7 @@ if [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
echo "deb https://apt.armbian.com/ ${IB_SUITE} main" > config/archives/armbian.list echo "deb https://apt.armbian.com/ ${IB_SUITE} main" > config/archives/armbian.list
fi fi
if [ "$NVIDIA" = 1 ]; then if [ "$NON_FREE" = 1 ]; then
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o config/archives/nvidia-container-toolkit.key curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o config/archives/nvidia-container-toolkit.key
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \ curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/etc/apt/trusted.gpg.d/nvidia-container-toolkit.key.gpg] https://#g' \ | sed 's#deb https://#deb [signed-by=/etc/apt/trusted.gpg.d/nvidia-container-toolkit.key.gpg] https://#g' \
@@ -223,15 +205,11 @@ cat > config/hooks/normal/9000-install-startos.hook.chroot << EOF
set -e set -e
if [ "${IB_TARGET_PLATFORM}" != "raspberrypi" ]; then if [ "${NON_FREE}" = "1" ] && [ "${IB_TARGET_PLATFORM}" != "raspberrypi" ] && [ "${IB_TARGET_PLATFORM}" != "riscv64-nonfree" ]; then
/usr/lib/startos/scripts/enable-kiosk
fi
if [ "${NVIDIA}" = "1" ]; then
# install a specific NVIDIA driver version # install a specific NVIDIA driver version
# ---------------- configuration ---------------- # ---------------- configuration ----------------
NVIDIA_DRIVER_VERSION="\${NVIDIA_DRIVER_VERSION:-580.126.09}" NVIDIA_DRIVER_VERSION="\${NVIDIA_DRIVER_VERSION:-580.119.02}"
BASE_URL="https://download.nvidia.com/XFree86/Linux-${QEMU_ARCH}" BASE_URL="https://download.nvidia.com/XFree86/Linux-${QEMU_ARCH}"
@@ -254,7 +232,7 @@ if [ "${NVIDIA}" = "1" ]; then
echo "[nvidia-hook] Target kernel version: \${KVER}" >&2 echo "[nvidia-hook] Target kernel version: \${KVER}" >&2
# Ensure kernel headers are present # Ensure kernel headers are present
TEMP_APT_DEPS=(build-essential pkg-config) TEMP_APT_DEPS=(build-essential)
if [ ! -e "/lib/modules/\${KVER}/build" ]; then if [ ! -e "/lib/modules/\${KVER}/build" ]; then
TEMP_APT_DEPS+=(linux-headers-\${KVER}) TEMP_APT_DEPS+=(linux-headers-\${KVER})
fi fi
@@ -281,15 +259,12 @@ if [ "${NVIDIA}" = "1" ]; then
echo "[nvidia-hook] Running NVIDIA installer for kernel \${KVER}" >&2 echo "[nvidia-hook] Running NVIDIA installer for kernel \${KVER}" >&2
if ! sh "\${RUN_PATH}" \ sh "\${RUN_PATH}" \
--silent \ --silent \
--kernel-name="\${KVER}" \ --kernel-name="\${KVER}" \
--no-x-check \ --no-x-check \
--no-nouveau-check \ --no-nouveau-check \
--no-runlevel-check; then --no-runlevel-check
cat /var/log/nvidia-installer.log
exit 1
fi
# Rebuild module metadata # Rebuild module metadata
echo "[nvidia-hook] Running depmod for \${KVER}" >&2 echo "[nvidia-hook] Running depmod for \${KVER}" >&2
@@ -297,32 +272,12 @@ if [ "${NVIDIA}" = "1" ]; then
echo "[nvidia-hook] NVIDIA \${NVIDIA_DRIVER_VERSION} installation complete for kernel \${KVER}" >&2 echo "[nvidia-hook] NVIDIA \${NVIDIA_DRIVER_VERSION} installation complete for kernel \${KVER}" >&2
echo "[nvidia-hook] Removing .run installer..." >&2
rm -f "\${RUN_PATH}"
echo "[nvidia-hook] Blacklisting nouveau..." >&2
echo "blacklist nouveau" > /etc/modprobe.d/blacklist-nouveau.conf
echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf
echo "[nvidia-hook] Rebuilding initramfs..." >&2
update-initramfs -u -k "\${KVER}"
echo "[nvidia-hook] Removing build dependencies..." >&2 echo "[nvidia-hook] Removing build dependencies..." >&2
apt-get purge -y nvidia-depends apt-get purge -y nvidia-depends
apt-get autoremove -y apt-get autoremove -y
echo "[nvidia-hook] Removed build dependencies." >&2 echo "[nvidia-hook] Removed build dependencies." >&2
fi fi
# Install linux-kbuild for sign-file (Secure Boot module signing)
KVER_ALL="\$(ls -1t /boot/vmlinuz-* 2>/dev/null | head -n1 | sed 's|.*/vmlinuz-||')"
if [ -n "\${KVER_ALL}" ]; then
KBUILD_VER="\$(echo "\${KVER_ALL}" | grep -oP '^\d+\.\d+')"
if [ -n "\${KBUILD_VER}" ]; then
echo "[build] Installing linux-kbuild-\${KBUILD_VER} for Secure Boot support" >&2
apt-get install -y "linux-kbuild-\${KBUILD_VER}" || echo "[build] WARNING: linux-kbuild-\${KBUILD_VER} not available" >&2
fi
fi
cp /etc/resolv.conf /etc/resolv.conf.bak cp /etc/resolv.conf /etc/resolv.conf.bak
if [ "${IB_SUITE}" = trixie ] && [ "${IB_TARGET_ARCH}" != riscv64 ]; then if [ "${IB_SUITE}" = trixie ] && [ "${IB_TARGET_ARCH}" != riscv64 ]; then
@@ -336,10 +291,9 @@ fi
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
ln -sf /usr/bin/pi-beep /usr/local/bin/beep ln -sf /usr/bin/pi-beep /usr/local/bin/beep
sh /boot/firmware/config.sh > /boot/firmware/config.txt KERNEL_VERSION=${RPI_KERNEL_VERSION} sh /boot/config.sh > /boot/config.txt
mkinitramfs -c gzip -o /boot/initrd.img-${RPI_KERNEL_VERSION}-rpi-v8 ${RPI_KERNEL_VERSION}-rpi-v8 mkinitramfs -c gzip -o /boot/initrd.img-${RPI_KERNEL_VERSION}-rpi-v8 ${RPI_KERNEL_VERSION}-rpi-v8
mkinitramfs -c gzip -o /boot/initrd.img-${RPI_KERNEL_VERSION}-rpi-2712 ${RPI_KERNEL_VERSION}-rpi-2712 mkinitramfs -c gzip -o /boot/initrd.img-${RPI_KERNEL_VERSION}-rpi-2712 ${RPI_KERNEL_VERSION}-rpi-2712
cp /usr/lib/u-boot/rpi_arm64/u-boot.bin /boot/firmware/u-boot.bin
fi fi
useradd --shell /bin/bash -G startos -m start9 useradd --shell /bin/bash -G startos -m start9
@@ -349,16 +303,14 @@ usermod -aG systemd-journal start9
echo "start9 ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee "/etc/sudoers.d/010_start9-nopasswd" echo "start9 ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee "/etc/sudoers.d/010_start9-nopasswd"
if [ "${IB_TARGET_PLATFORM}" != "raspberrypi" ]; then
/usr/lib/startos/scripts/enable-kiosk
fi
if ! [[ "${IB_OS_ENV}" =~ (^|-)dev($|-) ]]; then if ! [[ "${IB_OS_ENV}" =~ (^|-)dev($|-) ]]; then
passwd -l start9 passwd -l start9
fi fi
mkdir -p /media/startos
chmod 750 /media/startos
chown root:startos /media/startos
start-cli --registry=https://alpha-registry-x.start9.com registry package download tor -d /usr/lib/startos/tor_${QEMU_ARCH}.s9pk -a "${QEMU_ARCH}"
EOF EOF
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(date '+%s')}" SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(date '+%s')}"
@@ -411,85 +363,38 @@ if [ "${IMAGE_TYPE}" = iso ]; then
elif [ "${IMAGE_TYPE}" = img ]; then elif [ "${IMAGE_TYPE}" = img ]; then
SECTOR_LEN=512 SECTOR_LEN=512
FW_START=$((1024 * 1024)) # 1MiB (sector 2048) — Pi-specific BOOT_START=$((1024 * 1024)) # 1MiB
FW_LEN=$((128 * 1024 * 1024)) # 128MiB (Pi firmware + U-Boot + DTBs) BOOT_LEN=$((512 * 1024 * 1024)) # 512MiB
FW_END=$((FW_START + FW_LEN - 1))
ESP_START=$((FW_END + 1)) # 100MB EFI System Partition (matches os_install)
ESP_LEN=$((100 * 1024 * 1024))
ESP_END=$((ESP_START + ESP_LEN - 1))
BOOT_START=$((ESP_END + 1)) # 2GB /boot (matches os_install)
BOOT_LEN=$((2 * 1024 * 1024 * 1024))
BOOT_END=$((BOOT_START + BOOT_LEN - 1)) BOOT_END=$((BOOT_START + BOOT_LEN - 1))
ROOT_START=$((BOOT_END + 1)) ROOT_START=$((BOOT_END + 1))
ROOT_LEN=$((MAX_IMG_LEN - ROOT_START))
# Size root partition to fit the squashfs + 256MB overhead for btrfs ROOT_END=$((MAX_IMG_LEN - 1))
# metadata and config overlay, avoiding the need for btrfs resize
SQUASHFS_SIZE=$(stat -c %s $prep_results_dir/binary/live/filesystem.squashfs)
ROOT_LEN=$(( SQUASHFS_SIZE + 256 * 1024 * 1024 ))
# Align to sector boundary
ROOT_LEN=$(( (ROOT_LEN + SECTOR_LEN - 1) / SECTOR_LEN * SECTOR_LEN ))
# Total image: partitions + GPT backup header (34 sectors)
IMG_LEN=$((ROOT_START + ROOT_LEN + 34 * SECTOR_LEN))
# Fixed GPT partition UUIDs (deterministic, based on old MBR disk ID cb15ae4d)
FW_UUID=cb15ae4d-0001-4000-8000-000000000001
ESP_UUID=cb15ae4d-0002-4000-8000-000000000002
BOOT_UUID=cb15ae4d-0003-4000-8000-000000000003
ROOT_UUID=cb15ae4d-0004-4000-8000-000000000004
TARGET_NAME=$prep_results_dir/${IMAGE_BASENAME}.img TARGET_NAME=$prep_results_dir/${IMAGE_BASENAME}.img
truncate -s $IMG_LEN $TARGET_NAME truncate -s $MAX_IMG_LEN $TARGET_NAME
sfdisk $TARGET_NAME <<-EOF sfdisk $TARGET_NAME <<-EOF
label: gpt label: dos
label-id: 0xcb15ae4d
unit: sectors
sector-size: 512
${TARGET_NAME}1 : start=$((FW_START / SECTOR_LEN)), size=$((FW_LEN / SECTOR_LEN)), type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=${FW_UUID}, name="firmware" ${TARGET_NAME}1 : start=$((BOOT_START / SECTOR_LEN)), size=$((BOOT_LEN / SECTOR_LEN)), type=c, bootable
${TARGET_NAME}2 : start=$((ESP_START / SECTOR_LEN)), size=$((ESP_LEN / SECTOR_LEN)), type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=${ESP_UUID}, name="efi" ${TARGET_NAME}2 : start=$((ROOT_START / SECTOR_LEN)), size=$((ROOT_LEN / SECTOR_LEN)), type=83
${TARGET_NAME}3 : start=$((BOOT_START / SECTOR_LEN)), size=$((BOOT_LEN / SECTOR_LEN)), type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=${BOOT_UUID}, name="boot"
${TARGET_NAME}4 : start=$((ROOT_START / SECTOR_LEN)), size=$((ROOT_LEN / SECTOR_LEN)), type=B921B045-1DF0-41C3-AF44-4C6F280D3FAE, uuid=${ROOT_UUID}, name="root"
EOF EOF
# Create named loop device nodes (high minor numbers to avoid conflicts) BOOT_DEV=$(losetup --show -f --offset $BOOT_START --sizelimit $BOOT_LEN $TARGET_NAME)
# and detach any stale ones from previous failed builds ROOT_DEV=$(losetup --show -f --offset $ROOT_START --sizelimit $ROOT_LEN $TARGET_NAME)
FW_DEV=/dev/startos-loop-fw
ESP_DEV=/dev/startos-loop-esp
BOOT_DEV=/dev/startos-loop-boot
ROOT_DEV=/dev/startos-loop-root
for dev in $FW_DEV:200 $ESP_DEV:201 $BOOT_DEV:202 $ROOT_DEV:203; do
name=${dev%:*}
minor=${dev#*:}
[ -e $name ] || mknod $name b 7 $minor
losetup -d $name 2>/dev/null || true
done
losetup $FW_DEV --offset $FW_START --sizelimit $FW_LEN $TARGET_NAME mkfs.vfat -F32 $BOOT_DEV
losetup $ESP_DEV --offset $ESP_START --sizelimit $ESP_LEN $TARGET_NAME mkfs.ext4 $ROOT_DEV
losetup $BOOT_DEV --offset $BOOT_START --sizelimit $BOOT_LEN $TARGET_NAME
losetup $ROOT_DEV --offset $ROOT_START --sizelimit $ROOT_LEN $TARGET_NAME
mkfs.vfat -F32 -n firmware $FW_DEV
mkfs.vfat -F32 -n efi $ESP_DEV
mkfs.vfat -F32 -n boot $BOOT_DEV
mkfs.btrfs -f -L rootfs $ROOT_DEV
TMPDIR=$(mktemp -d) TMPDIR=$(mktemp -d)
# Extract boot files from squashfs to staging area
BOOT_STAGING=$(mktemp -d)
unsquashfs -n -f -d $BOOT_STAGING $prep_results_dir/binary/live/filesystem.squashfs boot
# Mount partitions (nested: firmware and efi inside boot)
mkdir -p $TMPDIR/boot $TMPDIR/root mkdir -p $TMPDIR/boot $TMPDIR/root
mount $BOOT_DEV $TMPDIR/boot
mkdir -p $TMPDIR/boot/firmware $TMPDIR/boot/efi
mount $FW_DEV $TMPDIR/boot/firmware
mount $ESP_DEV $TMPDIR/boot/efi
mount $ROOT_DEV $TMPDIR/root mount $ROOT_DEV $TMPDIR/root
mount $BOOT_DEV $TMPDIR/boot
# Copy boot files — nested mounts route firmware/* to the firmware partition unsquashfs -n -f -d $TMPDIR $prep_results_dir/binary/live/filesystem.squashfs boot
cp -a $BOOT_STAGING/boot/. $TMPDIR/boot/
rm -rf $BOOT_STAGING
mkdir $TMPDIR/root/images $TMPDIR/root/config mkdir $TMPDIR/root/images $TMPDIR/root/config
B3SUM=$(b3sum $prep_results_dir/binary/live/filesystem.squashfs | head -c 16) B3SUM=$(b3sum $prep_results_dir/binary/live/filesystem.squashfs | head -c 16)
@@ -502,46 +407,40 @@ elif [ "${IMAGE_TYPE}" = img ]; then
mount -t overlay -o lowerdir=$TMPDIR/lower,workdir=$TMPDIR/root/config/work,upperdir=$TMPDIR/root/config/overlay overlay $TMPDIR/next mount -t overlay -o lowerdir=$TMPDIR/lower,workdir=$TMPDIR/root/config/work,upperdir=$TMPDIR/root/config/overlay overlay $TMPDIR/next
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
sed -i 's| boot=startos| boot=startos init=/usr/lib/startos/scripts/init_resize\.sh|' $TMPDIR/boot/cmdline.txt
rsync -a $SOURCE_DIR/raspberrypi/img/ $TMPDIR/next/ rsync -a $SOURCE_DIR/raspberrypi/img/ $TMPDIR/next/
# Install GRUB: ESP at /boot/efi (Part 2), /boot (Part 3)
mkdir -p $TMPDIR/next/boot \
$TMPDIR/next/dev $TMPDIR/next/proc $TMPDIR/next/sys $TMPDIR/next/media/startos/root
mount --rbind $TMPDIR/boot $TMPDIR/next/boot
mount --bind /dev $TMPDIR/next/dev
mount -t proc proc $TMPDIR/next/proc
mount -t sysfs sysfs $TMPDIR/next/sys
mount --bind $TMPDIR/root $TMPDIR/next/media/startos/root
chroot $TMPDIR/next grub-install --target=arm64-efi --removable --efi-directory=/boot/efi --boot-directory=/boot --no-nvram
chroot $TMPDIR/next update-grub
umount $TMPDIR/next/media/startos/root
umount $TMPDIR/next/sys
umount $TMPDIR/next/proc
umount $TMPDIR/next/dev
umount -l $TMPDIR/next/boot
# Fix root= in grub.cfg: update-grub sees loop devices, but the
# real device uses a fixed GPT PARTUUID for root (Part 4).
sed -i "s|root=[^ ]*|root=PARTUUID=${ROOT_UUID}|g" $TMPDIR/boot/grub/grub.cfg
# Inject first-boot resize script into GRUB config
sed -i 's| boot=startos| boot=startos init=/usr/lib/startos/scripts/init_resize\.sh|' $TMPDIR/boot/grub/grub.cfg
fi fi
umount $TMPDIR/next umount $TMPDIR/next
umount $TMPDIR/lower umount $TMPDIR/lower
umount $TMPDIR/boot/firmware
umount $TMPDIR/boot/efi
umount $TMPDIR/boot umount $TMPDIR/boot
umount $TMPDIR/root umount $TMPDIR/root
e2fsck -fy $ROOT_DEV
resize2fs -M $ROOT_DEV
BLOCK_COUNT=$(dumpe2fs -h $ROOT_DEV | awk '/^Block count:/ { print $3 }')
BLOCK_SIZE=$(dumpe2fs -h $ROOT_DEV | awk '/^Block size:/ { print $3 }')
ROOT_LEN=$((BLOCK_COUNT * BLOCK_SIZE))
losetup -d $ROOT_DEV losetup -d $ROOT_DEV
losetup -d $BOOT_DEV losetup -d $BOOT_DEV
losetup -d $ESP_DEV
losetup -d $FW_DEV # Recreate partition 2 with the new size using sfdisk
sfdisk $TARGET_NAME <<-EOF
label: dos
label-id: 0xcb15ae4d
unit: sectors
sector-size: 512
${TARGET_NAME}1 : start=$((BOOT_START / SECTOR_LEN)), size=$((BOOT_LEN / SECTOR_LEN)), type=c, bootable
${TARGET_NAME}2 : start=$((ROOT_START / SECTOR_LEN)), size=$((ROOT_LEN / SECTOR_LEN)), type=83
EOF
TARGET_SIZE=$((ROOT_START + ROOT_LEN))
truncate -s $TARGET_SIZE $TARGET_NAME
mv $TARGET_NAME $RESULTS_DIR/$IMAGE_BASENAME.img mv $TARGET_NAME $RESULTS_DIR/$IMAGE_BASENAME.img

View File

@@ -1,4 +1,2 @@
PARTUUID=cb15ae4d-0001-4000-8000-000000000001 /boot/firmware vfat umask=0077 0 2 /dev/mmcblk0p1 /boot vfat umask=0077 0 2
PARTUUID=cb15ae4d-0002-4000-8000-000000000002 /boot/efi vfat umask=0077 0 1 /dev/mmcblk0p2 / ext4 defaults 0 1
PARTUUID=cb15ae4d-0003-4000-8000-000000000003 /boot vfat umask=0077 0 2
PARTUUID=cb15ae4d-0004-4000-8000-000000000004 / btrfs defaults 0 1

View File

@@ -12,16 +12,15 @@ get_variables () {
BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4) BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition") BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")
ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size") OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')
# GPT backup header/entries occupy last 33 sectors
USABLE_END=$((ROOT_DEV_SIZE - 34))
if [ "$USABLE_END" -le 67108864 ]; then ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
TARGET_END=$USABLE_END if [ "$ROOT_DEV_SIZE" -le 67108864 ]; then
TARGET_END=$((ROOT_DEV_SIZE - 1))
else else
TARGET_END=$((33554432 - 1)) TARGET_END=$((33554432 - 1))
DATA_PART_START=33554432 DATA_PART_START=33554432
DATA_PART_END=$USABLE_END DATA_PART_END=$((ROOT_DEV_SIZE - 1))
fi fi
PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's') PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')
@@ -58,30 +57,37 @@ check_variables () {
main () { main () {
get_variables get_variables
# Fix GPT backup header first — the image was built with a tight root
# partition, so the backup GPT is not at the end of the SD card. parted
# will prompt interactively if this isn't fixed before we use it.
sgdisk -e "$ROOT_DEV" 2>/dev/null || true
if ! check_variables; then if ! check_variables; then
return 1 return 1
fi fi
# if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
# reboot_pi
# fi
if ! echo Yes | parted -m --align=optimal "$ROOT_DEV" ---pretend-input-tty u s resizepart "$ROOT_PART_NUM" "$TARGET_END" ; then if ! echo Yes | parted -m --align=optimal "$ROOT_DEV" ---pretend-input-tty u s resizepart "$ROOT_PART_NUM" "$TARGET_END" ; then
FAIL_REASON="Root partition resize failed" FAIL_REASON="Root partition resize failed"
return 1 return 1
fi fi
if [ -n "$DATA_PART_START" ]; then if [ -n "$DATA_PART_START" ]; then
if ! parted -ms --align=optimal "$ROOT_DEV" u s mkpart data "$DATA_PART_START" "$DATA_PART_END"; then if ! parted -ms --align=optimal "$ROOT_DEV" u s mkpart primary "$DATA_PART_START" "$DATA_PART_END"; then
FAIL_REASON="Data partition creation failed" FAIL_REASON="Data partition creation failed"
return 1 return 1
fi fi
fi fi
(
echo x
echo i
echo "0xcb15ae4d"
echo r
echo w
) | fdisk $ROOT_DEV
mount / -o remount,rw mount / -o remount,rw
btrfs filesystem resize max /media/startos/root resize2fs $ROOT_PART_DEV
if ! systemd-machine-id-setup --root=/media/startos/config/overlay/; then if ! systemd-machine-id-setup --root=/media/startos/config/overlay/; then
FAIL_REASON="systemd-machine-id-setup failed" FAIL_REASON="systemd-machine-id-setup failed"
@@ -105,7 +111,7 @@ mount / -o remount,ro
beep beep
if main; then if main; then
sed -i 's| init=/usr/lib/startos/scripts/init_resize\.sh||' /boot/grub/grub.cfg sed -i 's| init=/usr/lib/startos/scripts/init_resize\.sh||' /boot/cmdline.txt
echo "Resized root filesystem. Rebooting in 5 seconds..." echo "Resized root filesystem. Rebooting in 5 seconds..."
sleep 5 sleep 5
else else

View File

@@ -0,0 +1 @@
usb-storage.quirks=152d:0562:u,14cd:121c:u,0781:cfcb:u console=serial0,115200 console=tty1 root=PARTUUID=cb15ae4d-02 rootfstype=ext4 fsck.repair=yes rootwait cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory boot=startos

View File

@@ -27,18 +27,20 @@ disable_overscan=1
# (e.g. for USB device mode) or if USB support is not required. # (e.g. for USB device mode) or if USB support is not required.
otg_mode=1 otg_mode=1
[all]
[pi4] [pi4]
# Run as fast as firmware / board allows # Run as fast as firmware / board allows
arm_boost=1 arm_boost=1
kernel=vmlinuz-${KERNEL_VERSION}-rpi-v8
initramfs initrd.img-${KERNEL_VERSION}-rpi-v8 followkernel
[pi5]
kernel=vmlinuz-${KERNEL_VERSION}-rpi-2712
initramfs initrd.img-${KERNEL_VERSION}-rpi-2712 followkernel
[all] [all]
gpu_mem=16 gpu_mem=16
dtoverlay=pwm-2chan,disable-bt dtoverlay=pwm-2chan,disable-bt
# Enable UART for U-Boot and serial console EOF
enable_uart=1
# Load U-Boot as the bootloader (GRUB is chainloaded from U-Boot)
kernel=u-boot.bin
EOF

View File

@@ -84,8 +84,4 @@ arm_boost=1
gpu_mem=16 gpu_mem=16
dtoverlay=pwm-2chan,disable-bt dtoverlay=pwm-2chan,disable-bt
# Enable UART for U-Boot and serial console auto_initramfs=1
enable_uart=1
# Load U-Boot as the bootloader (GRUB is chainloaded from U-Boot)
kernel=u-boot.bin

View File

@@ -1,4 +0,0 @@
# Raspberry Pi-specific GRUB overrides
# Overrides GRUB_CMDLINE_LINUX from /etc/default/grub with Pi-specific
# console devices and hardware quirks.
GRUB_CMDLINE_LINUX="boot=startos console=serial0,115200 console=tty1 usb-storage.quirks=152d:0562:u,14cd:121c:u,0781:cfcb:u cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory"

View File

@@ -1,3 +1,6 @@
os-partitions:
boot: /dev/mmcblk0p1
root: /dev/mmcblk0p2
ethernet-interface: end0 ethernet-interface: end0
wifi-interface: wlan0 wifi-interface: wlan0
disable-encryption: true disable-encryption: true

View File

@@ -118,6 +118,6 @@ else
fi fi
printf "\n \033[1;37m┌──────────────────────────────────────────────────── QUICK ACCESS ─┐\033[0m\n" printf "\n \033[1;37m┌──────────────────────────────────────────────────── QUICK ACCESS ─┐\033[0m\n"
printf " \033[1;37m│\033[0m Web Interface: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "$web_url" printf " \033[1;37m│\033[0m Web Interface: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "$web_url"
printf " \033[1;37m│\033[0m Documentation: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "https://docs.start9.com" printf " \033[1;37m│\033[0m Documentation: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "https://staging.docs.start9.com"
printf " \033[1;37m│\033[0m Support: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "https://start9.com/contact" printf " \033[1;37m│\033[0m Support: \033[0;36m%-50s\033[0m \033[1;37m│\033[0m\n" "https://start9.com/contact"
printf " \033[1;37m└───────────────────────────────────────────────────────────────────┘\033[0m\n\n" printf " \033[1;37m└───────────────────────────────────────────────────────────────────┘\033[0m\n\n"

View File

@@ -34,7 +34,7 @@ set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
if [ -z "$NO_SYNC" ]; then if [ -z "$NO_SYNC" ]; then
echo 'Syncing...' echo 'Syncing...'
umount -l /media/startos/next 2> /dev/null umount -R /media/startos/next 2> /dev/null
umount /media/startos/upper 2> /dev/null umount /media/startos/upper 2> /dev/null
rm -rf /media/startos/upper /media/startos/next rm -rf /media/startos/upper /media/startos/next
mkdir /media/startos/upper mkdir /media/startos/upper
@@ -55,16 +55,16 @@ mkdir -p /media/startos/next/sys
mkdir -p /media/startos/next/proc mkdir -p /media/startos/next/proc
mkdir -p /media/startos/next/boot mkdir -p /media/startos/next/boot
mkdir -p /media/startos/next/media/startos/root mkdir -p /media/startos/next/media/startos/root
mount -t tmpfs tmpfs /media/startos/next/run mount --bind /run /media/startos/next/run
mount -t tmpfs tmpfs /media/startos/next/tmp mount --bind /tmp /media/startos/next/tmp
mount --bind /dev /media/startos/next/dev mount --bind /dev /media/startos/next/dev
mount -t sysfs sysfs /media/startos/next/sys mount --bind /sys /media/startos/next/sys
mount -t proc proc /media/startos/next/proc mount --bind /proc /media/startos/next/proc
mount --bind /boot /media/startos/next/boot mount --bind /boot /media/startos/next/boot
mount --bind /media/startos/root /media/startos/next/media/startos/root mount --bind /media/startos/root /media/startos/next/media/startos/root
if mountpoint /sys/firmware/efi/efivars 2>&1 > /dev/null; then if mountpoint /sys/firmware/efi/efivars 2>&1 > /dev/null; then
mount -t efivarfs efivarfs /media/startos/next/sys/firmware/efi/efivars mount --bind /sys/firmware/efi/efivars /media/startos/next/sys/firmware/efi/efivars
fi fi
if [ -z "$*" ]; then if [ -z "$*" ]; then
@@ -79,13 +79,13 @@ if mountpoint /media/startos/next/sys/firmware/efi/efivars 2>&1 > /dev/null; the
umount /media/startos/next/sys/firmware/efi/efivars umount /media/startos/next/sys/firmware/efi/efivars
fi fi
umount -l /media/startos/next/run umount /media/startos/next/run
umount -l /media/startos/next/tmp umount /media/startos/next/tmp
umount -l /media/startos/next/dev umount /media/startos/next/dev
umount -l /media/startos/next/sys umount /media/startos/next/sys
umount -l /media/startos/next/proc umount /media/startos/next/proc
umount -l /media/startos/next/boot umount /media/startos/next/boot
umount -l /media/startos/next/media/startos/root umount /media/startos/next/media/startos/root
if [ "$CHROOT_RES" -eq 0 ]; then if [ "$CHROOT_RES" -eq 0 ]; then
@@ -111,6 +111,6 @@ if [ "$CHROOT_RES" -eq 0 ]; then
reboot reboot
fi fi
umount -l /media/startos/next umount /media/startos/next
umount -l /media/startos/upper umount /media/startos/upper
rm -rf /media/startos/upper /media/startos/next rm -rf /media/startos/upper /media/startos/next

View File

@@ -1,76 +0,0 @@
#!/bin/bash
# sign-unsigned-modules [--source <dir> --dest <dir>] [--sign-file <path>]
# [--mok-key <path>] [--mok-pub <path>]
#
# Signs all unsigned kernel modules using the DKMS MOK key.
#
# Default (install) mode:
# Run inside a chroot. Finds and signs unsigned modules in /lib/modules in-place.
# sign-file and MOK key are auto-detected from standard paths.
#
# Overlay mode (--source/--dest):
# Finds unsigned modules in <source>, copies to <dest>, signs the copies.
# Clears old signed modules in <dest> first. Used during upgrades where the
# overlay upper is tmpfs and writes would be lost.
set -e
SOURCE=""
DEST=""
SIGN_FILE=""
MOK_KEY="/var/lib/dkms/mok.key"
MOK_PUB="/var/lib/dkms/mok.pub"
while [[ $# -gt 0 ]]; do
case $1 in
--source) SOURCE="$2"; shift 2;;
--dest) DEST="$2"; shift 2;;
--sign-file) SIGN_FILE="$2"; shift 2;;
--mok-key) MOK_KEY="$2"; shift 2;;
--mok-pub) MOK_PUB="$2"; shift 2;;
*) echo "Unknown option: $1" >&2; exit 1;;
esac
done
# Auto-detect sign-file if not specified
if [ -z "$SIGN_FILE" ]; then
SIGN_FILE="$(ls -1 /usr/lib/linux-kbuild-*/scripts/sign-file 2>/dev/null | head -1)"
fi
if [ -z "$SIGN_FILE" ] || [ ! -x "$SIGN_FILE" ]; then
exit 0
fi
if [ ! -f "$MOK_KEY" ] || [ ! -f "$MOK_PUB" ]; then
exit 0
fi
COUNT=0
if [ -n "$SOURCE" ] && [ -n "$DEST" ]; then
# Overlay mode: find unsigned in source, copy to dest, sign in dest
rm -rf "${DEST}"/lib/modules
for ko in $(find "${SOURCE}"/lib/modules -name '*.ko' 2>/dev/null); do
if ! modinfo "$ko" 2>/dev/null | grep -q '^sig_id:'; then
rel_path="${ko#${SOURCE}}"
mkdir -p "${DEST}$(dirname "$rel_path")"
cp "$ko" "${DEST}${rel_path}"
"$SIGN_FILE" sha256 "$MOK_KEY" "$MOK_PUB" "${DEST}${rel_path}"
COUNT=$((COUNT + 1))
fi
done
else
# In-place mode: sign modules directly
for ko in $(find /lib/modules -name '*.ko' 2>/dev/null); do
if ! modinfo "$ko" 2>/dev/null | grep -q '^sig_id:'; then
"$SIGN_FILE" sha256 "$MOK_KEY" "$MOK_PUB" "$ko"
COUNT=$((COUNT + 1))
fi
done
fi
if [ $COUNT -gt 0 ]; then
echo "[sign-modules] Signed $COUNT unsigned kernel modules"
fi

View File

@@ -104,7 +104,6 @@ local_mount_root()
-olowerdir=/startos/config/overlay:/lower,upperdir=/upper/data,workdir=/upper/work \ -olowerdir=/startos/config/overlay:/lower,upperdir=/upper/data,workdir=/upper/work \
overlay ${rootmnt} overlay ${rootmnt}
mkdir -m 750 -p ${rootmnt}/media/startos
mkdir -p ${rootmnt}/media/startos/config mkdir -p ${rootmnt}/media/startos/config
mount --bind /startos/config ${rootmnt}/media/startos/config mount --bind /startos/config ${rootmnt}/media/startos/config
mkdir -p ${rootmnt}/media/startos/images mkdir -p ${rootmnt}/media/startos/images

View File

@@ -24,7 +24,7 @@ fi
unsquashfs -f -d / $1 boot unsquashfs -f -d / $1 boot
umount -l /media/startos/next 2> /dev/null || true umount -R /media/startos/next 2> /dev/null || true
umount /media/startos/upper 2> /dev/null || true umount /media/startos/upper 2> /dev/null || true
umount /media/startos/lower 2> /dev/null || true umount /media/startos/lower 2> /dev/null || true
@@ -45,13 +45,18 @@ mkdir -p /media/startos/next/media/startos/root
mount --bind /run /media/startos/next/run mount --bind /run /media/startos/next/run
mount --bind /tmp /media/startos/next/tmp mount --bind /tmp /media/startos/next/tmp
mount --bind /dev /media/startos/next/dev mount --bind /dev /media/startos/next/dev
mount -t sysfs sysfs /media/startos/next/sys mount --bind /sys /media/startos/next/sys
mount -t proc proc /media/startos/next/proc mount --bind /proc /media/startos/next/proc
mount --rbind /boot /media/startos/next/boot mount --bind /boot /media/startos/next/boot
mount --bind /media/startos/root /media/startos/next/media/startos/root mount --bind /media/startos/root /media/startos/next/media/startos/root
if mountpoint /boot/efi 2>&1 > /dev/null; then
mkdir -p /media/startos/next/boot/efi
mount --bind /boot/efi /media/startos/next/boot/efi
fi
if mountpoint /sys/firmware/efi/efivars 2>&1 > /dev/null; then if mountpoint /sys/firmware/efi/efivars 2>&1 > /dev/null; then
mount -t efivarfs efivarfs /media/startos/next/sys/firmware/efi/efivars mount --bind /sys/firmware/efi/efivars /media/startos/next/sys/firmware/efi/efivars
fi fi
chroot /media/startos/next bash -e << "EOF" chroot /media/startos/next bash -e << "EOF"
@@ -63,18 +68,9 @@ fi
EOF EOF
# Sign unsigned kernel modules for Secure Boot
SIGN_FILE="$(ls -1 /media/startos/next/usr/lib/linux-kbuild-*/scripts/sign-file 2>/dev/null | head -1)"
/media/startos/next/usr/lib/startos/scripts/sign-unsigned-modules \
--source /media/startos/lower \
--dest /media/startos/config/overlay \
--sign-file "$SIGN_FILE" \
--mok-key /media/startos/config/overlay/var/lib/dkms/mok.key \
--mok-pub /media/startos/config/overlay/var/lib/dkms/mok.pub
sync sync
umount -l /media/startos/next umount -Rl /media/startos/next
umount /media/startos/upper umount /media/startos/upper
umount /media/startos/lower umount /media/startos/lower

View File

@@ -1,367 +0,0 @@
#!/bin/bash
set -e
REPO="Start9Labs/start-os"
REGISTRY="https://alpha-registry-x.start9.com"
S3_BUCKET="s3://startos-images"
S3_CDN="https://startos-images.nyc3.cdn.digitaloceanspaces.com"
START9_GPG_KEY="2D63C217"
ARCHES="aarch64 aarch64-nonfree aarch64-nvidia riscv64 riscv64-nonfree x86_64 x86_64-nonfree x86_64-nvidia"
CLI_ARCHES="aarch64 riscv64 x86_64"
parse_run_id() {
local val="$1"
if [[ "$val" =~ /actions/runs/([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
else
echo "$val"
fi
}
require_version() {
if [ -z "${VERSION:-}" ]; then
read -rp "VERSION: " VERSION
if [ -z "$VERSION" ]; then
>&2 echo '$VERSION required'
exit 2
fi
fi
}
release_dir() {
echo "$HOME/Downloads/v$VERSION"
}
ensure_release_dir() {
local dir
dir=$(release_dir)
if [ "$CLEAN" = "1" ]; then
rm -rf "$dir"
fi
mkdir -p "$dir"
cd "$dir"
}
enter_release_dir() {
local dir
dir=$(release_dir)
if [ ! -d "$dir" ]; then
>&2 echo "Release directory $dir does not exist. Run 'download' or 'pull' first."
exit 1
fi
cd "$dir"
}
cli_target_for() {
local arch=$1 os=$2
local pair="${arch}-${os}"
if [ "$pair" = "riscv64-linux" ]; then
echo "riscv64gc-unknown-linux-musl"
elif [ "$pair" = "riscv64-macos" ]; then
return 1
elif [ "$os" = "linux" ]; then
echo "${arch}-unknown-linux-musl"
elif [ "$os" = "macos" ]; then
echo "${arch}-apple-darwin"
fi
}
release_files() {
for file in *.iso *.squashfs *.deb; do
[ -f "$file" ] && echo "$file"
done
for file in start-cli_*; do
[[ "$file" == *.asc ]] && continue
[ -f "$file" ] && echo "$file"
done
}
resolve_gh_user() {
GH_USER=${GH_USER:-$(gh api user -q .login 2>/dev/null || true)}
GH_GPG_KEY=$(git config user.signingkey 2>/dev/null || true)
}
# --- Subcommands ---
cmd_download() {
require_version
if [ -z "${RUN_ID:-}" ]; then
read -rp "RUN_ID (OS images, leave blank to skip): " RUN_ID
fi
RUN_ID=$(parse_run_id "${RUN_ID:-}")
if [ -z "${ST_RUN_ID:-}" ]; then
read -rp "ST_RUN_ID (start-tunnel, leave blank to skip): " ST_RUN_ID
fi
ST_RUN_ID=$(parse_run_id "${ST_RUN_ID:-}")
if [ -z "${CLI_RUN_ID:-}" ]; then
read -rp "CLI_RUN_ID (start-cli, leave blank to skip): " CLI_RUN_ID
fi
CLI_RUN_ID=$(parse_run_id "${CLI_RUN_ID:-}")
ensure_release_dir
if [ -n "$RUN_ID" ]; then
for arch in $ARCHES; do
while ! gh run download -R $REPO "$RUN_ID" -n "$arch.squashfs" -D "$(pwd)"; do sleep 1; done
done
for arch in $ARCHES; do
while ! gh run download -R $REPO "$RUN_ID" -n "$arch.iso" -D "$(pwd)"; do sleep 1; done
done
fi
if [ -n "$ST_RUN_ID" ]; then
for arch in $CLI_ARCHES; do
while ! gh run download -R $REPO "$ST_RUN_ID" -n "start-tunnel_$arch.deb" -D "$(pwd)"; do sleep 1; done
done
fi
if [ -n "$CLI_RUN_ID" ]; then
for arch in $CLI_ARCHES; do
for os in linux macos; do
local target
target=$(cli_target_for "$arch" "$os") || continue
while ! gh run download -R $REPO "$CLI_RUN_ID" -n "start-cli_$target" -D "$(pwd)"; do sleep 1; done
mv start-cli "start-cli_${arch}-${os}"
done
done
fi
}
cmd_pull() {
require_version
ensure_release_dir
echo "Downloading release assets from tag v$VERSION..."
# Download debs and CLI binaries from the GH release
for file in $(gh release view -R $REPO "v$VERSION" --json assets -q '.assets[].name' | grep -E '\.(deb)$|^start-cli_'); do
gh release download -R $REPO "v$VERSION" -p "$file" -D "$(pwd)" --clobber
done
# Download ISOs and squashfs from S3 CDN
for arch in $ARCHES; do
for ext in squashfs iso; do
# Get the actual filename from the GH release asset list or body
local filename
filename=$(gh release view -R $REPO "v$VERSION" --json assets -q ".assets[].name" | grep "_${arch}\\.${ext}$" || true)
if [ -z "$filename" ]; then
filename=$(gh release view -R $REPO "v$VERSION" --json body -q .body | grep -oP "[^ ]*_${arch}\\.${ext}" | head -1 || true)
fi
if [ -n "$filename" ]; then
echo "Downloading $filename from S3..."
curl -fSL -o "$filename" "$S3_CDN/v$VERSION/$filename"
fi
done
done
}
cmd_register() {
require_version
enter_release_dir
start-cli --registry=$REGISTRY registry os version add "$VERSION" "v$VERSION" '' ">=0.3.5 <=$VERSION"
}
cmd_upload() {
require_version
enter_release_dir
for file in $(release_files); do
case "$file" in
*.iso|*.squashfs)
s3cmd put -P "$file" "$S3_BUCKET/v$VERSION/$file"
;;
*)
gh release upload -R $REPO "v$VERSION" "$file"
;;
esac
done
}
cmd_index() {
require_version
enter_release_dir
for arch in $ARCHES; do
for file in *_"$arch".squashfs *_"$arch".iso; do
start-cli --registry=$REGISTRY registry os asset add --platform="$arch" --version="$VERSION" "$file" "$S3_CDN/v$VERSION/$file"
done
done
}
cmd_sign() {
require_version
enter_release_dir
resolve_gh_user
mkdir -p signatures
for file in $(release_files); do
gpg -u $START9_GPG_KEY --detach-sign --armor -o "signatures/${file}.start9.asc" "$file"
if [ -n "$GH_USER" ] && [ -n "$GH_GPG_KEY" ]; then
gpg -u "$GH_GPG_KEY" --detach-sign --armor -o "signatures/${file}.${GH_USER}.asc" "$file"
fi
done
gpg --export -a $START9_GPG_KEY > signatures/start9.key.asc
if [ -n "$GH_USER" ] && [ -n "$GH_GPG_KEY" ]; then
gpg --export -a "$GH_GPG_KEY" > "signatures/${GH_USER}.key.asc"
else
>&2 echo 'Warning: could not determine GitHub user or GPG signing key, skipping personal signature'
fi
tar -czvf signatures.tar.gz -C signatures .
gh release upload -R $REPO "v$VERSION" signatures.tar.gz --clobber
}
cmd_cosign() {
require_version
enter_release_dir
resolve_gh_user
if [ -z "$GH_USER" ] || [ -z "$GH_GPG_KEY" ]; then
>&2 echo 'Error: could not determine GitHub user or GPG signing key'
>&2 echo "Set GH_USER and/or configure git user.signingkey"
exit 1
fi
echo "Downloading existing signatures..."
gh release download -R $REPO "v$VERSION" -p "signatures.tar.gz" -D "$(pwd)" --clobber
mkdir -p signatures
tar -xzf signatures.tar.gz -C signatures
echo "Adding personal signatures as $GH_USER..."
for file in $(release_files); do
gpg -u "$GH_GPG_KEY" --detach-sign --armor -o "signatures/${file}.${GH_USER}.asc" "$file"
done
gpg --export -a "$GH_GPG_KEY" > "signatures/${GH_USER}.key.asc"
echo "Re-packing signatures..."
tar -czvf signatures.tar.gz -C signatures .
gh release upload -R $REPO "v$VERSION" signatures.tar.gz --clobber
echo "Done. Personal signatures for $GH_USER added to v$VERSION."
}
cmd_notes() {
require_version
enter_release_dir
cat << EOF
# ISO Downloads
- [x86_64/AMD64]($S3_CDN/v$VERSION/$(ls *_x86_64-nonfree.iso))
- [x86_64/AMD64 + NVIDIA]($S3_CDN/v$VERSION/$(ls *_x86_64-nvidia.iso))
- [x86_64/AMD64-slim (FOSS-only)]($S3_CDN/v$VERSION/$(ls *_x86_64.iso) "Without proprietary software or drivers")
- [aarch64/ARM64]($S3_CDN/v$VERSION/$(ls *_aarch64-nonfree.iso))
- [aarch64/ARM64 + NVIDIA]($S3_CDN/v$VERSION/$(ls *_aarch64-nvidia.iso))
- [aarch64/ARM64-slim (FOSS-Only)]($S3_CDN/v$VERSION/$(ls *_aarch64.iso) "Without proprietary software or drivers")
- [RISCV64 (RVA23)]($S3_CDN/v$VERSION/$(ls *_riscv64-nonfree.iso))
- [RISCV64 (RVA23)-slim (FOSS-only)]($S3_CDN/v$VERSION/$(ls *_riscv64.iso) "Without proprietary software or drivers")
EOF
cat << 'EOF'
# StartOS Checksums
## SHA-256
```
EOF
sha256sum *.iso *.squashfs
cat << 'EOF'
```
## BLAKE-3
```
EOF
b3sum *.iso *.squashfs
cat << 'EOF'
```
# Start-Tunnel Checksums
## SHA-256
```
EOF
sha256sum start-tunnel*.deb
cat << 'EOF'
```
## BLAKE-3
```
EOF
b3sum start-tunnel*.deb
cat << 'EOF'
```
# start-cli Checksums
## SHA-256
```
EOF
release_files | grep '^start-cli_' | xargs sha256sum
cat << 'EOF'
```
## BLAKE-3
```
EOF
release_files | grep '^start-cli_' | xargs b3sum
cat << 'EOF'
```
EOF
}
cmd_full_release() {
cmd_download
cmd_register
cmd_upload
cmd_index
cmd_sign
cmd_notes
}
usage() {
cat << 'EOF'
Usage: manage-release.sh <subcommand>
Subcommands:
download Download artifacts from GitHub Actions runs
Requires: RUN_ID, ST_RUN_ID, CLI_RUN_ID (any combination)
pull Download an existing release from the GH tag and S3
register Register the version in the Start9 registry
upload Upload artifacts to GitHub Releases and S3
index Add assets to the registry index
sign Sign all artifacts with Start9 org key (+ personal key if available)
and upload signatures.tar.gz
cosign Add personal GPG signature to an existing release's signatures
(requires 'pull' first so you can verify assets before signing)
notes Print release notes with download links and checksums
full-release Run: download → register → upload → index → sign → notes
Environment variables:
VERSION (required) Release version
RUN_ID GitHub Actions run ID for OS images (download subcommand)
ST_RUN_ID GitHub Actions run ID for start-tunnel (download subcommand)
CLI_RUN_ID GitHub Actions run ID for start-cli (download subcommand)
GH_USER Override GitHub username (default: autodetected via gh cli)
CLEAN Set to 1 to wipe and recreate the release directory
EOF
}
case "${1:-}" in
download) cmd_download ;;
pull) cmd_pull ;;
register) cmd_register ;;
upload) cmd_upload ;;
index) cmd_index ;;
sign) cmd_sign ;;
cosign) cmd_cosign ;;
notes) cmd_notes ;;
full-release) cmd_full_release ;;
*) usage; exit 1 ;;
esac

View File

@@ -1,36 +0,0 @@
#!/bin/bash
# Save Docker images needed by the 0.3.6-alpha.0 migration as tarballs
# so they can be bundled into the OS and loaded without internet access.
set -e
ARCH="${ARCH:-x86_64}"
DESTDIR="${1:-build/lib/migration-images}"
if [ "$ARCH" = "x86_64" ]; then
DOCKER_PLATFORM="linux/amd64"
elif [ "$ARCH" = "aarch64" ]; then
DOCKER_PLATFORM="linux/arm64"
else
DOCKER_PLATFORM="linux/$ARCH"
fi
IMAGES=("tonistiigi/binfmt:latest")
if [ "$ARCH" != "riscv64" ]; then
IMAGES=("start9/compat:latest" "start9/utils:latest" "${IMAGES[@]}")
fi
mkdir -p "$DESTDIR"
for IMAGE in "${IMAGES[@]}"; do
FILENAME=$(echo "$IMAGE" | sed 's|/|_|g; s/:/_/g').tar
if [ -f "$DESTDIR/$FILENAME" ]; then
echo "Skipping $IMAGE (already saved)"
continue
fi
echo "Pulling $IMAGE for $DOCKER_PLATFORM..."
docker pull --platform "$DOCKER_PLATFORM" "$IMAGE"
echo "Saving $IMAGE to $DESTDIR/$FILENAME..."
docker save "$IMAGE" -o "$DESTDIR/$FILENAME"
done
echo "Migration images saved to $DESTDIR"

142
build/upload-ota.sh Executable file
View File

@@ -0,0 +1,142 @@
#!/bin/bash
if [ -z "$VERSION" ]; then
>&2 echo '$VERSION required'
exit 2
fi
set -e
if [ "$SKIP_DL" != "1" ]; then
if [ "$SKIP_CLEAN" != "1" ]; then
rm -rf ~/Downloads/v$VERSION
mkdir ~/Downloads/v$VERSION
cd ~/Downloads/v$VERSION
fi
if [ -n "$RUN_ID" ]; then
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
while ! gh run download -R Start9Labs/start-os $RUN_ID -n $arch.squashfs -D $(pwd); do sleep 1; done
done
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
while ! gh run download -R Start9Labs/start-os $RUN_ID -n $arch.iso -D $(pwd); do sleep 1; done
done
fi
if [ -n "$ST_RUN_ID" ]; then
for arch in aarch64 riscv64 x86_64; do
while ! gh run download -R Start9Labs/start-os $ST_RUN_ID -n start-tunnel_$arch.deb -D $(pwd); do sleep 1; done
done
fi
if [ -n "$CLI_RUN_ID" ]; then
for arch in aarch64 riscv64 x86_64; do
for os in linux macos; do
pair=${arch}-${os}
if [ "${pair}" = "riscv64-linux" ]; then
target=riscv64gc-unknown-linux-musl
elif [ "${pair}" = "riscv64-macos" ]; then
continue
elif [ "${os}" = "linux" ]; then
target="${arch}-unknown-linux-musl"
elif [ "${os}" = "macos" ]; then
target="${arch}-apple-darwin"
fi
while ! gh run download -R Start9Labs/start-os $CLI_RUN_ID -n start-cli_$target -D $(pwd); do sleep 1; done
mv start-cli "start-cli_${pair}"
done
done
fi
else
cd ~/Downloads/v$VERSION
fi
start-cli --registry=https://alpha-registry-x.start9.com registry os version add $VERSION "v$VERSION" '' ">=0.3.5 <=$VERSION"
if [ "$SKIP_UL" = "2" ]; then
exit 2
elif [ "$SKIP_UL" != "1" ]; then
for file in *.deb start-cli_*; do
gh release upload -R Start9Labs/start-os v$VERSION $file
done
for file in *.iso *.squashfs; do
s3cmd put -P $file s3://startos-images/v$VERSION/$file
done
fi
if [ "$SKIP_INDEX" != "1" ]; then
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
for file in *_$arch.squashfs *_$arch.iso; do
start-cli --registry=https://alpha-registry-x.start9.com registry os asset add --platform=$arch --version=$VERSION $file https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$file
done
done
fi
for file in *.iso *.squashfs *.deb start-cli_*; do
gpg -u 7CFFDA41CA66056A --detach-sign --armor -o "${file}.asc" "$file"
done
gpg --export -a 7CFFDA41CA66056A > dr-bonez.key.asc
tar -czvf signatures.tar.gz *.asc
gh release upload -R Start9Labs/start-os v$VERSION signatures.tar.gz
cat << EOF
# ISO Downloads
- [x86_64/AMD64](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_x86_64-nonfree.iso))
- [x86_64/AMD64-slim (FOSS-only)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_x86_64.iso) "Without proprietary software or drivers")
- [aarch64/ARM64](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_aarch64-nonfree.iso))
- [aarch64/ARM64-slim (FOSS-Only)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_aarch64.iso) "Without proprietary software or drivers")
- [RISCV64 (RVA23)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_riscv64.iso))
EOF
cat << 'EOF'
# StartOS Checksums
## SHA-256
```
EOF
sha256sum *.iso *.squashfs
cat << 'EOF'
```
## BLAKE-3
```
EOF
b3sum *.iso *.squashfs
cat << 'EOF'
```
# Start-Tunnel Checksums
## SHA-256
```
EOF
sha256sum start-tunnel*.deb
cat << 'EOF'
```
## BLAKE-3
```
EOF
b3sum start-tunnel*.deb
cat << 'EOF'
```
# start-cli Checksums
## SHA-256
```
EOF
sha256sum start-cli_*
cat << 'EOF'
```
## BLAKE-3
```
EOF
b3sum start-cli_*
cat << 'EOF'
```
EOF

View File

@@ -1,30 +0,0 @@
// Mock for ESM-only mime package — Jest's module loader doesn't support require(esm)
const types = {
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".svg": "image/svg+xml",
".webp": "image/webp",
".ico": "image/x-icon",
".json": "application/json",
".js": "application/javascript",
".html": "text/html",
".css": "text/css",
".txt": "text/plain",
".md": "text/markdown",
}
module.exports = {
default: {
getType(path) {
const ext = "." + path.split(".").pop()
return types[ext] || null
},
getExtension(type) {
const entry = Object.entries(types).find(([, v]) => v === type)
return entry ? entry[0].slice(1) : null
},
},
__esModule: true,
}

View File

@@ -5,7 +5,7 @@ OnFailure=container-runtime-failure.service
[Service] [Service]
Type=simple Type=simple
Environment=RUST_LOG=startos=debug Environment=RUST_LOG=startos=debug
ExecStart=/usr/bin/start-container pipe-wrap /usr/bin/node --experimental-detect-module --trace-warnings /usr/lib/startos/init/index.js ExecStart=/usr/bin/node --experimental-detect-module --trace-warnings --unhandled-rejections=warn /usr/lib/startos/init/index.js
Restart=no Restart=no
[Install] [Install]

View File

@@ -5,7 +5,4 @@ module.exports = {
testEnvironment: "node", testEnvironment: "node",
rootDir: "./src/", rootDir: "./src/",
modulePathIgnorePatterns: ["./dist/"], modulePathIgnorePatterns: ["./dist/"],
moduleNameMapper: {
"^mime$": "<rootDir>/../__mocks__/mime.js",
},
} }

View File

@@ -37,7 +37,7 @@
}, },
"../sdk/dist": { "../sdk/dist": {
"name": "@start9labs/start-sdk", "name": "@start9labs/start-sdk",
"version": "0.4.0-beta.66", "version": "0.4.0-beta.51",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@iarna/toml": "^3.0.0", "@iarna/toml": "^3.0.0",
@@ -45,13 +45,11 @@
"@noble/hashes": "^1.7.2", "@noble/hashes": "^1.7.2",
"@types/ini": "^4.1.1", "@types/ini": "^4.1.1",
"deep-equality-data-structures": "^2.0.0", "deep-equality-data-structures": "^2.0.0",
"fast-xml-parser": "^5.5.6",
"ini": "^5.0.0", "ini": "^5.0.0",
"isomorphic-fetch": "^3.0.0", "isomorphic-fetch": "^3.0.0",
"mime": "^4.0.7", "mime": "^4.0.7",
"yaml": "^2.7.1", "yaml": "^2.7.1",
"zod": "^4.3.6", "zod": "^4.3.6"
"zod-deep-partial": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",

View File

@@ -187,10 +187,9 @@ export function makeEffects(context: EffectContext): Effects {
getServiceManifest( getServiceManifest(
...[options]: Parameters<T.Effects["getServiceManifest"]> ...[options]: Parameters<T.Effects["getServiceManifest"]>
) { ) {
return rpcRound("get-service-manifest", { return rpcRound("get-service-manifest", options) as ReturnType<
...options, T.Effects["getServiceManifest"]
callback: context.callbacks?.addCallback(options.callback) || null, >
}) as ReturnType<T.Effects["getServiceManifest"]>
}, },
subcontainer: { subcontainer: {
createFs(options: { imageId: string; name: string }) { createFs(options: { imageId: string; name: string }) {
@@ -212,10 +211,9 @@ export function makeEffects(context: EffectContext): Effects {
> >
}) as Effects["exportServiceInterface"], }) as Effects["exportServiceInterface"],
getContainerIp(...[options]: Parameters<T.Effects["getContainerIp"]>) { getContainerIp(...[options]: Parameters<T.Effects["getContainerIp"]>) {
return rpcRound("get-container-ip", { return rpcRound("get-container-ip", options) as ReturnType<
...options, T.Effects["getContainerIp"]
callback: context.callbacks?.addCallback(options.callback) || null, >
}) as ReturnType<T.Effects["getContainerIp"]>
}, },
getOsIp(...[]: Parameters<T.Effects["getOsIp"]>) { getOsIp(...[]: Parameters<T.Effects["getOsIp"]>) {
return rpcRound("get-os-ip", {}) as ReturnType<T.Effects["getOsIp"]> return rpcRound("get-os-ip", {}) as ReturnType<T.Effects["getOsIp"]>
@@ -246,10 +244,9 @@ export function makeEffects(context: EffectContext): Effects {
> >
}, },
getSslCertificate(options: Parameters<T.Effects["getSslCertificate"]>[0]) { getSslCertificate(options: Parameters<T.Effects["getSslCertificate"]>[0]) {
return rpcRound("get-ssl-certificate", { return rpcRound("get-ssl-certificate", options) as ReturnType<
...options, T.Effects["getSslCertificate"]
callback: context.callbacks?.addCallback(options.callback) || null, >
}) as ReturnType<T.Effects["getSslCertificate"]>
}, },
getSslKey(options: Parameters<T.Effects["getSslKey"]>[0]) { getSslKey(options: Parameters<T.Effects["getSslKey"]>[0]) {
return rpcRound("get-ssl-key", options) as ReturnType< return rpcRound("get-ssl-key", options) as ReturnType<
@@ -311,10 +308,7 @@ export function makeEffects(context: EffectContext): Effects {
}, },
getStatus(...[o]: Parameters<T.Effects["getStatus"]>) { getStatus(...[o]: Parameters<T.Effects["getStatus"]>) {
return rpcRound("get-status", { return rpcRound("get-status", o) as ReturnType<T.Effects["getStatus"]>
...o,
callback: context.callbacks?.addCallback(o.callback) || null,
}) as ReturnType<T.Effects["getStatus"]>
}, },
/// DEPRECATED /// DEPRECATED
setMainStatus(o: { status: "running" | "stopped" }): Promise<null> { setMainStatus(o: { status: "running" | "stopped" }): Promise<null> {

View File

@@ -298,10 +298,13 @@ export class RpcListener {
} }
case "stop": { case "stop": {
const { id } = stopType.parse(input) const { id } = stopType.parse(input)
this.callbacks?.removeChild("main")
return handleRpc( return handleRpc(
id, id,
this.system.stop().then((result) => ({ result })), this.system.stop().then((result) => {
this.callbacks?.removeChild("main")
return { result }
}),
) )
} }
case "exit": { case "exit": {

View File

@@ -42,74 +42,6 @@ function todo(): never {
throw new Error("Not implemented") throw new Error("Not implemented")
} }
function getStatus(
effects: Effects,
options: Omit<Parameters<Effects["getStatus"]>[0], "callback"> = {},
) {
async function* watch(abort?: AbortSignal) {
const resolveCell = { resolve: () => {} }
effects.onLeaveContext(() => {
resolveCell.resolve()
})
abort?.addEventListener("abort", () => resolveCell.resolve())
while (effects.isInContext && !abort?.aborted) {
let callback: () => void = () => {}
const waitForNext = new Promise<void>((resolve) => {
callback = resolve
resolveCell.resolve = resolve
})
yield await effects.getStatus({ ...options, callback })
await waitForNext
}
}
return {
const: () =>
effects.getStatus({
...options,
callback:
effects.constRetry &&
(() => effects.constRetry && effects.constRetry()),
}),
once: () => effects.getStatus(options),
watch: (abort?: AbortSignal) => {
const ctrl = new AbortController()
abort?.addEventListener("abort", () => ctrl.abort())
return watch(ctrl.signal)
},
onChange: (
callback: (
value: T.StatusInfo | null,
error?: Error,
) => { cancel: boolean } | Promise<{ cancel: boolean }>,
) => {
;(async () => {
const ctrl = new AbortController()
for await (const value of watch(ctrl.signal)) {
try {
const res = await callback(value)
if (res.cancel) {
ctrl.abort()
break
}
} catch (e) {
console.error(
"callback function threw an error @ getStatus.onChange",
e,
)
}
}
})()
.catch((e) => callback(null, e as Error))
.catch((e) =>
console.error(
"callback function threw an error @ getStatus.onChange",
e,
),
)
},
}
}
/** /**
* Local type for procedure values from the manifest. * Local type for procedure values from the manifest.
* The manifest's zod schemas use ZodTypeAny casts that produce `unknown` in zod v4. * The manifest's zod schemas use ZodTypeAny casts that produce `unknown` in zod v4.
@@ -445,14 +377,15 @@ export class SystemForEmbassy implements System {
} }
callCallback(_callback: number, _args: any[]): void {} callCallback(_callback: number, _args: any[]): void {}
async stop(): Promise<void> { async stop(): Promise<void> {
const clean = this.currentRunning?.clean({ const { currentRunning } = this
timeout: fromDuration( this.currentRunning?.clean()
(this.manifest.main["sigterm-timeout"] as any) || "30s",
),
})
delete this.currentRunning delete this.currentRunning
if (clean) { if (currentRunning) {
await clean await currentRunning.clean({
timeout: fromDuration(
(this.manifest.main["sigterm-timeout"] as any) || "30s",
),
})
} }
} }
@@ -1113,26 +1046,16 @@ export class SystemForEmbassy implements System {
timeoutMs: number | null, timeoutMs: number | null,
): Promise<void> { ): Promise<void> {
// TODO: docker // TODO: docker
const status = await getStatus(effects, { packageId: id }).const() await effects.mount({
if (!status) return location: `/media/embassy/${id}`,
try { target: {
await effects.mount({ packageId: id,
location: `/media/embassy/${id}`, volumeId: "embassy",
target: { subpath: null,
packageId: id, readonly: true,
volumeId: "embassy", idmap: [],
subpath: null, },
readonly: true, })
idmap: [],
},
})
} catch (e) {
console.error(
`Failed to mount dependency volume for ${id}, skipping autoconfig:`,
e,
)
return
}
configFile configFile
.withPath(`/media/embassy/${id}/config.json`) .withPath(`/media/embassy/${id}/config.json`)
.read() .read()
@@ -1281,11 +1204,6 @@ async function updateConfig(
if (specValue.target === "config") { if (specValue.target === "config") {
const jp = require("jsonpath") const jp = require("jsonpath")
const depId = specValue["package-id"] const depId = specValue["package-id"]
const depStatus = await getStatus(effects, { packageId: depId }).const()
if (!depStatus) {
mutConfigValue[key] = null
continue
}
await effects.mount({ await effects.mount({
location: `/media/embassy/${depId}`, location: `/media/embassy/${depId}`,
target: { target: {

View File

@@ -10,11 +10,6 @@ const matchJsProcedure = z.object({
const matchProcedure = z.union([matchDockerProcedure, matchJsProcedure]) const matchProcedure = z.union([matchDockerProcedure, matchJsProcedure])
export type Procedure = z.infer<typeof matchProcedure> export type Procedure = z.infer<typeof matchProcedure>
const healthCheckFields = {
name: z.string(),
"success-message": z.string().nullable().optional(),
}
const matchAction = z.object({ const matchAction = z.object({
name: z.string(), name: z.string(),
description: z.string(), description: z.string(),
@@ -37,10 +32,13 @@ export const matchManifest = z.object({
.optional(), .optional(),
"health-checks": z.record( "health-checks": z.record(
z.string(), z.string(),
z.union([ z.intersection(
matchDockerProcedure.extend(healthCheckFields), matchProcedure,
matchJsProcedure.extend(healthCheckFields), z.object({
]), name: z.string(),
"success-message": z.string().nullable().optional(),
}),
),
), ),
config: z config: z
.object({ .object({

View File

@@ -71,7 +71,7 @@ export class SystemForStartOs implements System {
this.starting = true this.starting = true
effects.constRetry = utils.once(() => { effects.constRetry = utils.once(() => {
console.debug(".const() triggered") console.debug(".const() triggered")
if (effects.isInContext) effects.restart() effects.restart()
}) })
let mainOnTerm: () => Promise<void> | undefined let mainOnTerm: () => Promise<void> | undefined
const daemons = await ( const daemons = await (

View File

@@ -1,4 +1,5 @@
import { RpcListener } from "./Adapters/RpcListener" import { RpcListener } from "./Adapters/RpcListener"
import { SystemForEmbassy } from "./Adapters/Systems/SystemForEmbassy"
import { AllGetDependencies } from "./Interfaces/AllGetDependencies" import { AllGetDependencies } from "./Interfaces/AllGetDependencies"
import { getSystem } from "./Adapters/Systems" import { getSystem } from "./Adapters/Systems"
@@ -6,18 +7,6 @@ const getDependencies: AllGetDependencies = {
system: getSystem, system: getSystem,
} }
process.on("unhandledRejection", (reason) => {
if (
reason instanceof Error &&
"muteUnhandled" in reason &&
reason.muteUnhandled
) {
// mute
} else {
console.error("Unhandled promise rejection", reason)
}
})
for (let s of ["SIGTERM", "SIGINT", "SIGHUP"]) { for (let s of ["SIGTERM", "SIGINT", "SIGHUP"]) {
process.on(s, (s) => { process.on(s, (s) => {
console.log(`Caught ${s}`) console.log(`Caught ${s}`)

View File

@@ -22,7 +22,6 @@ cd sdk && make baseDist dist # Rebuild SDK after ts-bindings
- Always run `cargo check -p start-os` after modifying Rust code - Always run `cargo check -p start-os` after modifying Rust code
- When adding RPC endpoints, follow the patterns in [rpc-toolkit.md](rpc-toolkit.md) - When adding RPC endpoints, follow the patterns in [rpc-toolkit.md](rpc-toolkit.md)
- When modifying `#[ts(export)]` types, regenerate bindings and rebuild the SDK (see [ARCHITECTURE.md](../ARCHITECTURE.md#build-pipeline)) - When modifying `#[ts(export)]` types, regenerate bindings and rebuild the SDK (see [ARCHITECTURE.md](../ARCHITECTURE.md#build-pipeline))
- **i18n is mandatory** — any user-facing string must go in `core/locales/i18n.yaml` with all 5 locales (`en_US`, `de_DE`, `es_ES`, `fr_FR`, `pl_PL`). This includes CLI subcommand descriptions (`about.<name>`), CLI arg help (`help.arg.<name>`), error messages (`error.<name>`), notifications, setup messages, and any other text shown to users. Entries are alphabetically ordered within their section. See [i18n-patterns.md](i18n-patterns.md) - When adding i18n keys, add all 5 locales in `core/locales/i18n.yaml` (see [i18n-patterns.md](i18n-patterns.md))
- When using DB watches, follow the `TypedDbWatch<T>` patterns in [patchdb.md](patchdb.md) - When using DB watches, follow the `TypedDbWatch<T>` patterns in [patchdb.md](patchdb.md)
- **Always use `.invoke(ErrorKind::...)` instead of `.status()` when running CLI commands** via `tokio::process::Command`. The `Invoke` trait (from `crate::util::Invoke`) captures stdout/stderr and checks exit codes properly. Using `.status()` leaks stderr directly to system logs, creating noise. For check-then-act patterns (e.g. `iptables -C`), use `.invoke(...).await.is_ok()` / `.is_err()` instead of `.status().await.map_or(false, |s| s.success())`. - **Always use `.invoke(ErrorKind::...)` instead of `.status()` when running CLI commands** via `tokio::process::Command`. The `Invoke` trait (from `crate::util::Invoke`) captures stdout/stderr and checks exit codes properly. Using `.status()` leaks stderr directly to system logs, creating noise. For check-then-act patterns (e.g. `iptables -C`), use `.invoke(...).await.is_ok()` / `.is_err()` instead of `.status().await.map_or(false, |s| s.success())`.
- Always use file utils in util::io instead of tokio::fs when available

751
core/Cargo.lock generated

File diff suppressed because it is too large Load Diff

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.23" # VERSION_BUMP version = "0.4.0-alpha.20" # VERSION_BUMP
[lib] [lib]
name = "startos" name = "startos"
@@ -63,7 +63,7 @@ async-compression = { version = "0.4.32", features = [
] } ] }
async-stream = "0.3.5" async-stream = "0.3.5"
async-trait = "0.1.74" async-trait = "0.1.74"
axum = { version = "0.8.4", features = ["http2", "ws"] } axum = { version = "0.8.4", features = ["ws", "http2"] }
backtrace-on-stack-overflow = { version = "0.3.0", optional = true } backtrace-on-stack-overflow = { version = "0.3.0", optional = true }
base32 = "0.5.0" base32 = "0.5.0"
base64 = "0.22.1" base64 = "0.22.1"
@@ -100,7 +100,6 @@ fd-lock-rs = "0.1.4"
form_urlencoded = "1.2.1" form_urlencoded = "1.2.1"
futures = "0.3.28" futures = "0.3.28"
gpt = "4.1.0" gpt = "4.1.0"
hashing-serializer = "0.1.1"
hex = "0.4.3" hex = "0.4.3"
hickory-server = { version = "0.25.2", features = ["resolver"] } hickory-server = { version = "0.25.2", features = ["resolver"] }
hmac = "0.12.1" hmac = "0.12.1"
@@ -171,7 +170,9 @@ once_cell = "1.19.0"
openssh-keys = "0.6.2" openssh-keys = "0.6.2"
openssl = { version = "0.10.57", features = ["vendored"] } openssl = { version = "0.10.57", features = ["vendored"] }
p256 = { version = "0.13.2", features = ["pem"] } p256 = { version = "0.13.2", features = ["pem"] }
patch-db = { version = "*", path = "../patch-db/core", features = ["trace"] } patch-db = { version = "*", path = "../patch-db/patch-db", features = [
"trace",
] }
pbkdf2 = "0.12.2" pbkdf2 = "0.12.2"
pin-project = "1.1.3" pin-project = "1.1.3"
pkcs8 = { version = "0.10.2", features = ["std"] } pkcs8 = { version = "0.10.2", features = ["std"] }
@@ -183,16 +184,16 @@ r3bl_tui = "0.7.6"
rand = "0.9.2" rand = "0.9.2"
regex = "1.10.2" regex = "1.10.2"
reqwest = { version = "0.12.25", features = [ reqwest = { version = "0.12.25", features = [
"http2",
"json", "json",
"socks", "socks",
"stream", "stream",
"http2",
] } ] }
reqwest_cookie_store = "0.9.0" reqwest_cookie_store = "0.9.0"
rpassword = "7.2.0" rpassword = "7.2.0"
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git" }
rust-argon2 = "3.0.0" rust-argon2 = "3.0.0"
rust-i18n = "3.1.5" rust-i18n = "3.1.5"
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git" }
semver = { version = "1.0.20", features = ["serde"] } semver = { version = "1.0.20", features = ["serde"] }
serde = { version = "1.0", features = ["derive", "rc"] } serde = { version = "1.0", features = ["derive", "rc"] }
serde_cbor = { package = "ciborium", version = "0.2.1" } serde_cbor = { package = "ciborium", version = "0.2.1" }
@@ -201,7 +202,6 @@ serde_toml = { package = "toml", version = "0.9.9+spec-1.0.0" }
serde_yaml = { package = "serde_yml", version = "0.0.12" } serde_yaml = { package = "serde_yml", version = "0.0.12" }
sha-crypt = "0.5.0" sha-crypt = "0.5.0"
sha2 = "0.10.2" sha2 = "0.10.2"
sha3 = "0.10"
signal-hook = "0.3.17" signal-hook = "0.3.17"
socket2 = { version = "0.6.0", features = ["all"] } socket2 = { version = "0.6.0", features = ["all"] }
socks5-impl = { version = "0.7.2", features = ["client", "server"] } socks5-impl = { version = "0.7.2", features = ["client", "server"] }
@@ -233,9 +233,7 @@ uuid = { version = "1.4.1", features = ["v4"] }
visit-rs = "0.1.1" visit-rs = "0.1.1"
x25519-dalek = { version = "2.0.1", features = ["static_secrets"] } x25519-dalek = { version = "2.0.1", features = ["static_secrets"] }
zbus = "5.1.1" zbus = "5.1.1"
hashing-serializer = "0.1.1"
[dev-dependencies]
clap_mangen = "0.2.33"
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
procfs = "0.18.0" procfs = "0.18.0"

View File

@@ -67,10 +67,6 @@ if [[ "${ENVIRONMENT:-}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable" RUSTFLAGS="--cfg tokio_unstable"
fi fi
if [[ "${ENVIRONMENT:-}" =~ (^|-)unstable($|-) ]]; then
RUSTFLAGS="$RUSTFLAGS -C debuginfo=1"
fi
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-cli --target=$TARGET rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-cli --target=$TARGET

View File

@@ -1,44 +0,0 @@
#!/bin/bash
cd "$(dirname "${BASH_SOURCE[0]}")"
source ./builder-alias.sh
set -ea
shopt -s expand_aliases
PROFILE=${PROFILE:-debug}
if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
if [ "$PROFILE" != "debug" ]; then
>&2 echo "Unknown profile $PROFILE: falling back to debug..."
PROFILE=debug
fi
fi
if [ -z "$ARCH" ]; then
ARCH=$(uname -m)
fi
if [ "$ARCH" = "arm64" ]; then
ARCH="aarch64"
fi
RUST_ARCH="$ARCH"
if [ "$ARCH" = "riscv64" ]; then
RUST_ARCH="riscv64gc"
fi
cd ../..
FEATURES="$(echo $ENVIRONMENT | sed 's/-/,/g')"
RUSTFLAGS=""
if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable"
fi
echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo test --manifest-path=./core/Cargo.toml --lib $BUILD_FLAGS --features test,$FEATURES --locked 'export_manpage_'
if [ "$(ls -nd "core/man" | awk '{ print $3 }')" != "$UID" ]; then
rust-zig-builder sh -c "chown -R $UID:$UID core/target && chown -R $UID:$UID core/man && chown -R $UID:$UID /usr/local/cargo"
fi

View File

@@ -38,10 +38,6 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable" RUSTFLAGS="--cfg tokio_unstable"
fi fi
if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
RUSTFLAGS="$RUSTFLAGS -C debuginfo=1"
fi
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin registrybox --target=$RUST_ARCH-unknown-linux-musl rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin registrybox --target=$RUST_ARCH-unknown-linux-musl

View File

@@ -38,10 +38,6 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable" RUSTFLAGS="--cfg tokio_unstable"
fi fi
if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
RUSTFLAGS="$RUSTFLAGS -C debuginfo=1"
fi
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-container --target=$RUST_ARCH-unknown-linux-musl rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-container --target=$RUST_ARCH-unknown-linux-musl

View File

@@ -38,10 +38,6 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable" RUSTFLAGS="--cfg tokio_unstable"
fi fi
if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
RUSTFLAGS="$RUSTFLAGS -C debuginfo=1"
fi
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin startbox --target=$RUST_ARCH-unknown-linux-musl rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin startbox --target=$RUST_ARCH-unknown-linux-musl

View File

@@ -38,10 +38,6 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
RUSTFLAGS="--cfg tokio_unstable" RUSTFLAGS="--cfg tokio_unstable"
fi fi
if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
RUSTFLAGS="$RUSTFLAGS -C debuginfo=1"
fi
echo "FEATURES=\"$FEATURES\"" echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\"" echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin tunnelbox --target=$RUST_ARCH-unknown-linux-musl rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin tunnelbox --target=$RUST_ARCH-unknown-linux-musl

View File

@@ -197,13 +197,6 @@ setup.transferring-data:
fr_FR: "Transfert de données" fr_FR: "Transfert de données"
pl_PL: "Przesyłanie danych" pl_PL: "Przesyłanie danych"
setup.password-required:
en_US: "Password is required for fresh setup"
de_DE: "Passwort ist für die Ersteinrichtung erforderlich"
es_ES: "Se requiere contraseña para la configuración inicial"
fr_FR: "Le mot de passe est requis pour la première configuration"
pl_PL: "Hasło jest wymagane do nowej konfiguracji"
# system.rs # system.rs
system.governor-not-available: system.governor-not-available:
en_US: "Governor %{governor} not available" en_US: "Governor %{governor} not available"
@@ -857,13 +850,6 @@ error.set-sys-info:
fr_FR: "Erreur de Définition des Infos Système" fr_FR: "Erreur de Définition des Infos Système"
pl_PL: "Błąd Ustawiania Informacji o Systemie" pl_PL: "Błąd Ustawiania Informacji o Systemie"
error.bios:
en_US: "BIOS/UEFI Error"
de_DE: "BIOS/UEFI-Fehler"
es_ES: "Error de BIOS/UEFI"
fr_FR: "Erreur BIOS/UEFI"
pl_PL: "Błąd BIOS/UEFI"
# disk/main.rs # disk/main.rs
disk.main.disk-not-found: disk.main.disk-not-found:
en_US: "StartOS disk not found." en_US: "StartOS disk not found."
@@ -872,13 +858,6 @@ disk.main.disk-not-found:
fr_FR: "Disque StartOS non trouvé." fr_FR: "Disque StartOS non trouvé."
pl_PL: "Nie znaleziono dysku StartOS." pl_PL: "Nie znaleziono dysku StartOS."
disk.main.converting-to-btrfs:
en_US: "Performing file system conversion to btrfs. This can take many hours, please be patient and DO NOT unplug the server."
de_DE: "Dateisystemkonvertierung zu btrfs wird durchgeführt. Dies kann viele Stunden dauern, bitte haben Sie Geduld und trennen Sie den Server NICHT vom Strom."
es_ES: "Realizando conversión del sistema de archivos a btrfs. Esto puede tardar muchas horas, tenga paciencia y NO desconecte el servidor."
fr_FR: "Conversion du système de fichiers vers btrfs en cours. Cela peut prendre de nombreuses heures, soyez patient et NE débranchez PAS le serveur."
pl_PL: "Wykonywanie konwersji systemu plików na btrfs. To może potrwać wiele godzin, prosimy o cierpliwość i NIE odłączaj serwera od zasilania."
disk.main.incorrect-disk: disk.main.incorrect-disk:
en_US: "A StartOS disk was found, but it is not the correct disk for this device." en_US: "A StartOS disk was found, but it is not the correct disk for this device."
de_DE: "Eine StartOS-Festplatte wurde gefunden, aber es ist nicht die richtige Festplatte für dieses Gerät." de_DE: "Eine StartOS-Festplatte wurde gefunden, aber es ist nicht die richtige Festplatte für dieses Gerät."
@@ -1262,13 +1241,6 @@ backup.bulk.leaked-reference:
fr_FR: "référence fuitée vers BackupMountGuard" fr_FR: "référence fuitée vers BackupMountGuard"
pl_PL: "wyciekła referencja do BackupMountGuard" pl_PL: "wyciekła referencja do BackupMountGuard"
backup.bulk.service-not-ready:
en_US: "Cannot create a backup of a service that is still initializing or in an error state"
de_DE: "Es kann keine Sicherung eines Dienstes erstellt werden, der noch initialisiert wird oder sich im Fehlerzustand befindet"
es_ES: "No se puede crear una copia de seguridad de un servicio que aún se está inicializando o está en estado de error"
fr_FR: "Impossible de créer une sauvegarde d'un service encore en cours d'initialisation ou en état d'erreur"
pl_PL: "Nie można utworzyć kopii zapasowej usługi, która jest jeszcze inicjalizowana lub znajduje się w stanie błędu"
# backup/restore.rs # backup/restore.rs
backup.restore.package-error: backup.restore.package-error:
en_US: "Error restoring package %{id}: %{error}" en_US: "Error restoring package %{id}: %{error}"
@@ -1393,21 +1365,6 @@ net.tor.client-error:
fr_FR: "Erreur du client Tor : %{error}" fr_FR: "Erreur du client Tor : %{error}"
pl_PL: "Błąd klienta Tor: %{error}" pl_PL: "Błąd klienta Tor: %{error}"
# net/tunnel.rs
net.tunnel.timeout-waiting-for-add:
en_US: "timed out waiting for gateway %{gateway} to appear in database"
de_DE: "Zeitüberschreitung beim Warten auf das Erscheinen von Gateway %{gateway} in der Datenbank"
es_ES: "se agotó el tiempo esperando que la puerta de enlace %{gateway} aparezca en la base de datos"
fr_FR: "délai d'attente dépassé pour l'apparition de la passerelle %{gateway} dans la base de données"
pl_PL: "upłynął limit czasu oczekiwania na pojawienie się bramy %{gateway} w bazie danych"
net.tunnel.timeout-waiting-for-remove:
en_US: "timed out waiting for gateway %{gateway} to be removed from database"
de_DE: "Zeitüberschreitung beim Warten auf das Entfernen von Gateway %{gateway} aus der Datenbank"
es_ES: "se agotó el tiempo esperando que la puerta de enlace %{gateway} sea eliminada de la base de datos"
fr_FR: "délai d'attente dépassé pour la suppression de la passerelle %{gateway} de la base de données"
pl_PL: "upłynął limit czasu oczekiwania na usunięcie bramy %{gateway} z bazy danych"
# net/wifi.rs # net/wifi.rs
net.wifi.ssid-no-special-characters: net.wifi.ssid-no-special-characters:
en_US: "SSID may not have special characters" en_US: "SSID may not have special characters"
@@ -1621,13 +1578,6 @@ net.gateway.cannot-delete-without-connection:
fr_FR: "Impossible de supprimer l'appareil sans connexion active" fr_FR: "Impossible de supprimer l'appareil sans connexion active"
pl_PL: "Nie można usunąć urządzenia bez aktywnego połączenia" pl_PL: "Nie można usunąć urządzenia bez aktywnego połączenia"
net.gateway.no-configured-echoip-urls:
en_US: "No configured echoip URLs"
de_DE: "Keine konfigurierten EchoIP-URLs"
es_ES: "No hay URLs de echoip configuradas"
fr_FR: "Aucune URL echoip configurée"
pl_PL: "Brak skonfigurowanych adresów URL echoip"
# net/dns.rs # net/dns.rs
net.dns.timeout-updating-catalog: net.dns.timeout-updating-catalog:
en_US: "timed out waiting to update dns catalog" en_US: "timed out waiting to update dns catalog"
@@ -1721,14 +1671,6 @@ lxc.mod.cleaned-up-containers:
fr_FR: "Conteneurs LXC orphelins nettoyés avec succès" fr_FR: "Conteneurs LXC orphelins nettoyés avec succès"
pl_PL: "Pomyślnie wyczyszczono wiszące kontenery LXC" pl_PL: "Pomyślnie wyczyszczono wiszące kontenery LXC"
# version/v0_3_6_alpha_0.rs
migration.migrating-package:
en_US: "Migrating package %{package}..."
de_DE: "Paket %{package} wird migriert..."
es_ES: "Migrando paquete %{package}..."
fr_FR: "Migration du paquet %{package}..."
pl_PL: "Migracja pakietu %{package}..."
# registry/admin.rs # registry/admin.rs
registry.admin.unknown-signer: registry.admin.unknown-signer:
en_US: "Unknown signer" en_US: "Unknown signer"
@@ -2657,13 +2599,6 @@ help.arg.add-signer-key:
fr_FR: "Ajouter une clé publique au signataire" fr_FR: "Ajouter une clé publique au signataire"
pl_PL: "Dodaj klucz publiczny do sygnatariusza" pl_PL: "Dodaj klucz publiczny do sygnatariusza"
help.arg.address:
en_US: "Network address"
de_DE: "Netzwerkadresse"
es_ES: "Dirección de red"
fr_FR: "Adresse réseau"
pl_PL: "Adres sieciowy"
help.arg.allow-model-mismatch: help.arg.allow-model-mismatch:
en_US: "Allow database model mismatch" en_US: "Allow database model mismatch"
de_DE: "Datenbankmodell-Abweichung erlauben" de_DE: "Datenbankmodell-Abweichung erlauben"
@@ -2678,13 +2613,6 @@ help.arg.allow-partial-backup:
fr_FR: "Laisser le média monté même si backupfs échoue à monter" fr_FR: "Laisser le média monté même si backupfs échoue à monter"
pl_PL: "Pozostaw nośnik zamontowany nawet jeśli backupfs nie może się zamontować" pl_PL: "Pozostaw nośnik zamontowany nawet jeśli backupfs nie może się zamontować"
help.arg.architecture:
en_US: "Target CPU architecture (e.g. x86_64, aarch64)"
de_DE: "Ziel-CPU-Architektur (z.B. x86_64, aarch64)"
es_ES: "Arquitectura de CPU objetivo (ej. x86_64, aarch64)"
fr_FR: "Architecture CPU cible (ex. x86_64, aarch64)"
pl_PL: "Docelowa architektura CPU (np. x86_64, aarch64)"
help.arg.architecture-mask: help.arg.architecture-mask:
en_US: "Filter by CPU architecture" en_US: "Filter by CPU architecture"
de_DE: "Nach CPU-Architektur filtern" de_DE: "Nach CPU-Architektur filtern"
@@ -2811,20 +2739,6 @@ help.arg.download-directory:
fr_FR: "Chemin du répertoire de téléchargement" fr_FR: "Chemin du répertoire de téléchargement"
pl_PL: "Ścieżka katalogu do pobrania" pl_PL: "Ścieżka katalogu do pobrania"
help.arg.echoip-urls:
en_US: "Echo IP service URLs for external IP detection"
de_DE: "Echo-IP-Dienst-URLs zur externen IP-Erkennung"
es_ES: "URLs del servicio Echo IP para detección de IP externa"
fr_FR: "URLs du service Echo IP pour la détection d'IP externe"
pl_PL: "Adresy URL usługi Echo IP do wykrywania zewnętrznego IP"
help.arg.ed25519:
en_US: "Use Ed25519 instead of NIST P-256"
de_DE: "Ed25519 anstelle von NIST P-256 verwenden"
es_ES: "Usar Ed25519 en lugar de NIST P-256"
fr_FR: "Utiliser Ed25519 au lieu de NIST P-256"
pl_PL: "Użyj Ed25519 zamiast NIST P-256"
help.arg.emulate-missing-arch: help.arg.emulate-missing-arch:
en_US: "Emulate missing architecture using this one" en_US: "Emulate missing architecture using this one"
de_DE: "Fehlende Architektur mit dieser emulieren" de_DE: "Fehlende Architektur mit dieser emulieren"
@@ -2909,13 +2823,6 @@ help.arg.host-url:
fr_FR: "URL du serveur StartOS" fr_FR: "URL du serveur StartOS"
pl_PL: "URL serwera StartOS" pl_PL: "URL serwera StartOS"
help.arg.hostnames:
en_US: "Hostnames to include in the certificate"
de_DE: "Hostnamen, die in das Zertifikat aufgenommen werden sollen"
es_ES: "Nombres de host para incluir en el certificado"
fr_FR: "Noms d'hôtes à inclure dans le certificat"
pl_PL: "Nazwy hostów do uwzględnienia w certyfikacie"
help.arg.icon-path: help.arg.icon-path:
en_US: "Path to service icon file" en_US: "Path to service icon file"
de_DE: "Pfad zur Service-Icon-Datei" de_DE: "Pfad zur Service-Icon-Datei"
@@ -3000,13 +2907,6 @@ help.arg.log-limit:
fr_FR: "Nombre maximum d'entrées de journal" fr_FR: "Nombre maximum d'entrées de journal"
pl_PL: "Maksymalna liczba wpisów logu" pl_PL: "Maksymalna liczba wpisów logu"
help.arg.merge:
en_US: "Merge with existing version range instead of replacing"
de_DE: "Mit vorhandenem Versionsbereich zusammenführen statt ersetzen"
es_ES: "Combinar con el rango de versiones existente en lugar de reemplazar"
fr_FR: "Fusionner avec la plage de versions existante au lieu de remplacer"
pl_PL: "Połącz z istniejącym zakresem wersji zamiast zastępować"
help.arg.mirror-url: help.arg.mirror-url:
en_US: "URL of the mirror" en_US: "URL of the mirror"
de_DE: "URL des Spiegels" de_DE: "URL des Spiegels"
@@ -3119,13 +3019,6 @@ help.arg.platform:
fr_FR: "Identifiant de la plateforme cible" fr_FR: "Identifiant de la plateforme cible"
pl_PL: "Identyfikator platformy docelowej" pl_PL: "Identyfikator platformy docelowej"
help.arg.port:
en_US: "Port number"
de_DE: "Portnummer"
es_ES: "Número de puerto"
fr_FR: "Numéro de port"
pl_PL: "Numer portu"
help.arg.postgres-connection-url: help.arg.postgres-connection-url:
en_US: "PostgreSQL connection URL" en_US: "PostgreSQL connection URL"
de_DE: "PostgreSQL-Verbindungs-URL" de_DE: "PostgreSQL-Verbindungs-URL"
@@ -3210,13 +3103,6 @@ help.arg.server-id:
fr_FR: "Identifiant unique du serveur" fr_FR: "Identifiant unique du serveur"
pl_PL: "Unikalny identyfikator serwera" pl_PL: "Unikalny identyfikator serwera"
help.arg.set-as-default-outbound:
en_US: "Set as the default outbound gateway"
de_DE: "Als Standard-Ausgangs-Gateway festlegen"
es_ES: "Establecer como puerta de enlace de salida predeterminada"
fr_FR: "Définir comme passerelle de sortie par défaut"
pl_PL: "Ustaw jako domyślną bramę wychodzącą"
help.arg.set-signer-name: help.arg.set-signer-name:
en_US: "Set the signer name" en_US: "Set the signer name"
de_DE: "Unterzeichnernamen festlegen" de_DE: "Unterzeichnernamen festlegen"
@@ -3581,13 +3467,6 @@ help.arg.gateway-name:
fr_FR: "Nom de la passerelle" fr_FR: "Nom de la passerelle"
pl_PL: "Nazwa bramy" pl_PL: "Nazwa bramy"
help.arg.gateway-type:
en_US: "Type of gateway"
de_DE: "Typ des Gateways"
es_ES: "Tipo de puerta de enlace"
fr_FR: "Type de passerelle"
pl_PL: "Typ bramy"
help.arg.governor-name: help.arg.governor-name:
en_US: "CPU governor name" en_US: "CPU governor name"
de_DE: "CPU-Governor-Name" de_DE: "CPU-Governor-Name"
@@ -3798,13 +3677,6 @@ help.arg.s9pk-file-path:
fr_FR: "Chemin vers le fichier de paquet s9pk" fr_FR: "Chemin vers le fichier de paquet s9pk"
pl_PL: "Ścieżka do pliku pakietu s9pk" pl_PL: "Ścieżka do pliku pakietu s9pk"
help.arg.s9pk-file-paths:
en_US: "Paths to s9pk package files"
de_DE: "Pfade zu s9pk-Paketdateien"
es_ES: "Rutas a los archivos de paquete s9pk"
fr_FR: "Chemins vers les fichiers de paquet s9pk"
pl_PL: "Ścieżki do plików pakietów s9pk"
help.arg.session-ids: help.arg.session-ids:
en_US: "Session identifiers" en_US: "Session identifiers"
de_DE: "Sitzungskennungen" de_DE: "Sitzungskennungen"
@@ -4114,13 +3986,6 @@ about.add-version-signer:
fr_FR: "Ajouter un signataire de version" fr_FR: "Ajouter un signataire de version"
pl_PL: "Dodaj sygnatariusza wersji" pl_PL: "Dodaj sygnatariusza wersji"
about.add-vhost-passthrough:
en_US: "Add vhost passthrough"
de_DE: "Vhost-Passthrough hinzufügen"
es_ES: "Agregar passthrough de vhost"
fr_FR: "Ajouter un passthrough vhost"
pl_PL: "Dodaj passthrough vhost"
about.add-wifi-ssid-password: about.add-wifi-ssid-password:
en_US: "Add wifi ssid and password" en_US: "Add wifi ssid and password"
de_DE: "WLAN-SSID und Passwort hinzufügen" de_DE: "WLAN-SSID und Passwort hinzufügen"
@@ -4170,13 +4035,6 @@ about.check-for-updates:
fr_FR: "Vérifier les mises à jour disponibles" fr_FR: "Vérifier les mises à jour disponibles"
pl_PL: "Sprawdź dostępne aktualizacje" pl_PL: "Sprawdź dostępne aktualizacje"
about.check-port-reachability:
en_US: "Check if a port is reachable from the WAN"
de_DE: "Prüfen, ob ein Port vom WAN erreichbar ist"
es_ES: "Comprobar si un puerto es accesible desde la WAN"
fr_FR: "Vérifier si un port est accessible depuis le WAN"
pl_PL: "Sprawdź, czy port jest osiągalny z WAN"
about.check-update-startos: about.check-update-startos:
en_US: "Check a given registry for StartOS updates and update if available" en_US: "Check a given registry for StartOS updates and update if available"
de_DE: "Ein bestimmtes Registry auf StartOS-Updates prüfen und bei Verfügbarkeit aktualisieren" de_DE: "Ein bestimmtes Registry auf StartOS-Updates prüfen und bei Verfügbarkeit aktualisieren"
@@ -4275,13 +4133,6 @@ about.commands-authentication:
fr_FR: "Commandes liées à l'authentification, comme connexion, déconnexion" fr_FR: "Commandes liées à l'authentification, comme connexion, déconnexion"
pl_PL: "Polecenia związane z uwierzytelnianiem, np. logowanie, wylogowanie" pl_PL: "Polecenia związane z uwierzytelnianiem, np. logowanie, wylogowanie"
about.commands-authorized-keys:
en_US: "Commands for managing authorized keys"
de_DE: "Befehle zur Verwaltung autorisierter Schlüssel"
es_ES: "Comandos para gestionar claves autorizadas"
fr_FR: "Commandes pour gérer les clés autorisées"
pl_PL: "Polecenia do zarządzania autoryzowanymi kluczami"
about.commands-backup: about.commands-backup:
en_US: "Commands related to backup creation and backup targets" en_US: "Commands related to backup creation and backup targets"
de_DE: "Befehle zur Backup-Erstellung und Backup-Zielen" de_DE: "Befehle zur Backup-Erstellung und Backup-Zielen"
@@ -4345,41 +4196,6 @@ about.commands-experimental:
fr_FR: "Commandes liées à la configuration d'options expérimentales comme zram et le gouverneur CPU" fr_FR: "Commandes liées à la configuration d'options expérimentales comme zram et le gouverneur CPU"
pl_PL: "Polecenia konfiguracji opcji eksperymentalnych jak zram i regulator CPU" pl_PL: "Polecenia konfiguracji opcji eksperymentalnych jak zram i regulator CPU"
about.commands-host-address-domain:
en_US: "Commands for managing host address domains"
de_DE: "Befehle zur Verwaltung von Host-Adressdomänen"
es_ES: "Comandos para gestionar dominios de direcciones del host"
fr_FR: "Commandes pour gérer les domaines d'adresses de l'hôte"
pl_PL: "Polecenia do zarządzania domenami adresów hosta"
about.commands-host-addresses:
en_US: "Commands for managing host addresses"
de_DE: "Befehle zur Verwaltung von Host-Adressen"
es_ES: "Comandos para gestionar direcciones del host"
fr_FR: "Commandes pour gérer les adresses de l'hôte"
pl_PL: "Polecenia do zarządzania adresami hosta"
about.commands-host-bindings:
en_US: "Commands for managing host bindings"
de_DE: "Befehle zur Verwaltung von Host-Bindungen"
es_ES: "Comandos para gestionar vínculos del host"
fr_FR: "Commandes pour gérer les liaisons de l'hôte"
pl_PL: "Polecenia do zarządzania powiązaniami hosta"
about.commands-host-private-domain:
en_US: "Commands for managing private domains for a host"
de_DE: "Befehle zur Verwaltung privater Domänen für einen Host"
es_ES: "Comandos para gestionar dominios privados de un host"
fr_FR: "Commandes pour gérer les domaines privés d'un hôte"
pl_PL: "Polecenia do zarządzania prywatnymi domenami hosta"
about.commands-host-public-domain:
en_US: "Commands for managing public domains for a host"
de_DE: "Befehle zur Verwaltung öffentlicher Domänen für einen Host"
es_ES: "Comandos para gestionar dominios públicos de un host"
fr_FR: "Commandes pour gérer les domaines publics d'un hôte"
pl_PL: "Polecenia do zarządzania publicznymi domenami hosta"
about.commands-host-system-ui: about.commands-host-system-ui:
en_US: "Commands for modifying the host for the system ui" en_US: "Commands for modifying the host for the system ui"
de_DE: "Befehle zum Ändern des Hosts für die System-UI" de_DE: "Befehle zum Ändern des Hosts für die System-UI"
@@ -4436,13 +4252,6 @@ about.commands-packages:
fr_FR: "Commandes liées aux paquets" fr_FR: "Commandes liées aux paquets"
pl_PL: "Polecenia związane z pakietami" pl_PL: "Polecenia związane z pakietami"
about.commands-port-forward:
en_US: "Commands for managing port forwards"
de_DE: "Befehle zur Verwaltung von Portweiterleitungen"
es_ES: "Comandos para gestionar reenvíos de puertos"
fr_FR: "Commandes pour gérer les redirections de ports"
pl_PL: "Polecenia do zarządzania przekierowaniami portów"
about.commands-registry: about.commands-registry:
en_US: "Commands related to the registry" en_US: "Commands related to the registry"
de_DE: "Befehle zum Registry" de_DE: "Befehle zum Registry"
@@ -4457,13 +4266,6 @@ about.commands-registry-db:
fr_FR: "Commandes pour interagir avec la base de données, comme dump et apply" fr_FR: "Commandes pour interagir avec la base de données, comme dump et apply"
pl_PL: "Polecenia interakcji z bazą danych, np. dump i apply" pl_PL: "Polecenia interakcji z bazą danych, np. dump i apply"
about.commands-registry-info:
en_US: "View or edit registry information"
de_DE: "Registry-Informationen anzeigen oder bearbeiten"
es_ES: "Ver o editar información del registro"
fr_FR: "Afficher ou modifier les informations du registre"
pl_PL: "Wyświetl lub edytuj informacje rejestru"
about.commands-restore-backup: about.commands-restore-backup:
en_US: "Commands for restoring package(s) from backup" en_US: "Commands for restoring package(s) from backup"
de_DE: "Befehle zum Wiederherstellen von Paketen aus dem Backup" de_DE: "Befehle zum Wiederherstellen von Paketen aus dem Backup"
@@ -4506,20 +4308,6 @@ about.commands-tunnel:
fr_FR: "Commandes liées à StartTunnel" fr_FR: "Commandes liées à StartTunnel"
pl_PL: "Polecenia związane z StartTunnel" pl_PL: "Polecenia związane z StartTunnel"
about.commands-tunnel-update:
en_US: "Commands for checking and applying tunnel updates"
de_DE: "Befehle zum Prüfen und Anwenden von Tunnel-Updates"
es_ES: "Comandos para verificar y aplicar actualizaciones del túnel"
fr_FR: "Commandes pour vérifier et appliquer les mises à jour du tunnel"
pl_PL: "Polecenia do sprawdzania i stosowania aktualizacji tunelu"
about.commands-tunnel-web:
en_US: "Commands for managing the tunnel web interface"
de_DE: "Befehle zur Verwaltung der Tunnel-Weboberfläche"
es_ES: "Comandos para gestionar la interfaz web del túnel"
fr_FR: "Commandes pour gérer l'interface web du tunnel"
pl_PL: "Polecenia do zarządzania interfejsem webowym tunelu"
about.commands-wifi: about.commands-wifi:
en_US: "Commands related to wifi networks i.e. add, connect, delete" en_US: "Commands related to wifi networks i.e. add, connect, delete"
de_DE: "Befehle zu WLAN-Netzwerken, z.B. hinzufügen, verbinden, löschen" de_DE: "Befehle zu WLAN-Netzwerken, z.B. hinzufügen, verbinden, löschen"
@@ -4660,13 +4448,6 @@ about.display-s9pk-manifest:
fr_FR: "Afficher le manifeste s9pk" fr_FR: "Afficher le manifeste s9pk"
pl_PL: "Wyświetl manifest s9pk" pl_PL: "Wyświetl manifest s9pk"
about.display-s9pk-root-sighash-and-maxsize:
en_US: "Display the s9pk root signature hash and max size"
de_DE: "Den s9pk-Root-Signaturhash und die maximale Größe anzeigen"
es_ES: "Mostrar el hash de firma raíz y el tamaño máximo del s9pk"
fr_FR: "Afficher le hachage de signature racine et la taille maximale du s9pk"
pl_PL: "Wyświetl hash podpisu głównego i maksymalny rozmiar s9pk"
about.display-server-metrics: about.display-server-metrics:
en_US: "Display server metrics" en_US: "Display server metrics"
de_DE: "Server-Metriken anzeigen" de_DE: "Server-Metriken anzeigen"
@@ -4730,20 +4511,6 @@ about.dump-address-resolution-table:
fr_FR: "Exporter la table de résolution d'adresses" fr_FR: "Exporter la table de résolution d'adresses"
pl_PL: "Zrzuć tabelę rozpoznawania adresów" pl_PL: "Zrzuć tabelę rozpoznawania adresów"
about.dump-port-forward-table:
en_US: "Dump port forward table"
de_DE: "Portweiterleitungstabelle ausgeben"
es_ES: "Volcar tabla de reenvío de puertos"
fr_FR: "Exporter la table de redirection de ports"
pl_PL: "Zrzuć tabelę przekierowań portów"
about.dump-vhost-proxy-table:
en_US: "Dump vhost proxy table"
de_DE: "Vhost-Proxy-Tabelle ausgeben"
es_ES: "Volcar tabla de proxy vhost"
fr_FR: "Exporter la table de proxy vhost"
pl_PL: "Zrzuć tabelę proxy vhost"
about.echo-message: about.echo-message:
en_US: "Echo a message back" en_US: "Echo a message back"
de_DE: "Eine Nachricht zurückgeben" de_DE: "Eine Nachricht zurückgeben"
@@ -4779,13 +4546,6 @@ about.enable-kiosk-mode:
fr_FR: "Activer le mode kiosque" fr_FR: "Activer le mode kiosque"
pl_PL: "Włącz tryb kiosku" pl_PL: "Włącz tryb kiosku"
about.enable-or-disable-port-forward:
en_US: "Enable or disable a port forward"
de_DE: "Portweiterleitung aktivieren oder deaktivieren"
es_ES: "Habilitar o deshabilitar un reenvío de puerto"
fr_FR: "Activer ou désactiver une redirection de port"
pl_PL: "Włącz lub wyłącz przekierowanie portu"
about.enable-webserver: about.enable-webserver:
en_US: "Enable the webserver" en_US: "Enable the webserver"
de_DE: "Webserver aktivieren" de_DE: "Webserver aktivieren"
@@ -4877,13 +4637,6 @@ about.get-developer-pubkey:
fr_FR: "Obtenir la clé publique du développeur" fr_FR: "Obtenir la clé publique du développeur"
pl_PL: "Pobierz klucz publiczny dewelopera" pl_PL: "Pobierz klucz publiczny dewelopera"
about.get-device-info:
en_US: "Display device information"
de_DE: "Geräteinformationen anzeigen"
es_ES: "Mostrar información del dispositivo"
fr_FR: "Afficher les informations de l'appareil"
pl_PL: "Wyświetl informacje o urządzeniu"
about.get-initialization-progress: about.get-initialization-progress:
en_US: "Get initialization progress" en_US: "Get initialization progress"
de_DE: "Initialisierungsfortschritt abrufen" de_DE: "Initialisierungsfortschritt abrufen"
@@ -5073,13 +4826,6 @@ about.list-paths-of-package-ingredients:
fr_FR: "Lister les chemins des composants du package" fr_FR: "Lister les chemins des composants du package"
pl_PL: "Wyświetl ścieżki składników pakietu" pl_PL: "Wyświetl ścieżki składników pakietu"
about.list-registry-categories:
en_US: "List registry categories"
de_DE: "Registry-Kategorien auflisten"
es_ES: "Listar categorías del registro"
fr_FR: "Lister les catégories du registre"
pl_PL: "Wyświetl kategorie rejestru"
about.list-registry-info-packages: about.list-registry-info-packages:
en_US: "List registry info and packages" en_US: "List registry info and packages"
de_DE: "Registry-Informationen und Pakete auflisten" de_DE: "Registry-Informationen und Pakete auflisten"
@@ -5108,13 +4854,6 @@ about.list-version-signers:
fr_FR: "Lister les signataires de versions" fr_FR: "Lister les signataires de versions"
pl_PL: "Wyświetl sygnatariuszy wersji" pl_PL: "Wyświetl sygnatariuszy wersji"
about.list-vhost-passthrough:
en_US: "List vhost passthroughs"
de_DE: "Vhost-Passthroughs auflisten"
es_ES: "Listar passthroughs de vhost"
fr_FR: "Lister les passthroughs vhost"
pl_PL: "Wyświetl passthrough vhost"
about.list-wifi-info: about.list-wifi-info:
en_US: "List wifi information" en_US: "List wifi information"
de_DE: "WLAN-Informationen auflisten" de_DE: "WLAN-Informationen auflisten"
@@ -5164,13 +4903,6 @@ about.manage-query-dns:
fr_FR: "Gérer et interroger le DNS" fr_FR: "Gérer et interroger le DNS"
pl_PL: "Zarządzaj i odpytuj DNS" pl_PL: "Zarządzaj i odpytuj DNS"
about.manage-ssl-certificates:
en_US: "Manage SSL certificates"
de_DE: "SSL-Zertifikate verwalten"
es_ES: "Gestionar certificados SSL"
fr_FR: "Gérer les certificats SSL"
pl_PL: "Zarządzaj certyfikatami SSL"
about.manage-ssl-vhost-proxy: about.manage-ssl-vhost-proxy:
en_US: "Manage SSL vhost proxy" en_US: "Manage SSL vhost proxy"
de_DE: "SSL-vhost-Proxy verwalten" de_DE: "SSL-vhost-Proxy verwalten"
@@ -5241,13 +4973,6 @@ about.publish-s9pk:
fr_FR: "Publier s9pk dans le bucket S3 et indexer dans le registre" fr_FR: "Publier s9pk dans le bucket S3 et indexer dans le registre"
pl_PL: "Opublikuj s9pk do bucketu S3 i zindeksuj w rejestrze" pl_PL: "Opublikuj s9pk do bucketu S3 i zindeksuj w rejestrze"
about.select-s9pk-for-device:
en_US: "Select the best compatible s9pk for a target device"
de_DE: "Das beste kompatible s9pk für ein Zielgerät auswählen"
es_ES: "Seleccionar el s9pk más compatible para un dispositivo destino"
fr_FR: "Sélectionner le meilleur s9pk compatible pour un appareil cible"
pl_PL: "Wybierz najlepiej kompatybilny s9pk dla urządzenia docelowego"
about.rebuild-service-container: about.rebuild-service-container:
en_US: "Rebuild service container" en_US: "Rebuild service container"
de_DE: "Dienst-Container neu erstellen" de_DE: "Dienst-Container neu erstellen"
@@ -5416,13 +5141,6 @@ about.remove-version-signer:
fr_FR: "Supprimer le signataire de version" fr_FR: "Supprimer le signataire de version"
pl_PL: "Usuń sygnatariusza wersji" pl_PL: "Usuń sygnatariusza wersji"
about.remove-vhost-passthrough:
en_US: "Remove vhost passthrough"
de_DE: "Vhost-Passthrough entfernen"
es_ES: "Eliminar passthrough de vhost"
fr_FR: "Supprimer un passthrough vhost"
pl_PL: "Usuń passthrough vhost"
about.remove-wifi-network: about.remove-wifi-network:
en_US: "Remove a wifi network" en_US: "Remove a wifi network"
de_DE: "Ein WLAN-Netzwerk entfernen" de_DE: "Ein WLAN-Netzwerk entfernen"
@@ -5465,12 +5183,12 @@ about.reset-user-interface-password:
fr_FR: "Réinitialiser le mot de passe de l'interface utilisateur" fr_FR: "Réinitialiser le mot de passe de l'interface utilisateur"
pl_PL: "Zresetuj hasło interfejsu użytkownika" pl_PL: "Zresetuj hasło interfejsu użytkownika"
about.uninitialize-webserver: about.reset-webserver:
en_US: "Uninitialize the webserver" en_US: "Reset the webserver"
de_DE: "Den Webserver deinitialisieren" de_DE: "Den Webserver zurücksetzen"
es_ES: "Desinicializar el servidor web" es_ES: "Restablecer el servidor web"
fr_FR: "Désinitialiser le serveur web" fr_FR: "initialiser le serveur web"
pl_PL: "Zdezinicjalizuj serwer internetowy" pl_PL: "Zresetuj serwer internetowy"
about.restart-server: about.restart-server:
en_US: "Restart the server" en_US: "Restart the server"
@@ -5486,13 +5204,6 @@ about.restart-service:
fr_FR: "Redémarrer un service" fr_FR: "Redémarrer un service"
pl_PL: "Uruchom ponownie usługę" pl_PL: "Uruchom ponownie usługę"
about.restart-tunnel:
en_US: "Reboot the tunnel server"
de_DE: "Den Tunnel-Server neu starten"
es_ES: "Reiniciar el servidor del túnel"
fr_FR: "Redémarrer le serveur tunnel"
pl_PL: "Uruchom ponownie serwer tunelu"
about.restore-packages-from-backup: about.restore-packages-from-backup:
en_US: "Restore packages from backup" en_US: "Restore packages from backup"
de_DE: "Pakete aus Backup wiederherstellen" de_DE: "Pakete aus Backup wiederherstellen"
@@ -5507,13 +5218,6 @@ about.run-service-action:
fr_FR: "Exécuter une action de service" fr_FR: "Exécuter une action de service"
pl_PL: "Uruchom akcję usługi" pl_PL: "Uruchom akcję usługi"
about.set-address-enabled-for-binding:
en_US: "Set a gateway address enabled for a binding"
de_DE: "Gateway-Adresse für eine Bindung aktivieren"
es_ES: "Establecer una dirección de gateway habilitada para un vínculo"
fr_FR: "Définir une adresse de passerelle activée pour une liaison"
pl_PL: "Ustaw adres bramy jako włączony dla powiązania"
about.set-country: about.set-country:
en_US: "Set the country" en_US: "Set the country"
de_DE: "Das Land festlegen" de_DE: "Das Land festlegen"
@@ -5521,20 +5225,6 @@ about.set-country:
fr_FR: "Définir le pays" fr_FR: "Définir le pays"
pl_PL: "Ustaw kraj" pl_PL: "Ustaw kraj"
about.set-default-outbound-gateway:
en_US: "Set the default outbound gateway"
de_DE: "Standard-Ausgangs-Gateway festlegen"
es_ES: "Establecer la puerta de enlace de salida predeterminada"
fr_FR: "Définir la passerelle sortante par défaut"
pl_PL: "Ustaw domyślną bramę wychodzącą"
about.set-echoip-urls:
en_US: "Set the Echo IP service URLs"
de_DE: "Die Echo-IP-Dienst-URLs festlegen"
es_ES: "Establecer las URLs del servicio Echo IP"
fr_FR: "Définir les URLs du service Echo IP"
pl_PL: "Ustaw adresy URL usługi Echo IP"
about.set-hostname: about.set-hostname:
en_US: "Set the server hostname" en_US: "Set the server hostname"
de_DE: "Den Server-Hostnamen festlegen" de_DE: "Den Server-Hostnamen festlegen"
@@ -5570,13 +5260,6 @@ about.set-listen-address-for-webserver:
fr_FR: "Définir l'adresse d'écoute du serveur web" fr_FR: "Définir l'adresse d'écoute du serveur web"
pl_PL: "Ustaw adres nasłuchiwania serwera internetowego" pl_PL: "Ustaw adres nasłuchiwania serwera internetowego"
about.set-outbound-gateway-package:
en_US: "Set the outbound gateway for a package"
de_DE: "Ausgangs-Gateway für ein Paket festlegen"
es_ES: "Establecer la puerta de enlace de salida para un paquete"
fr_FR: "Définir la passerelle sortante pour un package"
pl_PL: "Ustaw bramę wychodzącą dla pakietu"
about.set-registry-icon: about.set-registry-icon:
en_US: "Set the registry icon" en_US: "Set the registry icon"
de_DE: "Das Registry-Symbol festlegen" de_DE: "Das Registry-Symbol festlegen"
@@ -5675,13 +5358,6 @@ about.stop-service:
fr_FR: "Arrêter un service" fr_FR: "Arrêter un service"
pl_PL: "Zatrzymaj usługę" pl_PL: "Zatrzymaj usługę"
about.ssl-generate-certificate:
en_US: "Generate an SSL certificate from the system root CA"
de_DE: "SSL-Zertifikat von der System-Root-CA generieren"
es_ES: "Generar un certificado SSL desde la CA raíz del sistema"
fr_FR: "Générer un certificat SSL depuis l'autorité racine du système"
pl_PL: "Wygeneruj certyfikat SSL z głównego CA systemu"
about.teardown-rebuild-containers: about.teardown-rebuild-containers:
en_US: "Teardown and rebuild containers" en_US: "Teardown and rebuild containers"
de_DE: "Container abbauen und neu erstellen" de_DE: "Container abbauen und neu erstellen"
@@ -5752,13 +5428,6 @@ about.update-firmware:
fr_FR: "Mettre à jour le firmware" fr_FR: "Mettre à jour le firmware"
pl_PL: "Zaktualizuj oprogramowanie układowe" pl_PL: "Zaktualizuj oprogramowanie układowe"
about.update-port-forward-label:
en_US: "Update the label of a port forward"
de_DE: "Bezeichnung einer Portweiterleitung aktualisieren"
es_ES: "Actualizar la etiqueta de un reenvío de puerto"
fr_FR: "Mettre à jour le libellé d'une redirection de port"
pl_PL: "Zaktualizuj etykietę przekierowania portu"
about.view-edit-gateway-configs: about.view-edit-gateway-configs:
en_US: "View and edit gateway configurations" en_US: "View and edit gateway configurations"
de_DE: "Gateway-Konfigurationen anzeigen und bearbeiten" de_DE: "Gateway-Konfigurationen anzeigen und bearbeiten"

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-get-pubkey 1 "get-pubkey "
.SH NAME
start\-cli\-auth\-get\-pubkey \- Get the public key from the server
.SH SYNOPSIS
\fBstart\-cli auth get\-pubkey\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Get the public key from the server
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-login 1 "login "
.SH NAME
start\-cli\-auth\-login \- Login to a new auth session
.SH SYNOPSIS
\fBstart\-cli auth login\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Login to a new auth session
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-logout 1 "logout "
.SH NAME
start\-cli\-auth\-logout \- Logout from current auth session
.SH SYNOPSIS
\fBstart\-cli auth logout\fR [\fB\-h\fR|\fB\-\-help\fR] <\fISESSION\fR>
.SH DESCRIPTION
Logout from current auth session
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fISESSION\fR>

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-reset-password 1 "reset-password "
.SH NAME
start\-cli\-auth\-reset\-password \- Reset the password
.SH SYNOPSIS
\fBstart\-cli auth reset\-password\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Reset the password
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-session-kill 1 "kill "
.SH NAME
start\-cli\-auth\-session\-kill \- Terminate auth sessions
.SH SYNOPSIS
\fBstart\-cli auth session kill\fR [\fB\-h\fR|\fB\-\-help\fR] [\fIIDS\fR]
.SH DESCRIPTION
Terminate auth sessions
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
[\fIIDS\fR]
Session identifiers

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-session-list 1 "list "
.SH NAME
start\-cli\-auth\-session\-list \- Display all auth sessions
.SH SYNOPSIS
\fBstart\-cli auth session list\fR [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display all auth sessions
.SH OPTIONS
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,20 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth-session 1 "session "
.SH NAME
start\-cli\-auth\-session \- List or kill auth sessions
.SH SYNOPSIS
\fBstart\-cli auth session\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
List or kill auth sessions
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-auth\-session\-kill(1)
Terminate auth sessions
.TP
start\-cli\-auth\-session\-list(1)
Display all auth sessions

View File

@@ -1,29 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-auth 1 "auth "
.SH NAME
start\-cli\-auth \- Commands related to Authentication i.e. login, logout
.SH SYNOPSIS
\fBstart\-cli auth\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands related to Authentication i.e. login, logout
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-auth\-get\-pubkey(1)
Get the public key from the server
.TP
start\-cli\-auth\-login(1)
Login to a new auth session
.TP
start\-cli\-auth\-logout(1)
Logout from current auth session
.TP
start\-cli\-auth\-reset\-password(1)
Reset the password
.TP
start\-cli\-auth\-session(1)
List or kill auth sessions

View File

@@ -1,25 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-create 1 "create "
.SH NAME
start\-cli\-backup\-create \- Create a backup for all packages
.SH SYNOPSIS
\fBstart\-cli backup create\fR [\fB\-\-old\-password\fR] [\fB\-\-package\-ids\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fITARGET_ID\fR> <\fIPASSWORD\fR>
.SH DESCRIPTION
Create a backup for all packages
.SH OPTIONS
.TP
\fB\-\-old\-password\fR \fI<OLD_PASSWORD>\fR
Previous backup password
.TP
\fB\-\-package\-ids\fR \fI<PACKAGE_IDS>\fR
Package IDs to include in backup
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fITARGET_ID\fR>
Backup target identifier
.TP
<\fIPASSWORD\fR>
Password for backup encryption

View File

@@ -1,25 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-cifs-add 1 "add "
.SH NAME
start\-cli\-backup\-target\-cifs\-add \- Add a new backup target
.SH SYNOPSIS
\fBstart\-cli backup target cifs add\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIHOSTNAME\fR> <\fIPATH\fR> <\fIUSERNAME\fR> [\fIPASSWORD\fR]
.SH DESCRIPTION
Add a new backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIHOSTNAME\fR>
CIFS server hostname
.TP
<\fIPATH\fR>
Path on the CIFS share
.TP
<\fIUSERNAME\fR>
CIFS authentication username
.TP
[\fIPASSWORD\fR]
CIFS authentication password

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-cifs-remove 1 "remove "
.SH NAME
start\-cli\-backup\-target\-cifs\-remove \- Remove existing backup target
.SH SYNOPSIS
\fBstart\-cli backup target cifs remove\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIID\fR>
.SH DESCRIPTION
Remove existing backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIID\fR>
Backup target identifier

View File

@@ -1,28 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-cifs-update 1 "update "
.SH NAME
start\-cli\-backup\-target\-cifs\-update \- Update an existing backup target
.SH SYNOPSIS
\fBstart\-cli backup target cifs update\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIID\fR> <\fIHOSTNAME\fR> <\fIPATH\fR> <\fIUSERNAME\fR> [\fIPASSWORD\fR]
.SH DESCRIPTION
Update an existing backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIID\fR>
Backup target identifier
.TP
<\fIHOSTNAME\fR>
CIFS server hostname
.TP
<\fIPATH\fR>
Path on the CIFS share
.TP
<\fIUSERNAME\fR>
CIFS authentication username
.TP
[\fIPASSWORD\fR]
CIFS authentication password

View File

@@ -1,23 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-cifs 1 "cifs "
.SH NAME
start\-cli\-backup\-target\-cifs \- Add, remove, or update a backup target
.SH SYNOPSIS
\fBstart\-cli backup target cifs\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Add, remove, or update a backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-backup\-target\-cifs\-add(1)
Add a new backup target
.TP
start\-cli\-backup\-target\-cifs\-remove(1)
Remove existing backup target
.TP
start\-cli\-backup\-target\-cifs\-update(1)
Update an existing backup target

View File

@@ -1,25 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-info 1 "info "
.SH NAME
start\-cli\-backup\-target\-info \- Display backup information for a package
.SH SYNOPSIS
\fBstart\-cli backup target info\fR [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fITARGET_ID\fR> <\fISERVER_ID\fR> <\fIPASSWORD\fR>
.SH DESCRIPTION
Display backup information for a package
.SH OPTIONS
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fITARGET_ID\fR>
Backup target identifier
.TP
<\fISERVER_ID\fR>
Unique server identifier
.TP
<\fIPASSWORD\fR>
Password for backup encryption

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-list 1 "list "
.SH NAME
start\-cli\-backup\-target\-list \- List existing backup targets
.SH SYNOPSIS
\fBstart\-cli backup target list\fR [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
List existing backup targets
.SH OPTIONS
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,25 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-mount 1 "mount "
.SH NAME
start\-cli\-backup\-target\-mount \- Mount a backup target
.SH SYNOPSIS
\fBstart\-cli backup target mount\fR [\fB\-\-server\-id\fR] [\fB\-\-allow\-partial\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fITARGET_ID\fR> <\fIPASSWORD\fR>
.SH DESCRIPTION
Mount a backup target
.SH OPTIONS
.TP
\fB\-\-server\-id\fR \fI<SERVER_ID>\fR
Unique server identifier
.TP
\fB\-\-allow\-partial\fR
Leave media mounted even if backupfs fails to mount
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fITARGET_ID\fR>
Backup target identifier
.TP
<\fIPASSWORD\fR>
Password for backup encryption

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target-umount 1 "umount "
.SH NAME
start\-cli\-backup\-target\-umount \- Unmount a backup target
.SH SYNOPSIS
\fBstart\-cli backup target umount\fR [\fB\-h\fR|\fB\-\-help\fR] [\fITARGET_ID\fR]
.SH DESCRIPTION
Unmount a backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
[\fITARGET_ID\fR]
Backup target identifier

View File

@@ -1,29 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup-target 1 "target "
.SH NAME
start\-cli\-backup\-target \- Commands related to a backup target
.SH SYNOPSIS
\fBstart\-cli backup target\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands related to a backup target
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-backup\-target\-cifs(1)
Add, remove, or update a backup target
.TP
start\-cli\-backup\-target\-info(1)
Display backup information for a package
.TP
start\-cli\-backup\-target\-list(1)
List existing backup targets
.TP
start\-cli\-backup\-target\-mount(1)
Mount a backup target
.TP
start\-cli\-backup\-target\-umount(1)
Unmount a backup target

View File

@@ -1,20 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-backup 1 "backup "
.SH NAME
start\-cli\-backup \- Commands related to backup creation and backup targets
.SH SYNOPSIS
\fBstart\-cli backup\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands related to backup creation and backup targets
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-backup\-create(1)
Create a backup for all packages
.TP
start\-cli\-backup\-target(1)
Commands related to a backup target

View File

@@ -1,22 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-db-apply 1 "apply "
.SH NAME
start\-cli\-db\-apply \- Update a database record
.SH SYNOPSIS
\fBstart\-cli db apply\fR [\fB\-\-allow\-model\-mismatch\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fIEXPR\fR> [\fIPATH\fR]
.SH DESCRIPTION
Update a database record
.SH OPTIONS
.TP
\fB\-\-allow\-model\-mismatch\fR
Allow database model mismatch
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIEXPR\fR>
Database patch expression to apply
.TP
[\fIPATH\fR]
Path to the database

View File

@@ -1,22 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-db-dump 1 "dump "
.SH NAME
start\-cli\-db\-dump \- Filter and query the database
.SH SYNOPSIS
\fBstart\-cli db dump\fR [\fB\-p\fR|\fB\-\-include\-private\fR] [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIPATH\fR]
.SH DESCRIPTION
Filter and query the database
.SH OPTIONS
.TP
\fB\-p\fR, \fB\-\-include\-private\fR
Include private data in output
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
[\fIPATH\fR]
Path to the database

View File

@@ -1,22 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-db-put-ui 1 "ui "
.SH NAME
start\-cli\-db\-put\-ui \- Add path and value to db
.SH SYNOPSIS
\fBstart\-cli db put ui\fR [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fIPOINTER\fR> <\fIVALUE\fR>
.SH DESCRIPTION
Add path and value to db
.SH OPTIONS
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIPOINTER\fR>
JSON pointer to specific value
.TP
<\fIVALUE\fR>
JSON value to set

View File

@@ -1,17 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-db-put 1 "put "
.SH NAME
start\-cli\-db\-put \- Command for adding UI record to db
.SH SYNOPSIS
\fBstart\-cli db put\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Command for adding UI record to db
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-db\-put\-ui(1)
Add path and value to db

View File

@@ -1,23 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-db 1 "db "
.SH NAME
start\-cli\-db \- Commands to interact with the db i.e. dump, put, apply
.SH SYNOPSIS
\fBstart\-cli db\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands to interact with the db i.e. dump, put, apply
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-db\-apply(1)
Update a database record
.TP
start\-cli\-db\-dump(1)
Filter and query the database
.TP
start\-cli\-db\-put(1)
Command for adding UI record to db

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-disk-forget 1 "forget "
.SH NAME
start\-cli\-diagnostic\-disk\-forget \- Remove disk filesystem
.SH SYNOPSIS
\fBstart\-cli diagnostic disk forget\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Remove disk filesystem
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-disk-repair 1 "repair "
.SH NAME
start\-cli\-diagnostic\-disk\-repair \- Repair disk corruption
.SH SYNOPSIS
\fBstart\-cli diagnostic disk repair\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Repair disk corruption
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,20 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-disk 1 "disk "
.SH NAME
start\-cli\-diagnostic\-disk \- Command to remove disk from filesystem
.SH SYNOPSIS
\fBstart\-cli diagnostic disk\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Command to remove disk from filesystem
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-diagnostic\-disk\-forget(1)
Remove disk filesystem
.TP
start\-cli\-diagnostic\-disk\-repair(1)
Repair disk corruption

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-error 1 "error "
.SH NAME
start\-cli\-diagnostic\-error \- Display diagnostic error
.SH SYNOPSIS
\fBstart\-cli diagnostic error\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display diagnostic error
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,28 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-kernel-logs 1 "kernel-logs "
.SH NAME
start\-cli\-diagnostic\-kernel\-logs \- Display kernel logs
.SH SYNOPSIS
\fBstart\-cli diagnostic kernel\-logs\fR [\fB\-l\fR|\fB\-\-limit\fR] [\fB\-c\fR|\fB\-\-cursor\fR] [\fB\-b\fR|\fB\-\-boot\fR] [\fB\-B\fR|\fB\-\-before\fR] [\fB\-f\fR|\fB\-\-follow\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display kernel logs
.SH OPTIONS
.TP
\fB\-l\fR, \fB\-\-limit\fR \fI<LIMIT>\fR
Maximum number of log entries
.TP
\fB\-c\fR, \fB\-\-cursor\fR \fI<CURSOR>\fR
Start from this cursor position
.TP
\fB\-b\fR, \fB\-\-boot\fR \fI<BOOT>\fR
Filter logs by boot ID
.TP
\fB\-B\fR, \fB\-\-before\fR
Show logs before the cursor position
.TP
\fB\-f\fR, \fB\-\-follow\fR
Follow log output in real\-time
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,28 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-logs 1 "logs "
.SH NAME
start\-cli\-diagnostic\-logs \- Display OS logs
.SH SYNOPSIS
\fBstart\-cli diagnostic logs\fR [\fB\-l\fR|\fB\-\-limit\fR] [\fB\-c\fR|\fB\-\-cursor\fR] [\fB\-b\fR|\fB\-\-boot\fR] [\fB\-B\fR|\fB\-\-before\fR] [\fB\-f\fR|\fB\-\-follow\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display OS logs
.SH OPTIONS
.TP
\fB\-l\fR, \fB\-\-limit\fR \fI<LIMIT>\fR
Maximum number of log entries
.TP
\fB\-c\fR, \fB\-\-cursor\fR \fI<CURSOR>\fR
Start from this cursor position
.TP
\fB\-b\fR, \fB\-\-boot\fR \fI<BOOT>\fR
Filter logs by boot ID
.TP
\fB\-B\fR, \fB\-\-before\fR
Show logs before the cursor position
.TP
\fB\-f\fR, \fB\-\-follow\fR
Follow log output in real\-time
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-rebuild 1 "rebuild "
.SH NAME
start\-cli\-diagnostic\-rebuild \- Teardown and rebuild containers
.SH SYNOPSIS
\fBstart\-cli diagnostic rebuild\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Teardown and rebuild containers
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic-restart 1 "restart "
.SH NAME
start\-cli\-diagnostic\-restart \- Restart the server
.SH SYNOPSIS
\fBstart\-cli diagnostic restart\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Restart the server
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,32 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-diagnostic 1 "diagnostic "
.SH NAME
start\-cli\-diagnostic \- Commands to display logs, restart the server, etc
.SH SYNOPSIS
\fBstart\-cli diagnostic\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands to display logs, restart the server, etc
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-diagnostic\-disk(1)
Command to remove disk from filesystem
.TP
start\-cli\-diagnostic\-error(1)
Display diagnostic error
.TP
start\-cli\-diagnostic\-kernel\-logs(1)
Display kernel logs
.TP
start\-cli\-diagnostic\-logs(1)
Display OS logs
.TP
start\-cli\-diagnostic\-rebuild(1)
Teardown and rebuild containers
.TP
start\-cli\-diagnostic\-restart(1)
Restart the server

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-disk-list 1 "list "
.SH NAME
start\-cli\-disk\-list \- List disk information
.SH SYNOPSIS
\fBstart\-cli disk list\fR [\fB\-\-format\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
List disk information
.SH OPTIONS
.TP
\fB\-\-format\fR
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-disk-repair 1 "repair "
.SH NAME
start\-cli\-disk\-repair \- Repair disk corruption
.SH SYNOPSIS
\fBstart\-cli disk repair\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Repair disk corruption
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,20 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-disk 1 "disk "
.SH NAME
start\-cli\-disk \- Commands for listing disk info and repairing
.SH SYNOPSIS
\fBstart\-cli disk\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands for listing disk info and repairing
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-disk\-list(1)
List disk information
.TP
start\-cli\-disk\-repair(1)
Repair disk corruption

View File

@@ -1,16 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-echo 1 "echo "
.SH NAME
start\-cli\-echo \- Echo a message back
.SH SYNOPSIS
\fBstart\-cli echo\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIMESSAGE\fR>
.SH DESCRIPTION
Echo a message back
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fIMESSAGE\fR>
Message to echo back

View File

@@ -1,32 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-flash-os 1 "flash-os "
.SH NAME
start\-cli\-flash\-os \- Flash StartOS to a drive
.SH SYNOPSIS
\fBstart\-cli flash\-os\fR [\fB\-\-efi\fR] [\fB\-h\fR|\fB\-\-help\fR] <\fISQUASHFS\fR> <\fIDISK\fR>
.SH DESCRIPTION
Flash StartOS to a drive
.SH OPTIONS
.TP
\fB\-\-efi\fR \fI<EFI>\fR
Use EFI boot mode
.br
.br
\fIPossible values:\fR
.RS 14
.IP \(bu 2
true
.IP \(bu 2
false
.RE
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.TP
<\fISQUASHFS\fR>
Path to squashfs image file
.TP
<\fIDISK\fR>
Target disk for installation

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-git-info 1 "git-info "
.SH NAME
start\-cli\-git\-info \- Display the git hash of this build
.SH SYNOPSIS
\fBstart\-cli git\-info\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display the git hash of this build
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,28 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-init-kernel-logs 1 "kernel-logs "
.SH NAME
start\-cli\-init\-kernel\-logs \- Display kernel logs
.SH SYNOPSIS
\fBstart\-cli init kernel\-logs\fR [\fB\-l\fR|\fB\-\-limit\fR] [\fB\-c\fR|\fB\-\-cursor\fR] [\fB\-b\fR|\fB\-\-boot\fR] [\fB\-B\fR|\fB\-\-before\fR] [\fB\-f\fR|\fB\-\-follow\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display kernel logs
.SH OPTIONS
.TP
\fB\-l\fR, \fB\-\-limit\fR \fI<LIMIT>\fR
Maximum number of log entries
.TP
\fB\-c\fR, \fB\-\-cursor\fR \fI<CURSOR>\fR
Start from this cursor position
.TP
\fB\-b\fR, \fB\-\-boot\fR \fI<BOOT>\fR
Filter logs by boot ID
.TP
\fB\-B\fR, \fB\-\-before\fR
Show logs before the cursor position
.TP
\fB\-f\fR, \fB\-\-follow\fR
Follow log output in real\-time
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-init-key 1 "init-key "
.SH NAME
start\-cli\-init\-key \- Create a new developer key
.SH SYNOPSIS
\fBstart\-cli init\-key\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Create a new developer key
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,28 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-init-logs 1 "logs "
.SH NAME
start\-cli\-init\-logs \- Display OS logs
.SH SYNOPSIS
\fBstart\-cli init logs\fR [\fB\-l\fR|\fB\-\-limit\fR] [\fB\-c\fR|\fB\-\-cursor\fR] [\fB\-b\fR|\fB\-\-boot\fR] [\fB\-B\fR|\fB\-\-before\fR] [\fB\-f\fR|\fB\-\-follow\fR] [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Display OS logs
.SH OPTIONS
.TP
\fB\-l\fR, \fB\-\-limit\fR \fI<LIMIT>\fR
Maximum number of log entries
.TP
\fB\-c\fR, \fB\-\-cursor\fR \fI<CURSOR>\fR
Start from this cursor position
.TP
\fB\-b\fR, \fB\-\-boot\fR \fI<BOOT>\fR
Filter logs by boot ID
.TP
\fB\-B\fR, \fB\-\-before\fR
Show logs before the cursor position
.TP
\fB\-f\fR, \fB\-\-follow\fR
Follow log output in real\-time
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-init-subscribe 1 "subscribe "
.SH NAME
start\-cli\-init\-subscribe \- Get initialization progress
.SH SYNOPSIS
\fBstart\-cli init subscribe\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Get initialization progress
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,23 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-init 1 "init "
.SH NAME
start\-cli\-init \- Commands for initialization
.SH SYNOPSIS
\fBstart\-cli init\fR [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
.SH DESCRIPTION
Commands for initialization
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
start\-cli\-init\-kernel\-logs(1)
Display kernel logs
.TP
start\-cli\-init\-logs(1)
Display OS logs
.TP
start\-cli\-init\-subscribe(1)
Get initialization progress

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-kiosk-disable 1 "disable "
.SH NAME
start\-cli\-kiosk\-disable \- Disable kiosk mode
.SH SYNOPSIS
\fBstart\-cli kiosk disable\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Disable kiosk mode
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

View File

@@ -1,13 +0,0 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH start-cli-kiosk-enable 1 "enable "
.SH NAME
start\-cli\-kiosk\-enable \- Enable kiosk mode
.SH SYNOPSIS
\fBstart\-cli kiosk enable\fR [\fB\-h\fR|\fB\-\-help\fR]
.SH DESCRIPTION
Enable kiosk mode
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help

Some files were not shown because too many files have changed in this diff Show More