Compare commits

...

1507 Commits

Author SHA1 Message Date
Aiden McClelland
5aa9c045e1 fix live-build resolv.conf (#3035)
* fix live-build resolv.conf

* improved debuggability
2025-09-24 22:44:25 -06:00
Matt Hill
6f1900f3bb limit adding gateway to StartTunnel, better copy around Tor SSL (#3033)
* limit adding gateway to StartTunnel, better copy around Tor SSL

* properly differentiate ssl

* exclude disconnected gateways

* better error handling

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-09-24 13:22:26 -06:00
Aiden McClelland
bc62de795e bugfixes for alpha.10 (#3032)
* bugfixes for alpha.10

* bump raspi kernel

* rpi kernel bump

* alpha.11
2025-09-23 22:42:17 +00:00
Alex Inkin
c62ca4b183 fix: make long dropdown options wrap (#3031) 2025-09-21 06:06:33 -06:00
Alex Inkin
876e5bc683 fix: fix overflowing interface table (#3027) 2025-09-20 07:10:58 -06:00
Alex Inkin
b99f3b73cd fix: make logs page take up all space (#3030) 2025-09-20 07:10:28 -06:00
Matt Hill
7eecf29449 fix dep error display, show starting if any health check starting, show disabled health check message, remove loader from service list, animated dots, better color (#3025)
* refector addresses to not need gateways array

* fix dep error display, show starting if any health check starting, show disabled health check message, remove loader from service list, animated dots, better color

* fix: fix action results textfields

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2025-09-17 10:32:20 -06:00
Mariusz Kogen
1d331d7810 Fix file permissions for developer key and auth cookie (#3024)
* fix permissions

* include read for group
2025-09-16 09:09:33 -06:00
Aiden McClelland
68414678d8 sdk updates; beta.39 (#3022)
* sdk updates; beta.39

* beta.40
2025-09-11 15:47:48 -06:00
Aiden McClelland
2f6b9dac26 Bugfix/dns recursion (#3023)
* fix dns recursion and localhost

* additional fix
2025-09-11 15:47:38 -06:00
Aiden McClelland
d1812d875b fix dns recursion and localhost (#3021) 2025-09-11 12:35:12 -06:00
Aiden McClelland
723dea100f add more gateway info to hostnameInfo (#3019) 2025-09-10 12:16:35 -06:00
Matt Hill
c4419ed31f show correct gateway name when adding public domain 2025-09-10 09:57:39 -06:00
Matt Hill
754ab86e51 only show http for tor if protocol is http 2025-09-10 09:36:03 -06:00
Mariusz Kogen
04dab532cd Motd Redesign - Visual and Structural Upgrade (#3018)
New 040 motd
2025-09-10 06:36:27 +00:00
Matt Hill
add01ebc68 Gateways, domains, and new service interface (#3001)
* add support for inbound proxies

* backend changes

* fix file type

* proxy -> tunnel, implement backend apis

* wip start-tunneld

* add domains and gateways, remove routers, fix docs links

* dont show hidden actions

* show and test dns

* edit instead of chnage acme and change gateway

* refactor: domains page

* refactor: gateways page

* domains and acme refactor

* certificate authorities

* refactor public/private gateways

* fix fe types

* domains mostly finished

* refactor: add file control to form service

* add ip util to sdk

* domains api + migration

* start service interface page, WIP

* different options for clearnet domains

* refactor: styles for interfaces page

* minor

* better placeholder for no addresses

* start sorting addresses

* best address logic

* comments

* fix unnecessary export

* MVP of service interface page

* domains preferred

* fix: address comments

* only translations left

* wip: start-tunnel & fix build

* forms for adding domain, rework things based on new ideas

* fix: dns testing

* public domain, max width, descriptions for dns

* nix StartOS domains, implement public and private domains at interface scope

* restart tor instead of reset

* better icon for restart tor

* dns

* fix sort functions for public and private domains

* with todos

* update types

* clean up tech debt, bump dependencies

* revert to ts-rs v9

* fix all types

* fix dns form

* add missing translations

* it builds

* fix: comments (#3009)

* fix: comments

* undo default

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* fix: refactor legacy components (#3010)

* fix: comments

* fix: refactor legacy components

* remove default again

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* more translations

* wip

* fix deadlock

* coukd work

* simple renaming

* placeholder for empty service interfaces table

* honor hidden form values

* remove logs

* reason instead of description

* fix dns

* misc fixes

* implement toggling gateways for service interface

* fix showing dns records

* move status column in service list

* remove unnecessary truthy check

* refactor: refactor forms components and remove legacy Taiga UI package (#3012)

* handle wh file uploads

* wip: debugging tor

* socks5 proxy working

* refactor: fix multiple comments (#3013)

* refactor: fix multiple comments

* styling changes, add documentation to sidebar

* translations for dns page

* refactor: subtle colors

* rearrange service page

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* fix file_stream and remove non-terminating test

* clean  up logs

* support for sccache

* fix gha sccache

* more marketplace translations

* install wizard clarity

* stub hostnameInfo in migration

* fix address info after setup, fix styling on SI page, new 040 release notes

* remove tor logs from os

* misc fixes

* reset tor still not functioning...

* update ts

* minor styling and wording

* chore: some fixes (#3015)

* fix gateway renames

* different handling for public domains

* styling fixes

* whole navbar should not be clickable on service show page

* timeout getState request

* remove links from changelog

* misc fixes from pairing

* use custom name for gateway in more places

* fix dns parsing

* closes #3003

* closes #2999

* chore: some fixes (#3017)

* small copy change

* revert hardcoded error for testing

* dont require port forward if gateway is public

* use old wan ip when not available

* fix .const hanging on undefined

* fix test

* fix doc test

* fix renames

* update deps

* allow specifying dependency metadata directly

* temporarily make dependencies not cliackable in marketplace listings

* fix socks bind

* fix test

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: waterplea <alexander@inkin.ru>
2025-09-10 03:43:51 +00:00
Mariusz Kogen
1cc9a1a30b build(cli): harden build-cli.sh (zig check, env defaults, GIT_HASH) (#3016) 2025-09-09 14:18:52 -06:00
Dominion5254
92a1de7500 remove entire service package directory on hard uninstall (#3007)
* remove entire service package directory on hard uninstall

* fix package path
2025-08-12 15:46:01 -06:00
Alex Inkin
a6fedcff80 fix: extract correct manifest in updating state (#3004) 2025-08-01 22:51:38 -06:00
Alex Inkin
55eb999305 fix: update notifications design (#3000) 2025-07-29 22:17:59 -06:00
Aiden McClelland
377b7b12ce update/alpha.9 (#2988)
* import marketplac preview for sideload

* fix: improve state service (#2977)

* fix: fix sideload DI

* fix: update Angular

* fix: cleanup

* fix: fix version selection

* Bump node version to fix build for Angular

* misc fixes
- update node to v22
- fix chroot-and-upgrade access to prune-images
- don't self-migrate legacy packages
- #2985
- move dataVersion to volume folder
- remove "instructions.md" from s9pk
- add "docsUrl" to manifest

* version bump

* include flavor when clicking view listing from updates tab

* closes #2980

* fix: fix select button

* bring back ssh keys

* fix: drop 'portal' from all routes

* fix: implement longtap action to select table rows

* fix description for ssh page

* replace instructions with docsLink and refactor marketplace preview

* delete unused translations

* fix patchdb diffing algorithm

* continue refactor of marketplace lib show components

* Booting StartOS instead of Setting up your server on init

* misc fixes
- closes #2990
- closes #2987

* fix build

* docsUrl and clickable service headers

* don't cleanup after update until new service install succeeds

* update types

* misc fixes

* beta.35

* sdkversion, githash for sideload, correct logs for init, startos pubkey display

* bring back reboot button on install

* misc fixes

* beta.36

* better handling of setup and init for websocket errors

* reopen init and setup logs even on graceful closure

* better logging, misc fixes

* fix build

* dont let package stats hang

* dont show docsurl in marketplace if no docsurl

* re-add needs-config

* show error if init fails, shorten hover state on header icons

* fix operator precedemce

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Mariusz Kogen <k0gen@pm.me>
2025-07-18 18:31:12 +00:00
gStart9
ba2906a42e Fallback DNS/NTP server privacy enhancements (#2992) 2025-07-16 21:31:52 +00:00
gStart9
ee27f14be0 Update/kiosk mode firefox settings (#2973)
* Privacy settings for firefox's kiosk mode

* Re-add extensions.update.enabled, false

* Don't enable letterboxing by default
2025-07-15 20:17:52 +00:00
Aiden McClelland
46c8be63a7 0.4.0-alpha.8 (#2975) 2025-07-08 12:28:21 -06:00
Matt Hill
7ba66c419a Misc frontend fixes (#2974)
* fix dependency input warning and extra comma

* clean up buttons during install in marketplace preview

* chore: grayscale and closing action-bar

* fix prerelease precedence

* fix duplicate url for addSsl on ssl proto

* no warning for soft uninstall

* fix: stop logs from repeating disconnected status and add 1 second delay between reconnection attempts

* fix stop on reactivation of critical task

* fix: fix disconnected toast

* fix: updates styles

* fix: updates styles

* misc fixes

* beta.33

* fix updates badge and initialization of marketplace preview controls

---------

Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-07-08 12:08:27 -06:00
Aiden McClelland
340775a593 Feature/more dynamic unions (#2972)
* with validators

* more dynamic unions

* fixes from v31

* better constructor for dynamic unions

* version bump

* fix build
2025-07-01 17:40:39 -06:00
Alex Inkin
35d2ec8a44 chore: fix font in Safari (#2970) 2025-06-25 09:55:50 -04:00
Alex Inkin
2983b9950f chore: fix issues from dev channel (#2968) 2025-06-25 09:30:28 -04:00
Aiden McClelland
dbf08a6cf8 stop service if critical task activated (#2966)
filter out union lists instead of erroring
2025-06-18 22:03:27 +00:00
Alex Inkin
28f31be36f Fix/fe 6 (#2965)
* fix backup reports modal

* chore: fix comments

* chore: fix controls status

* chore: fix stale marketplace data

* slightly better registry switching

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-06-18 10:40:39 -06:00
Aiden McClelland
3ec4db0225 addHealthCheck instead of additionalHealthChecks for Daemons (#2962)
* addHealthCheck on Daemons

* fix bug that prevents domains without protocols from being deleted

* fixes from testing

* version bump

* add sdk version to UI

* fix useEntrypoint

* fix dependency health check error display

* minor fixes

* beta.29

* fixes from testing

* beta.30

* set /etc/os-release (#2918)

* remove check-monitor from kiosk (#2059)

* add units for progress (#2693)

* use new progress type

* alpha.7

* fix up pwa stuff

* fix wormhole-squashfs and prune boot (#2964)

* don't exit on expected errors

* use bash

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-06-17 17:50:01 -06:00
Matt Hill
f5688e077a misc fixes (#2961)
* fix backup reports modal

* chore: fix comments

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2025-06-17 11:22:32 -06:00
Aiden McClelland
2464d255d5 improve daemons init system (#2960)
* repeatable command launch fn

* allow js fn for daemon exec

* improve daemon init system

* fixes from testing
2025-06-06 14:35:03 -06:00
Aiden McClelland
586d950b8c update cargo deps (#2959)
* update cargo deps

* readd device info header
2025-06-05 17:17:02 -06:00
Matt Hill
e7469388cc minor fixes (#2957)
* minor fixes

* more minor touchups

* minor fix

* fix release notes display
2025-06-05 17:02:54 -06:00
Dominion5254
ab6ca8e16a Bugfix/ssl proxy to ssl (#2956)
* fix registry rm command

* fix bind with addSsl on ssl proto

* fix bind with addSsl on ssl proto

* Add pre-release version migrations

* fix os build

* add mime to package deps

* update lockfile

* more ssl fixes

* add waitFor

* improve restart lockup

* beta.26

* fix dependency health check logic

* handle missing health check

* fix port forwards

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-06-04 19:41:21 -06:00
Alex Inkin
02413a4fac Update Angular (#2952)
* fix Tor logs actually fetching od logs

* chore: update to Angular 18

* chore: update to Angular 19

* bump patchDB

* chore: update Angular

* chore: fix setup-wizard success page

* chore: fix

* chore: fix

* chore: fix

* chore: fix

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-05-30 10:34:24 -04:00
Dominion5254
05b8dd9ad8 fix registry rm command (#2955) 2025-05-27 19:00:29 -06:00
Dominion5254
29c9419a6e add nfs-common (#2954) 2025-05-27 16:11:34 -06:00
Aiden McClelland
90e61989a4 misc bugfixes for alpha.4 (#2953)
* fix lockup when stop during init

* Fix incorrect description for registry package remove command

* alpha.5

* beta.25

---------

Co-authored-by: Mariusz Kogen <k0gen@pm.me>
2025-05-23 11:23:29 -06:00
Matt Hill
b1f9f90fec Frontend fixes/improvements (#2950)
* fix Tor logs actually fetching od logs

* chore: switch from `mime-types` to `mime` for browser environment support (#2951)

* change V2 s9pk title to Legacy

* show warning for domains when not public, disable launch too

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Mariusz Kogen <k0gen@pm.me>
2025-05-23 10:45:06 -06:00
Matt Hill
b40849f672 Fix/fe bugs 3 (#2943)
* fix typeo in patch db seed

* show all registries in updates tab, fix required dependnecy display in marketplace, update browser tab title desc

* always show pointer for version select

* chore: fix comments

* support html in action desc and marketplace long desc, only show qr in action res if qr is true

* disable save if smtp creds not edited, show better smtp success message

* dont dismiss login spinner until patchDB returns

* feat: redesign of service dashboard and interface (#2946)

* feat: redesign of service dashboard and interface

* chore: comments

* re-add setup complete

* dibale launch UI when not running, re-style things, rename things

* back to 1000

* fix clearnet docs link and require password retype in setup wiz

* faster hint display

* display dependency ID if title not available

* fix migration

* better init progress view

* fix setup success page by providing VERSION and notifications page fixes

* force uninstall from service error page, soft or hard

* handle error state better

* chore: fixed for install and setup wizards

* chore: fix issues (#2949)

* enable and disable kiosk mode

* minor fixes

* fix dependency mounts

* dismissable tasks

* provide replayId

* default if health check success message is null

* look for wifi interface too

* dash for null user agent in sessions

* add disk repair to diagnostic api

---------

Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-05-21 19:04:26 -06:00
Aiden McClelland
44560c8da8 Refactor/sdk init (#2947)
* fixes for main

* refactor package initialization

* fixes from testing

* more fixes

* beta.21

* do not use instanceof

* closes #2921

* beta22

* allow disabling kiosk

* migration

* fix /etc/shadow

* actionRequest -> task

* beta.23
2025-05-21 10:24:37 -06:00
Aiden McClelland
46fd01c264 0.4.0-alpha.4 (#2948) 2025-05-20 16:11:50 -06:00
nbxl21
100695c262 Add french translation (#2945)
* Add french translation

* Remove outdated instruction

* Fix missing instructions
2025-05-17 18:10:24 -06:00
H0mer
54b5a4ae55 Update pl.ts (#2944)
Collaboration with @k0gen
2025-05-14 08:07:56 -06:00
Aiden McClelland
ffb252962b hotfix migration 2025-05-12 06:38:48 -06:00
Aiden McClelland
ae31270e63 alpha3 (#2942) 2025-05-11 07:48:32 -06:00
Matt Hill
9b2b54d585 fix osUpdate check and address parser for Tor without protocol (#2941) 2025-05-10 12:18:20 -06:00
Aiden McClelland
e1ccc583a3 0.4.0-alpha.2 (#2940) 2025-05-09 16:34:29 -06:00
Aiden McClelland
7750e33f82 misc sdk changes (#2934)
* misc sdk changes

* delete the store ☠️

* port comments

* fix build

* fix removing

* fix tests

* beta.20

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-05-09 15:10:51 -06:00
Matt Hill
d2c4741f0b use fallback icon for missing dep 2025-05-09 15:07:49 -06:00
Matt Hill
c79c4f6bde remove http timeout for sideloading 2025-05-09 14:55:11 -06:00
Lucy
3849d0d1a9 Fix/controls (#2938)
* adjust copy to display package state

* use package id for service column in notifications table

* fixes

* less translations, fix notificaiton item, remove unnecessary conditional

* tidy up

* forgot spanish

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-05-09 14:53:46 -06:00
Alex Inkin
8bd71ccd5e fix: welcome page on mobile (#2936) 2025-05-09 14:49:19 -06:00
Matt Hill
b731f7fb64 handle removing and backing up state, fix ackInstructions too (#2935) 2025-05-09 14:48:40 -06:00
Matt Hill
cd554f77f3 unbang the test bang 2025-05-09 11:06:53 -06:00
Matt Hill
8c977c51ca frontend fixes for alpha.2 (#2919)
* rmeove icon from toggles

* fix: comments

* fix: more comments

* always show public domains even if interface private, only show delete on domains

* fix: even more comments

* fix: last comments

* feat: empty state for dashboard

* rework welcome, dlete update-toast, minor

* translation improvements

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2025-05-09 10:29:17 -06:00
Aiden McClelland
a3252f9671 allow mounting files directly (#2931)
* allow mounting files directly

* fixes from testing

* more fixes
2025-05-07 12:47:45 -06:00
Aiden McClelland
9bc945f76f upcast v0 action results to v1 (#2930) 2025-05-07 09:33:26 -06:00
Aiden McClelland
f6b4dfffb6 fix shell support in package attach (#2929)
* fix package attach

* final fixes

* apply changes to launch

* Update core/startos/src/service/effects/subcontainer/sync.rs
2025-05-07 09:19:38 -06:00
Aiden McClelland
68955c29cb add transformers to file helpers (#2922)
* fix undefined handling in INI

* beta.14

* Partial -> DeepPartial in action request

* boolean laziness kills

* beta.16

* misc fixes

* file transformers

* infer validator source argument

* simplify validator

* readd toml

* beta.17

* filter undefined instead of parse/stringify

* handle arrays of objects in filterUndefined
2025-05-06 11:04:11 -06:00
Matt Hill
97e4d036dc fix adding new registry 2025-05-03 20:35:13 -06:00
Matt Hill
0f49f54c29 dont show indeterminate progress when waiting for phase 2025-05-01 18:54:14 -06:00
Aiden McClelland
828e13adbb add support for "oneshot" daemons (#2917)
* add support for "oneshot" daemons

* add docs for oneshot

* add support for runAsInit in daemon.of

* beta.13
2025-05-01 16:00:35 -06:00
Matt Hill
e6f0067728 rework installing page and add cancel install button (#2915)
* rework installing page and add cancel install button

* actually call cancel endpoint

* fix two bugs

* include translations in progress component

* cancellable installs

* fix: comments (#2916)

* fix: comments

* delete comments

* ensure trailing slash and no qp for new registry url

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* fix raspi

* bump sdk

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
2025-04-30 13:50:08 -06:00
Lucy
5c473eb9cc update marketplace url to reflect build version (#2914)
* update marketplace url to reflect build version

* adjust marketplace config

* use helper function to compare urls

* rework some registry stuff

* #2900, #2899, and other registry changes

* alpha.1

* trailing /

* add startosRegistry

* fix migration

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2025-04-29 14:12:21 -06:00
Aiden McClelland
2adf34fbaf misc fixes (#2892)
* use docker for build steps that require linux when not on linux

* use fuse for overlay

* quiet mountpoint

* node 22

* misc fixes

* make shasum more compliant

* optimize download-base-image.sh with cleaner url handling and checksum verification

* fix script

* fixes #2900

* bump node and npm versions in web readme

* Minor pl.ts fixes

* fixes in response to synapse issues

* beta.8

* update ts-matches

* beta.11

* pl.ts finetuning

---------

Co-authored-by: Mariusz Kogen <k0gen@pm.me>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-04-28 17:33:41 -06:00
Matt Hill
05dd760388 Fix links for docs (#2908)
* fix docs paths

* docsLink directive

* fix: bugs (#2909)

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
2025-04-24 14:14:08 -06:00
Mariusz Kogen
2cf4864078 Polish language refactor (#2887)
* Refactored Polish Translation

* even more language fixes and no comments
2025-04-23 10:47:43 -06:00
Lucy
df4c92672f Fix/os update version (#2890)
* dynamically set a registry to use for os updates

* fix os updates response type

* fix saving high score

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-04-23 07:17:46 -06:00
Alex Inkin
5b173315f9 fix: store language properly (#2891) 2025-04-23 07:17:18 -06:00
Aiden McClelland
c85ea7d8fa sdk beta.6 (#2885)
beta.6
2025-04-22 12:00:34 -06:00
Alex Inkin
113154702f fix: fix logs overflow (#2888) 2025-04-22 08:58:20 -06:00
Lucy
33ae46f76a add proxima nova font (#2883)
* add proxima nova font

* update to woff files

* clean up defaults
2025-04-21 11:30:38 -06:00
Matt Hill
27272680a2 Bugfix/040 UI (#2881)
* fix sideload and install flow

* move updates chevron inside upddate button

* update dictionaries to include langauge names

* fix: address todos (#2880)

* fix: address todos

* fix enlgish translation

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* use existing translation, no need to duplicate

* fix: update dialog and other fixes (#2882)

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-04-21 10:57:12 -06:00
Matt Hill
b1621f6b34 Copy changes for 040 release (#2874)
* update 040 changelog

* remove post_up from 036-alpha6

* backend copy updates

* beta.4

* beta.5

* fix spelling

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-04-21 09:43:35 -06:00
Aiden McClelland
2c65033c0a Feature/sdk improvements (#2879)
* sdk improvements

* subcontainer fixes, disable wifi on migration if not in use, filterable interfaces
2025-04-18 14:11:13 -06:00
Matt Hill
dcfbaa9243 fix start bug in service dashboard 2025-04-17 21:29:08 -06:00
Matt Hill
accef65ede bug fixes (#2878)
* bug fixes, wip

* revert tranlstion
2025-04-17 21:06:50 -06:00
Alex Inkin
50755d8ba3 Refactor i18n approach (#2875)
* Refactor i18n approach

* chore: move to shared

* chore: add default

* create DialogService and update LoadingService (#2876)

* complete translation infra for ui project, currently broken

* cleanup and more dictionaries

* chore: fix

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-04-17 09:00:59 -06:00
Aiden McClelland
47b6509f70 sdk improvements (#2877) 2025-04-16 12:53:10 -06:00
Aiden McClelland
89f3fdc05f reduce task leaking (#2868)
* reduce task leaking

* fix onLeaveContext
2025-04-16 11:00:46 -06:00
Matt Hill
03f8b73627 minor web cleanup chores 2025-04-13 13:03:51 -06:00
Matt Hill
2e6e9635c3 fix a few, more to go (#2869)
* fix a few, more to go

* chore: comments (#2871)

* chore: comments

* chore: typo

* chore: stricter typescript (#2872)

* chore: comments

* chore: stricter typescript

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* minor styling

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
2025-04-12 09:53:03 -06:00
Aiden McClelland
6a312e3fdd Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2025-04-11 13:03:55 -06:00
Aiden McClelland
79dbbdf6b4 fix mounts for pre-existing subcontainers (#2870)
* fix mounts for pre-existing subcontainers

* don't error on missing assets
2025-04-11 19:03:25 +00:00
Aiden McClelland
0e8961efe3 Merge branch 'master' into next/major 2025-04-10 15:50:29 -06:00
Matt Hill
fc2be42418 sideload wip, websockets, styling, multiple todos (#2865)
* sideload wip, websockets, styling, multiple todos

* sideload

* misc backend updates

* chore: comments

* prep for license and instructions display

* comment for Matt

* s9pk updates and 040 sdk

* fix dependency error for actions

* 0.4.0-beta.1

* beta.2

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2025-04-10 19:51:05 +00:00
Aiden McClelland
ab4336cfd7 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2025-04-07 14:00:42 -06:00
Aiden McClelland
20d3b5288c sdk tweaks (#2858)
* sdk tweaks

* beta.20

* alpha.18
2025-04-07 19:55:38 +00:00
w3irdrobot
63a29d3a4a update github workflow actions to most recent versions (#2852) 2025-04-07 19:53:23 +00:00
Alex Inkin
31856d9895 chore: comments (#2863) 2025-04-06 07:18:01 -06:00
Alex Inkin
f51dcf23d6 feat: refactor metrics (#2861) 2025-03-31 14:22:54 -06:00
Mariusz Kogen
6ecaeb4fde fix initiall setup as user and clear messaging (#2848)
* fix initiall setup as user and clear messaging

* fix this and that :)

* add IPv6 support to validate_ip function

* Use vpn-clearnet as name for the interface

* Rebrand and finish with docs link

* set static clearnet name

* Magic clearnet to the end :D

* change the command name

* the name is magic-clearnet

* wireguard-vps-proxy-setup

* one more fix
2025-03-30 16:04:34 +02:00
Alex Inkin
1883c9666e feat: refactor updates (#2860) 2025-03-29 12:50:23 -06:00
Matt Hill
4b4cf76641 remove ssh, deprecate wifi (#2859) 2025-03-28 14:38:49 -06:00
Lucy
0016b4bd72 allow ids to include numbers (#2857) 2025-03-28 16:59:48 +00:00
Alex Inkin
495bbecc01 feat: refactor logs (#2856)
* feat: refactor logs

* download root ca, minor transaltions, better interfaces buttons

* chore: comments

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-03-28 07:02:06 -06:00
Alex Inkin
e6af7e9885 feat: finalize desktop and mobile design of system routes (#2855)
* feat: finalize desktop and mobile design of system routes

* clean up messaging and mobile tabbar utilities

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-03-27 06:41:47 -06:00
w3irdrobot
182b8c2283 update time dependency in core (#2850) 2025-03-25 16:49:50 +00:00
Alex Inkin
5318cccc5f feat: add i18n infrastructure (#2854)
* feat: add i18n infrastructure

* store langauge selection to patchDB ui section

* feat: react to patchdb language change

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-03-25 05:30:35 -06:00
Alex Inkin
99739575d4 chore: refactor system settings routes (#2853)
* chore: refactor system settings routes

* switch mock to null to see backup page

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-03-23 11:03:41 -06:00
Aiden McClelland
b8ff331ccc add callback for getHost 2025-03-21 11:17:05 -06:00
Aiden McClelland
9e63f3f7c6 add callback for getContainerIp (#2851)
* add callback for getContainerIp

* register callback before retrieving info

* version bump; only use backports for linux
2025-03-20 21:54:05 +00:00
Aiden McClelland
6f9069a4fb Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2025-03-17 14:00:49 -06:00
Alex Inkin
a18ab7f1e9 chore: refactor interfaces (#2849)
* chore: refactor interfaces

* chore: fix uptime
2025-03-17 12:07:52 -06:00
Aiden McClelland
05162ca350 Bugfix/sdk misc (#2847)
* misc sdk fixes

* version bump

* formatting

* add missing dependency to root

* alpha.16 and beta.17

* beta.18
2025-03-16 09:04:10 -06:00
Alex Inkin
be0371fb11 chore: refactor settings (#2846)
* small type changes and clear todos

* handle notifications and metrics

* wip

* fixes

* migration

* dedup all urls

* better handling of clearnet ips

* add rfkill dependency

* chore: refactor settings

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-03-10 13:09:08 -06:00
Matt Hill
fa3329abf2 remove duplicate dir with pages 2025-03-07 13:18:08 -07:00
Aiden McClelland
e830fade06 Update/040 types (#2845)
* small type changes and clear todos

* handle notifications and metrics

* wip

* fixes

* migration

* dedup all urls

* better handling of clearnet ips

* add rfkill dependency

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-03-06 20:36:19 -07:00
Alex Inkin
ac392dcb96 feat: more refactors (#2844) 2025-03-05 13:30:07 -07:00
Sam Sartor
e662b2f393 Version range compression utils (#2840)
* DNF normalization wip

* a bunch of wip stuff

* it is alive!

* tests

* deduplicate strings in tests

* fix != flavor behavior & parse flavor constraints & equals shorthand for normalize

* use normalization

* more comments & fix tests not running because of bad rebase

* fix comments+tests

* slightly better comment

* fix dependency & typos

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-03-04 22:55:20 +00:00
Aiden McClelland
00a5fdf491 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2025-03-03 12:51:40 -07:00
Aiden McClelland
63bc71da13 fix issues with legacy packages (#2841)
* fix issues with legacy packages

* include non-prerelease versions within compat range

* lock sdk to corresponding os prerelease

* bump sdk version

* fixes from PR review
2025-03-03 17:30:36 +00:00
Alex Inkin
7fff9579c0 feat: redesign service route (#2835)
* feat: redesign service route

* chore: more changes

* remove automated backups and fix interface addresses

* fix rpc methods and slightly better mocks

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-02-25 08:33:35 -07:00
Aiden McClelland
737beb11f6 improve error handling (#2839) 2025-02-24 20:49:16 +00:00
Aiden McClelland
f55af7da4c hotfix for alpha.15 (#2838)
* hotfix for alpha.15

* sdk version bump
2025-02-24 20:08:02 +00:00
Aiden McClelland
80461a78b0 misc improvements (#2836)
* misc improvements

* kill proc before destroying subcontainer fs

* version bump

* beta.11

* use bind mount explicitly

* Update sdk/base/lib/Effects.ts

Co-authored-by: Dominion5254 <musashidisciple@proton.me>

---------

Co-authored-by: Dominion5254 <musashidisciple@proton.me>
2025-02-21 22:08:22 +00:00
Aiden McClelland
40d194672b change 'delete' to 'remove' everywhere to be consistent (#2834) 2025-02-21 00:14:04 +00:00
Aiden McClelland
d63341ea06 alpha.14 (#2833) 2025-02-19 01:34:01 +00:00
Aiden McClelland
df8c8dc93b fix #2813 (#2832) 2025-02-18 22:54:33 +00:00
Aiden McClelland
dd3a140cb1 fix inputspec passthrough (#2830)
* fix inputspec passthrough

* beta.9
2025-02-18 19:41:20 +00:00
Alex Inkin
1b006599cf feat: add service uptime and start style changes (#2831) 2025-02-14 11:32:30 -07:00
Aiden McClelland
44aa3cc9b5 sdk hotfix 2025-02-12 17:11:54 -07:00
Aiden McClelland
b88b24e231 sdk version bump 2025-02-12 16:05:11 -07:00
Aiden McClelland
890c31ba74 minor sdk tweaks (#2828) 2025-02-12 22:08:13 +00:00
Aiden McClelland
6dc9a11a89 misc improvements to cli (#2827)
* misc improvements to cli

* switch host shorthand to H

* simplify macro
2025-02-12 19:20:18 +00:00
Matt Hill
ce2842d365 fix patch db types and comment out future domain and proxy features 2025-02-11 21:17:20 -07:00
Matt Hill
7d1096dbd8 compiles 2025-02-10 22:41:29 -07:00
Matt Hill
95722802dc Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2025-02-08 19:19:35 -07:00
Lucy
3047dae703 Action Request updates + misc fixes (#2818)
* fix web manifest format error

* fix setting optional dependencies

* rework dependency actions to be nested

* fix styling

* fix styles

* combine action requests into same component

* only display actions header if they exist

* fix storing polyfill dependencies

* fix styling and button propagation

* fixes for setting polyfill dependencies

* revert to test

* revert required deps setting logic

* add logs and adjust logic

* test

* fix deps logic when changing config

* remove logs; deps working as expected
2025-02-08 18:11:26 -07:00
Alex Inkin
95cad7bdd9 fix: properly handle values in unions (#2826) 2025-02-08 17:36:32 -07:00
Alex Inkin
4e22f13007 Fix/unions (#2825)
* mocks for union value

* fix: properly handle values in unions

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-02-06 10:06:04 -07:00
Mariusz Kogen
04611b0ae2 feat: add ssh key auth check and config on VPS (#2824) 2025-02-05 22:14:35 +01:00
Aiden McClelland
a00f1ab549 fix version bump 2025-01-29 12:29:49 -07:00
Aiden McClelland
446b37793b miscellaneous bugfixes for alpha12 (#2823)
* miscellaneous bugfixes for alpha12

* fix deserialization of path in cifs share

* catch error in setup.status

* actually reserialize db after migration

* better progress reporting for migrations

* fix infinite drop

* fix raspi build

* fix race condition

* version bump

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-01-28 23:02:52 +00:00
Alex Inkin
b2b98643d8 feat: better form array validation (#2822) 2025-01-27 17:46:29 -07:00
Alex Inkin
b83eeeb131 feat: better form array validation (#2821) 2025-01-27 17:46:21 -07:00
Matt Hill
e8d727c07a better acme ux (#2820)
* better acme ux

* fix patching arrays... again

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-01-27 18:40:26 +00:00
Alex Inkin
bb8109f67d fix: fix resetting config and other minor issues (#2819) 2025-01-24 11:12:57 -07:00
Mariusz Kogen
e28fa26c43 Set proper group permissions and enable ssh-copy-id password prompt (#2817) 2025-01-23 14:41:44 -07:00
Matt Hill
639fc3793a dont show success message if smtp test fails 2025-01-23 13:44:29 -07:00
Mariusz Kogen
2aaae5265a feat: add WireGuard VPS setup automation script (#2810)
* feat: add WireGuard VPS setup automation script

Adds a comprehensive bash script that automates:
- SSH key setup and authentication
- WireGuard installation on remote VPS
- Configuration download and import to NetworkManager
- User-friendly CLI interface with validation
- Detailed status messages and error handling
- Instructions for exposing services via ACME/Let's Encrypt

* use cat heredoc for issue files to fix formatting

Replaces echo with cat heredoc when writing to /etc/issue and /etc/issue.net to properly preserve escape sequences and prevent unwanted newlines in login prompts.

* add convent `wg-vps-setup` symlink to PATH

* sync ssh privkey on init

* Update default ssh key location

* simplify to use existing StartOS SSH keys and fix .ssh permission

* finetune

* Switch to start9labs repo

* rename some files

* set correct ownership

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-01-22 23:53:31 +00:00
Alex Inkin
baa4c1fd25 fix: fix resetting form to default values (#2816) 2025-01-21 20:52:47 -07:00
Matt Hill
479797361e add clearnet functionality to frontend (#2814)
* add clearnet functionality to frontend

* add pattern and add sync db on rpcs

* add domain pattern

* show acme name instead of url if known

* dont blow up if domain not present after delete

* use common name for letsencrypt

* normalize urls

* refactor start-os ui net service

* backend migration and rpcs for serverInfo.host

* fix cors

* implement clearnet for main startos ui

* ability to add and remove tor addresses, including vanity

* add guard to prevent duplicate addresses

* misc bugfixes

* better heuristics for launching UIs

* fix ipv6 mocks

* fix ipv6 display bug

* rewrite url selection for launch ui

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-01-22 03:46:36 +00:00
Aiden McClelland
0a9f1d2a27 fix migration for alpha.10 (#2811)
* fix migration for alpha.10

* fix binds

* don't commit if db model does not match

* stronger guard

* better guard
2025-01-15 15:40:10 -07:00
Aiden McClelland
5e103770fd rename some things in the sdk (#2809)
* rename some things in the sdk

* fix docs

* rename some types exported from rust
2025-01-15 16:58:50 +00:00
Matt Hill
e012a29b5e add smtp to frontend (#2802)
* add smtp to frontend

* left align headers

* just email

* change all to email

* fix test-smtp api

* types

* fix email from and login address handling

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-01-15 00:32:19 +00:00
Aiden McClelland
5d759f810c Bugfix/websockets (#2808)
* retry logic for init status

* fix login flashing and sideload hanging

* add logging

* misc backend bugfixes

* use closingObserver instead

* always show reinstall button

* go back to endWith

* show error if sideload fails

* refactor more watch channels

* navigate to services page on sideload complete

* handle error closure events properly

* handle error scenario better in sideload websocket

* remove a clone

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-01-14 03:39:52 +00:00
Remco Ros
eb1f3a0ced sdk: checkPortListening: check tcp6/udp6 ports (#2763)
* sdk: checkPortListening: check tcp6/udp6 ports

* allow ipv6 if unspecified address

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2025-01-09 16:40:41 -07:00
Aiden McClelland
29e8210782 enabling support for wireguard and firewall (#2713)
* wip: enabling support for wireguard and firewall

* wip

* wip

* wip

* wip

* wip

* implement some things

* fix warning

* wip

* alpha.23

* misc fixes

* remove ufw since no longer required

* remove debug info

* add cli bindings

* debugging

* fixes

* individualized acme and privacy settings for domains and bindings

* sdk version bump

* migration

* misc fixes

* refactor Host::update

* debug info

* refactor webserver

* misc fixes

* misc fixes

* refactor port forwarding

* recheck interfaces every 5 min if no dbus event

* misc fixes and cleanup

* misc fixes
2025-01-09 16:34:34 -07:00
Dominion5254
45ca9405d3 Feat/test smtp (#2806)
* add test-smtp server subcommand

* return error is password is None

* fix return type

* borrow variables

* convert args to &str

* Tuple needs to have the same types apparently

* Clone instead

* fix formatting

* improve test email body

* Update core/startos/src/system.rs

Co-authored-by: kn0wmad <39687477+kn0wmad@users.noreply.github.com>

* add tls connection

* remove commented code

* use aidens mail-send fork

---------

Co-authored-by: kn0wmad <39687477+kn0wmad@users.noreply.github.com>
2025-01-09 20:43:53 +00:00
Alex Inkin
e6f02bf8f7 feat: hover state for navigation (#2807)
* feat: hover state for navigation

* chore: fix
2025-01-06 11:56:16 -07:00
Alex Inkin
57e75e3614 feat: implement top navigation (#2805)
* feat: implement top navigation

* chore: fix order
2024-12-30 09:07:44 -07:00
Alex Inkin
89ab67e067 fix: finish porting minor changes to major (#2799) 2024-12-11 16:16:46 -07:00
Alex Inkin
e9d851e4d3 fix: reset sideload service after websocket completes (#2798)
* fix: reset sideload service after websocket completes

* chore: fix comment
2024-12-11 16:14:01 -07:00
Mariusz Kogen
c675d0feee Escape backslashes in /etc/issue to prevent unwanted newlines (#2797) 2024-12-10 09:55:20 -07:00
Matt Hill
1859c0505e remove deprecated useHash param 2024-12-06 08:53:59 -07:00
Aiden McClelland
f15251096c sdk beta.0 2024-12-03 16:47:45 -07:00
Matt Hill
115c599fd8 remove welcome component 2024-12-02 17:00:40 -07:00
Matt Hill
3121c08ee8 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-12-02 16:59:03 -07:00
Matt Hill
ef28b01286 delete patch dump and ack-welcome references 2024-12-02 16:58:39 -07:00
Matt Hill
a5bac39196 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-12-02 16:50:37 -07:00
Alex Inkin
9f640b24b3 fix: fix building UI project (#2794)
* fix: fix building UI project

* fix makefile

* inputspec instead of config

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-12-02 16:44:27 -07:00
Aiden McClelland
f48750c22c v0.3.6-alpha.9 (#2795)
* v0.3.6-alpha.9

* fix raspi build

* backup kernel still .51
2024-12-02 22:03:40 +00:00
Matt Hill
7a96e94491 More SDK comments (#2796)
* sdk tweaks

* switch back to deeppartial

* WIP, update comments

* reinstall chesterton's fence

* more comments

* delete extra package.lock

* handle TODOs

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-12-02 20:58:28 +00:00
Matt Hill
22a32af750 use notification system for OS updates (#2670)
* use notification system for OS updates

* feat: Include the version update notification in the update in rs

* chore: Change the location of the comment

* progress on release notes

* fill out missing sections

* fix build

* fix build

---------

Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-12-02 20:58:09 +00:00
Mariusz Kogen
dd423f2e7b Add System Debug Information Gathering Script (#2738)
* Add gather_debug_info.sh for comprehensive StartOS diagnostics
* chore: Update the services to use the lxc instead of podman
* chore: Add symlink /usr/bin/gather-debug

---------

Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>
2024-12-02 17:27:32 +01:00
Matt Hill
12dec676db Update sdk comments (#2793)
* sdk tweaks

* switch back to deeppartial

* WIP, update comments

* reinstall chesterton's fence

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-11-26 23:54:05 -07:00
Matt Hill
75e7556bfa Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-11-25 19:02:07 -07:00
Aiden McClelland
504f1a8e97 sdk tweaks (#2791)
* sdk tweaks

* switch back to deeppartial
2024-11-25 18:49:11 +00:00
Mariusz Kogen
e4a2af6ae7 Add serial console support for headless operation (#2790)
* implement serial console support
* customize local and remote login prompt
2024-11-23 12:32:52 +01:00
Aiden McClelland
fefa88fc2a Feature/cli clearnet (#2789)
* add support for ACME cert acquisition

* add support for modifying hosts for a package

* misc fixes

* more fixes

* use different port for lan clearnet than wan clearnet

* fix chroot-and-upgrade always growing

* bail on failure

* wip

* fix alpn auth

* bump async-acme

* fix cli

* add barebones documentation

* add domain to hostname info
2024-11-21 17:55:59 +00:00
Alex Inkin
ed8a7ee8a5 feat: make favicon react to theme (#2786)
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-11-19 14:19:41 -07:00
Aiden McClelland
1771797453 sdk input spec improvements (#2785)
* sdk input spec improvements

* more sdk changes

* fe changes

* alpha.14

* fix tests

* separate validator in filehelper

* use deeppartial for getinput

* fix union type and update ts-matches

* alpha.15

* alpha.16

* alpha.17

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-11-19 11:25:43 -07:00
Aiden McClelland
46179f5c83 attempt to fix webserver lockup (#2788) 2024-11-14 18:31:47 +00:00
Jade
db6fc661a6 fix: Dependency (#2784)
* fix: Dependency

* fix: set deps during container init
2024-11-13 10:53:19 -07:00
Alex Inkin
beb3a9f60a feat: make favicon react to theme (#2787) 2024-11-12 19:29:41 -07:00
Matt Hill
c088ab7a79 remove file from input spec (#2782) 2024-11-11 12:17:44 -07:00
Aiden McClelland
aab2b8fdbc do not request config action if no config exists (#2779) 2024-11-11 18:54:51 +00:00
Aiden McClelland
b1e7a717af allow updating grub from chroot-and-upgrade (#2778) 2024-11-08 12:39:16 -07:00
Aiden McClelland
25e38bfc98 do not mute logs of subcontainer launch dummy (#2781) 2024-11-08 12:39:02 -07:00
Aiden McClelland
279c7324c4 download to directory not filename (#2777) 2024-11-08 12:38:46 -07:00
Matt Hill
1c90303914 closes #2340 and #2431, fixes bug with select all for backup (#2780)
* closes #2340 and #2431, fixes bug with select all for backup

* revefrt mock
2024-11-08 11:57:42 -07:00
Aiden McClelland
6ab6502742 alpha.8 (#2776) 2024-11-06 03:52:38 +00:00
Aiden McClelland
b79c029f21 Feature/registry improvements (#2772)
* add build cli script for cross-building cli

* sdk alpha.13

* registry improvements
2024-11-06 03:38:52 +00:00
Aiden McClelland
020268fe67 don't attempt autoconfig if config is null (#2775)
* don't attempt autoconfig if config is null

* quiet

* fixes
2024-11-06 03:38:30 +00:00
Aiden McClelland
176b1c9d20 allow lxc-net for tor (#2774)
* allow lxc-net for tor

* /24
2024-11-05 17:50:24 +00:00
Jade
5ab2efa0c0 wip(fix): Working on fixing the migration. (#2771)
* wip(fix): Working on fixing the migration.

* get s9pk compat key

* wip: Change to just using the archive to not use the manifest parsing.

* fix: Fix the rebuild

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-11-05 17:49:38 +00:00
Jade
88320488a7 fix: Actions like the action don't give the results (#2770) 2024-10-30 20:41:06 +00:00
Aiden McClelland
2091abeea2 persist hostname in config overlay (#2769)
* persist hostname

* add migration

* fix version mismatch

* remove dmesg logging from build
2024-10-30 18:55:36 +00:00
Aiden McClelland
480f5c1a9a pi 5 support (#2640)
* prioritize raspi repo

* change kernel

* use newer kernel

* Update build.sh

* fix ssh keygen

* switch to .com

* use raspi-update to download firmware

* Update build.sh

* Update build.sh

* Update build.sh

* Update build.sh

* switch to boot/firmware

* fix fstab

* update-initramfs

* skip check partition

* switch back to boot

* fix initramfs

* use rpi-update kernels

* simplify kernel selection
2024-10-30 09:15:24 -06:00
Jade
8e0db2705f Fix/mac start cli packing (#2767)
* wip

* wip: Adding more of the docker for the mac build

* fix: Running a build

* chore: Make the code a little cleaner

* optimize: reduce docker image size for mac-tar2sqfs

* feat: Update sdk-utils container usage and Dockerfile

* feat: Publish SDK Utils Container image

* clean up ...

* feat: Add manual input to control tagging Docker image as 'latest'

* fix: Update workflow input handling

* switch to different repo and clean

---------

Co-authored-by: Mariusz Kogen <k0gen@pm.me>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-10-29 20:38:24 +00:00
Matt Hill
1be9cdae67 use hardware requirements to display conflicts and prevent install (#2700)
* use hardware requirements to display conflicts and prevent install

* better messaging and also consider OS compatibility

* wip: backend hw requirements

* update backend components

* migration

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-10-29 19:48:03 +00:00
Jade
e1a91a7e53 Feat: With path (#2768) 2024-10-29 19:09:56 +00:00
Remco Ros
b952e3183f sdk: allow passing docker build arguments in service manifest (#2764)
* start-cli s9pk pack: silence mksquashfs output

* sdk: allow passing docker build arguments in service manifest

* merge EnvVar into BuildArg
2024-10-28 22:33:26 +00:00
Aiden McClelland
26ae0bf207 sdk tweaks (#2760)
* sdk tweaks

* update action result types

* accommodate new action response types

* fix: show action value labels

* Feature/get status effect (#2765)

* wip: get status

* feat: Add the get_status for effects

* feat: Do a callback

---------

Co-authored-by: J H <dragondef@gmail.com>

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: J H <dragondef@gmail.com>
2024-10-28 18:12:36 +00:00
Remco Ros
42cfd69463 sdk: fix piping stdio of Daemons, support onStdOut/onStderr (#2762) 2024-10-24 16:29:12 -06:00
Jade
7694b68e06 Feat/stats (#2761)
* Feat: Add the memory for the stats.

* Chore: Add %
2024-10-22 13:49:01 -06:00
Jade
28e39c57bd Fix: Error Messages in HealthCheck (#2759)
* Fix: Error Messages in HealthCheck

* Update sdk/package/lib/util/SubContainer.ts

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* fix ts error

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-10-21 20:47:09 +00:00
Aiden McClelland
2fa0a57d2b fixing raspi image (#2712)
* wip: fixing raspi image

* fix pi build
2024-10-18 20:17:56 +00:00
Matt Hill
c9f3e1bdab fix bug allowing click on disabled actions 2024-10-17 21:20:46 -06:00
Matt Hill
2ba56b8c59 Convert properties to an action (#2751)
* update actions response types and partially implement in UI

* further remove diagnostic ui

* convert action response nested to array

* prepare action res modal for Alex

* ad dproperties action for Bitcoin

* feat: add action success dialog (#2753)

* feat: add action success dialog

* mocks for string action res and hide properties from actions page

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* return null

* remove properties from backend

* misc fixes

* make severity separate argument

* rename ActionRequest to ActionRequestOptions

* add clearRequests

* fix s9pk build

* remove config and properties, introduce action requests

* better ux, better moocks, include icons

* fix dependency types

* add variant for versionCompat

* fix dep icon display and patch operation display

* misc fixes

* misc fixes

* alpha 12

* honor provided input to set values in action

* fix: show full descriptions of action success items (#2758)

* fix type

* fix: fix build:deps command on Windows (#2752)

* fix: fix build:deps command on Windows

* fix: add escaped quotes

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>

* misc db compatibility fixes

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-10-17 13:31:56 -06:00
Jade
fb074c8c32 036 migration (#2750)
* chore: convert to use a value, cause why not

* wip: Add the up for this going up

* wip: trait changes

* wip: Add in some more of the private transformations

* chore(wip): Adding the ssh_keys todo

* wip: Add cifs

* fix migration structure

* chore: Fix the trait for the version

* wip(feat): Notifications are in the system

* fix marker trait hell

* handle key todos

* wip: Testing the migration in a system.

* fix pubkey parser

* fix: migration works

* wip: Trying to get the migration stuff?

* fix: Can now install the packages that we wanted, yay!"

* Merge branch 'next/minor' of github.com:Start9Labs/start-os into feat/migration

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-10-16 10:09:30 -06:00
Dominion5254
9fc082d1e6 add with_about for CLI commands (#2741)
* add with_about for echo, server, and auth

* update for feedback

* finish (most) remaining command documentation

* update comments after additional clarification

* add expanded_api descriptions

* add comments for action_api

* add comments for remaining apis

* add comment for package-rebuild

* fix build errors

* missed one with_about

* add context to git-info subcommands

* remove context from git-info subcommands

* Make git-info from_fns generic over context

* make version::git_info generic over the context

* try removing generics from subcommand and version::git_info

* try adding a closure with context

* Updates for reviewer feedback
2024-10-16 09:11:32 -06:00
Lucy
dfda2f7d5d Update Marketplace (#2742)
* update abstract marketplace for usage accuracy andrename store to registry

* use new abstract functions

* fix(marketplace): get rid of `AbstractMarketplaceService`

* bump shared marketplace lib

* update marketplace to use query params for registry url; comment out updates page - will be refactored

* cleanup

* cleanup duplicate

* cleanup unused imports

* rework setting registry url when loading marketplace

* cleanup marketplace service

* fix background

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2024-10-09 11:23:08 -06:00
Aiden McClelland
0c04802560 fix cors (#2749) 2024-10-01 11:44:24 -06:00
Aiden McClelland
5146689158 v0.3.6-alpha.6 (#2748) 2024-09-27 16:38:28 -06:00
Aiden McClelland
e7fa94c3d3 add error status (#2746)
* add error status

* update types

* ṗ̶̰̙̓͒̈́ͅü̵̢̙̫̣ŗ̷̪̺̺͛g̴̲͉͎̬̒̇e̵̪̎̅͌ ̶̡̜̘͐͛t̶͎͍̣̿̍̐h̴͕̩͗̈́̎̑e̵͚͒̂͝ ̸̛͙̦͈͝v̶̱͙̬̽̔ọ̶̧̡̒̓i̸̬̲͍̋̈́d̴͉̀

* fix some extra voids

* add `package.rebuild`

* introduce error status and pkg rebuild and fix mocks

* minor fixes

* fix build

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-09-26 20:19:06 -06:00
Matt Hill
a77ebd3b55 Merge pull request #2747 from Start9Labs/chore/remove-mastodon-from-readme
Update README.md
2024-09-26 11:04:19 -06:00
Aiden McClelland
00114287e5 Update README.md 2024-09-26 17:00:52 +00:00
Aiden McClelland
db0695126f Refactor/actions (#2733)
* store, properties, manifest

* interfaces

* init and backups

* fix init and backups

* file models

* more versions

* dependencies

* config except dynamic types

* clean up config

* remove disabled from non-dynamic vaues

* actions

* standardize example code block formats

* wip: actions refactor

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* commit types

* fix types

* update types

* update action request type

* update apis

* add description to actionrequest

* clean up imports

* revert package json

* chore: Remove the recursive to the index

* chore: Remove the other thing I was testing

* flatten action requests

* update container runtime with new config paradigm

* new actions strategy

* seems to be working

* misc backend fixes

* fix fe bugs

* only show breakages if breakages

* only show success modal if result

* don't panic on failed removal

* hide config from actions page

* polyfill autoconfig

* use metadata strategy for actions instead of prev

* misc fixes

* chore: split the sdk into 2 libs (#2736)

* follow sideload progress (#2718)

* follow sideload progress

* small bugfix

* shareReplay with no refcount false

* don't wrap sideload progress in RPCResult

* dont present toast

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>

* chore: Add the initial of the creation of the two sdk

* chore: Add in the baseDist

* chore: Add in the baseDist

* chore: Get the web and the runtime-container running

* chore: Remove the empty file

* chore: Fix it so the container-runtime works

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>

* misc fixes

* update todos

* minor clean up

* fix link script

* update node version in CI test

* fix node version syntax in ci build

* wip: fixing callbacks

* fix sdk makefile dependencies

* add support for const outside of main

* update apis

* don't panic!

* Chore: Capture weird case on rpc, and log that

* fix procedure id issue

* pass input value for dep auto config

* handle disabled and warning for actions

* chore: Fix for link not having node_modules

* sdk fixes

* fix build

* fix build

* fix build

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Jade <Blu-J@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2024-09-25 16:12:52 -06:00
Aiden McClelland
eec5cf6b65 add support for remote attaching to container (#2732)
* add support for remote attaching to container

* feature: Add in the subcontainer searching

* feat: Add in the name/ imageId filtering

* Feat: Fix the env and the workdir

* chore: Make the sigkill first?

* add some extra guard on term

* fix: Health during error doesnt return what we need

* chore: Cleanup for pr

* fix build

* fix build

* Update startos-iso.yaml

* Update startos-iso.yaml

* Update startos-iso.yaml

* Update startos-iso.yaml

* Update startos-iso.yaml

* Update startos-iso.yaml

* Update startos-iso.yaml

* check status during build

---------

Co-authored-by: J H <dragondef@gmail.com>
2024-09-20 15:38:16 -06:00
Matt Hill
a9569d0ed9 Merge pull request #2740 from Start9Labs/update/new-registry
Update/new registry
2024-09-20 09:52:16 -06:00
Lucy Cifferello
88d9388be2 remote package lock from root 2024-09-20 11:51:19 -04:00
Lucy Cifferello
93c72ecea5 adjust buttons on marketplace show page and bump marketplace lib 2024-09-20 11:42:12 -04:00
Lucy Cifferello
b5b0ac50bd update shared and marketplace libs for taiga dep 2024-09-20 11:27:40 -04:00
Lucy Cifferello
4d2afdb1a9 misc cleanup and bump marketplace lib 2024-09-19 13:37:34 -04:00
Lucy Cifferello
39a177bd70 misc copy 2024-09-19 13:19:24 -04:00
Lucy Cifferello
34fb6ac837 add bitcoind dep for proxy in mocks 2024-09-19 13:19:14 -04:00
Lucy Cifferello
f868a454d9 move registry component to shared marketplace lib 2024-09-19 13:18:16 -04:00
Matt Hill
24c6cd235b Merge pull request #2737 from Start9Labs/fix/flavors
Fix/flavors
2024-09-17 16:32:42 -06:00
Lucy Cifferello
47855dc78b remove explicit type 2024-09-17 14:46:09 -04:00
Lucy Cifferello
751ceab04e fix icons and flavor filtering 2024-09-12 17:48:57 -04:00
Lucy Cifferello
dbbc42c5fd update packages 2024-09-12 17:03:01 -04:00
Lucy Cifferello
27416efb6d only display alt implementations if no flavors 2024-09-12 11:55:54 -04:00
Lucy Cifferello
21dd08544b update version to clear refresh alert 2024-09-12 11:55:10 -04:00
Lucy Cifferello
ae88f7d181 add types 2024-09-12 11:51:19 -04:00
Matt Hill
9981ee7601 follow sideload progress (#2718)
* follow sideload progress

* small bugfix

* shareReplay with no refcount false

* don't wrap sideload progress in RPCResult

* dont present toast

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-09-03 09:23:47 -06:00
Jade
66b018a355 Fix/health check error (#2731)
* fix: No error's with an error code

* fix dns query

* await resolv.conf copy

* use tty in subcontainer exec if parent is tty

* Fix: Home=root for inject services

* fix: Add the action inject too

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-08-30 06:29:27 +00:00
Matt Hill
b6c48d0f98 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-08-28 15:49:28 -06:00
Matt Hill
097d77f7b3 Merge pull request #2727 from Start9Labs/final-fixes
fix: final fixes
2024-08-28 15:38:44 -06:00
Aiden McClelland
ed1bc6c215 fix: session display (#2730)
* fixes #2651

* fix display

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-08-28 18:36:57 +00:00
Aiden McClelland
c552fdfc0f fixes #2651 (#2729) 2024-08-27 17:11:37 -06:00
Aiden McClelland
4006dba9f1 fixes #2702 (#2728) 2024-08-27 16:48:11 -06:00
waterplea
7a0586684b fix: refresh edit target 2024-08-27 12:27:23 +04:00
waterplea
8f34d1c555 fix: final fixes 2024-08-27 12:17:05 +04:00
Aiden McClelland
571db5c0ee Bugfix/mac build (#2726)
* fix mac build

* additional fixes

* handle arm64 from uname -m

* handle arm64 from uname -m in all builds

* gracefully handle rootless docker

* use cross-platform method of determining file uid
2024-08-26 22:52:23 +00:00
Aiden McClelland
9059855f2b run tests in docker (#2725) 2024-08-23 22:54:31 +00:00
Jade
e423678995 chore: Bump the version to 5 (#2724) 2024-08-23 12:52:41 -06:00
Jade
ece5577f26 feat: Adding in the effects to the startSdk (#2722)
Currently the start sdk that we expose calls some of the effects. And
there are others that need to be called via the effects object. The
idea is that all the effects that could and should be called are from
the startsdk side
2024-08-23 11:20:18 -06:00
Jade
f373abdd14 fix: Container runtime actions (#2723)
Actions where running in a race condition that they sometimes didn't wait for the container to be started and the issue was the exec that was then run after would have an issue.
2024-08-23 11:19:49 -06:00
Aiden McClelland
4defec194f Feature/subcontainers (#2720)
* wip: subcontainers

* wip: subcontainer infra

* rename NonDestroyableOverlay to SubContainerHandle

* chore: Changes to the container and other things

* wip:

* wip: fixes

* fix launch & exec

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* tweak apis

* misc fixes

* don't treat sigterm as error

* handle health check set during starting

---------

Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Jade <Blu-J@users.noreply.github.com>
2024-08-22 21:45:54 -06:00
Matt Hill
5270a6781f Merge pull request #2719 from Start9Labs/flavor
fix: implement flavor across the app
2024-08-20 22:09:07 -06:00
waterplea
fa93e195cb fix: implement flavor across the app 2024-08-20 18:53:55 +04:00
Aiden McClelland
72898d897c Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/minor 2024-08-19 21:39:45 -06:00
Aiden McClelland
c6ee65b654 bump sdk version 2024-08-19 21:39:38 -06:00
Jade
4d7694de24 chore: reimplement refactor for the changes (#2716)
* chore: reimplement refactor for the changes

* chore: Make it so even more cases are caught on the transformation

* Update container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts

* chore: Update the types of the action result because it wasnt matching what was in the action.rs
2024-08-19 21:38:05 -06:00
Matt Hill
a083f25b6c better ergonomics for versions (#2717) 2024-08-19 19:44:57 +00:00
Matt Hill
befa9eb16d Merge pull request #2714 from Start9Labs/sideload-and-backups
fix: implement back sideload and server selection in restoring
2024-08-18 07:52:02 -06:00
waterplea
a278c630bb fix: implement back sideload and server selection in restoring 2024-08-17 16:44:33 +04:00
Aiden McClelland
6a8d8babce fix uid mapping in squashfs's made from tarballs (#2710) 2024-08-16 13:40:10 -06:00
Matt Hill
76eb0f1775 Merge pull request #2709 from Start9Labs/fix-build
fix: fix build after minor merged into major
2024-08-16 05:28:33 -06:00
waterplea
0abe08f243 chore: small changes 2024-08-16 14:39:54 +04:00
Aiden McClelland
f692ebbbb9 fix runtime lockup (#2711) 2024-08-15 23:41:14 +00:00
Aiden McClelland
c174b65465 create version graph to handle migrations (#2708)
* create version graph to handle migrations

* Fix some version alpha test

* connect dataVersion api

* rename init fns

* improve types and add tests

* set data version after backup restore

* chore: Add some types tests for version info

* wip: More changes to versionInfo tests

* wip: fix my stupid

* update mocks

* update runtime

* chore: Fix the loop

---------

Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
2024-08-15 20:58:53 +00:00
Matt Hill
015131f198 address comments and more 2024-08-15 08:05:37 -06:00
waterplea
a730543c76 fix: fix build after minor merged into major 2024-08-15 12:40:49 +04:00
Jade
c704626a39 Fix/overlay destroy (#2707)
* feature: Make all errors in console.error be including an error for that stack tract

* feature: Make all errors in console.error be including an error for that stack tract

* fix: Add the tinisubreaper for the subreapers to know they are not the reaper

* fix: overlay always destroyed

* chore: Move the style of destroy to just private
2024-08-14 11:16:23 -06:00
Aiden McClelland
7ef25a3816 Merge pull request #2703 from Start9Labs/bugfix/misc
Bugfix/misc
2024-08-13 21:42:50 +00:00
Matt Hill
b43ad93c54 Merge pull request #2706 from Start9Labs/setup-wizard
fix: fix merge issues for setup-wizard project
2024-08-10 15:04:01 -06:00
waterplea
7850681ce1 chore: add back logs 2024-08-11 00:41:26 +04:00
Matt Hill
846189b15b address comments 2024-08-10 05:57:33 -06:00
Matt Hill
46a893a8b6 fix bug with setup wiz recovery 2024-08-10 05:46:54 -06:00
waterplea
657aac0d68 fix: fix merge issues for setup-wizard project 2024-08-10 14:45:50 +04:00
Jade
30885cee01 fix: Gitea/ Synapse/ Nostr types for manifest + config (#2704) 2024-08-10 11:07:06 +02:00
Matt Hill
9237984782 remove disabled from createInterface 2024-08-08 22:26:42 -06:00
Aiden McClelland
c289629a28 bump sdk version 2024-08-08 20:10:37 -06:00
Jade
806196f572 fix: Gitea/ Synapse/ Nostr types for manifest + config (#2704) 2024-08-08 17:00:13 -06:00
Aiden McClelland
0e598660b4 redesign checkDependencies api 2024-08-08 15:54:46 -06:00
Aiden McClelland
058bfe0737 sdk updates 2024-08-08 11:10:02 -06:00
Matt Hill
81932c8cff Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-08-08 10:52:49 -06:00
J H
bd7adafee0 Fix: sdk setupManifest pass through docs 2024-08-07 16:38:35 -06:00
J H
faf0c2b816 Merge branch 'bugfix/misc' of github.com:Start9Labs/start-os into bugfix/misc 2024-08-07 06:19:16 -06:00
J H
419d4986f6 fix: Inject for actions and health 2024-08-07 06:19:04 -06:00
Mariusz Kogen
9f1a9a7d9c fix CI build
* update nodejs
* set up python
2024-08-07 10:40:25 +02:00
Mariusz Kogen
a3e7e7c6c9 version bump 2024-08-07 08:51:15 +02:00
Aiden McClelland
94a5075b6d Merge pull request #2684 from Start9Labs/bugfix/misc
miscellaneous fixes from alpha testing
2024-08-06 16:53:37 -06:00
Aiden McClelland
7c32404b69 fix test 2024-08-06 14:40:49 -06:00
Aiden McClelland
d0c2dc53fe fix dns in the overlay 2024-08-06 14:27:05 -06:00
Aiden McClelland
0e8530172c fix config set dry 2024-08-06 13:59:14 -06:00
Aiden McClelland
4427aeac54 fix asset mounts 2024-08-06 13:21:12 -06:00
Aiden McClelland
93640bb08e don't bail on error in dep config on startup 2024-08-06 13:20:59 -06:00
J H
512ed71fc3 fixes: The case on the readonly that the path before doesn't exist, just let it 2024-08-05 13:11:55 -06:00
Matt Hill
0cfc43c444 don't deprecate wifi 2024-08-01 21:39:16 -06:00
Matt Hill
ecd0edc29e Merge pull request #2701 from Start9Labs/bugfix/misc-alex
fix: address TODOs and close dialogs upon state change
2024-07-31 08:03:45 -06:00
waterplea
6168a006f4 fix: address TODOs and close dialogs upon state change 2024-07-31 11:57:56 +04:00
Mariusz Kogen
82ba5dad1b version bump 2024-07-31 09:11:37 +02:00
Aiden McClelland
972ee8e42e premake 5 versions 2024-07-31 00:06:44 -06:00
Aiden McClelland
7cd3f285ad fix dependency autoconfig 2024-07-30 12:08:20 -06:00
Matt Hill
89e327383e remove file uploads from config 2024-07-30 09:09:35 -06:00
Matt Hill
290a15bbd9 remove sourceVersion and minor cleanup 2024-07-29 22:42:17 -06:00
Aiden McClelland
1dd21f1f76 fix config pointers 2024-07-29 18:46:02 -06:00
Aiden McClelland
46b3f83ce2 don't trim logs 2024-07-29 18:45:18 -06:00
Aiden McClelland
5c153c9e21 improve install performance 2024-07-29 18:44:56 -06:00
Aiden McClelland
bca75a3ea4 stop container before unmounting logs 2024-07-29 13:18:04 -06:00
Aiden McClelland
0bc6f972b2 reserialize getConfig response for backwards compatibility 2024-07-29 13:00:48 -06:00
Aiden McClelland
36cc9cc1ec fix firmware checker 2024-07-29 12:20:13 -06:00
Matt Hill
20f6a5e797 Merge pull request #2687 from Start9Labs/taiga
chore: update taiga
2024-07-29 11:39:56 -06:00
Aiden McClelland
ccbb68aa0c fix instructions on installed packages 2024-07-29 11:34:59 -06:00
Aiden McClelland
08003c59b6 don't lazily unmount unless on error 2024-07-29 11:34:38 -06:00
Mariusz Kogen
dafa638558 fix SSH Key message (#2686)
* fix SSH Key message

* Update web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.ts

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-07-29 17:25:01 +00:00
Jade
75e5250509 fixed: Transforming for bitcoind and nostr (#2688) 2024-07-29 17:24:10 +00:00
Matt Hill
0ed6eb7029 Fix sessions (#2689)
* add loggedIn key to sessions

* show loggedIn timestamp in list

* don't double hash active session

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-07-29 17:13:35 +00:00
Aiden McClelland
63e26b6050 fix race condition 2024-07-29 10:15:46 -06:00
waterplea
949f1c648a chore: update taiga 2024-07-29 18:18:00 +04:00
Aiden McClelland
3e7578d670 bump version 2024-07-26 20:31:09 -06:00
Aiden McClelland
6f07ec2597 fix bindings 2024-07-26 19:29:24 -06:00
Aiden McClelland
e65c0a0d1d fix tests 2024-07-26 19:19:19 -06:00
Aiden McClelland
be217b5354 update-grub on update 2024-07-26 19:06:11 -06:00
Aiden McClelland
bfe3029d31 fix dependency autoconfig 2024-07-26 17:49:44 -06:00
Aiden McClelland
6abdc39fe5 ignore error on dependent mounts in polyfill 2024-07-26 17:44:16 -06:00
J H
bf55367f4d chore: remove the need for the method in the autoconfig 2024-07-26 15:12:22 -06:00
Aiden McClelland
9480758310 decrease lxc-net init weight 2024-07-26 15:05:25 -06:00
Aiden McClelland
25b33fb031 use ci for test 2024-07-26 14:47:55 -06:00
Aiden McClelland
10ede0d21c delegate pointer removal to config transformer 2024-07-26 14:47:43 -06:00
Aiden McClelland
698bdd619f fix version mapping 2024-07-26 13:26:23 -06:00
Aiden McClelland
5cef6874f6 install before test 2024-07-26 12:33:22 -06:00
Aiden McClelland
6d42ae2629 brackets for ipv6 2024-07-26 12:30:26 -06:00
Aiden McClelland
a3b94816f9 ephemeral logins 2024-07-26 12:29:59 -06:00
Jade
e0b47feb8b Fixing: Some getConfigs where breaking in new system (#2685) 2024-07-26 17:19:16 +00:00
Aiden McClelland
8aecec0b9a fix canonicalization 2024-07-26 11:09:46 -06:00
Aiden McClelland
078bf41029 bump version 2024-07-26 02:07:39 -06:00
Aiden McClelland
2754302fb7 standardize result type for sideload progress 2024-07-26 02:02:58 -06:00
Aiden McClelland
dfb7658c3e implement mount for dependencies 2024-07-26 01:43:46 -06:00
Aiden McClelland
a743785faf cleanup on uninstall 2024-07-26 01:42:10 -06:00
Aiden McClelland
e4782dee68 fix ca cert issue 2024-07-26 01:41:11 -06:00
Aiden McClelland
64315df85f log url for download 2024-07-25 17:34:48 -06:00
Aiden McClelland
2a1fd16849 curl fail and show error 2024-07-25 17:08:19 -06:00
Aiden McClelland
21e31d540e Merge branch 'bugfix/misc' of github.com:Start9Labs/start-os into bugfix/misc 2024-07-25 16:14:06 -06:00
Aiden McClelland
370c38ec76 fix launchUI button 2024-07-25 16:14:04 -06:00
Aiden McClelland
854044229c reduce reliance on sudo 2024-07-25 15:44:51 -06:00
Aiden McClelland
69baa44a3a use squashfuse if available 2024-07-25 15:44:40 -06:00
Aiden McClelland
419e3f7f2b fix https redirect 2024-07-25 14:34:30 -06:00
Aiden McClelland
a9373d9779 don't show "Bytes" for overall progress 2024-07-25 14:34:03 -06:00
J H
1a0536d212 fix: Optional input 2024-07-25 13:25:18 -06:00
Aiden McClelland
099b77cf9b fix .local service resolution 2024-07-25 12:30:05 -06:00
Aiden McClelland
c3d17bf847 fix sync_db middleware 2024-07-25 12:26:49 -06:00
Aiden McClelland
e04b93a51a fix builds on platforms without kernel support for squashfs 2024-07-25 12:17:13 -06:00
Aiden McClelland
b36b62c68e Feature/callbacks (#2678)
* wip

* initialize callbacks

* wip

* smtp

* list_service_interfaces

* wip

* wip

* fix domains

* fix hostname handling in NetService

* misc fixes

* getInstalledPackages

* misc fixes

* publish v6 lib

* refactor service effects

* fix import

* fix container runtime

* fix tests

* apply suggestions from review
2024-07-25 17:44:51 +00:00
Matt Hill
ab465a755e default to all category and fix rounding for progress (#2682)
* default to all category and fix rounding for progress

* Update install-progress.pipe.ts
2024-07-24 22:40:13 -06:00
Aiden McClelland
c6f19db1ec Bugfix/wsl build (#2681)
* explicitly declare squashfs as loop device

* Update update-image.sh
2024-07-23 18:35:38 +00:00
Aiden McClelland
019142efc9 v0.3.6-alpha.0 (#2680)
* v0.3.6-alpha.0

* show welcome on fresh install
2024-07-23 18:18:17 +00:00
Lucy
a535fc17c3 Feature/fe new registry (#2647)
* bugfixes

* update fe types

* implement new registry types in marketplace and ui

* fix marketplace types to have default params

* add alt implementation toggle

* merge cleanup

* more cleanup and notes

* fix build

* cleanup sync with next/minor

* add exver JS parser

* parse ValidExVer to string

* update types to interface

* add VersionRange and comparative functions

* Parse ExtendedVersion from string

* add conjunction, disjunction, and inversion logic

* consider flavor in satisfiedBy fn

* consider prerelease for ordering

* add compare fn for sorting

* rename fns for consistency

* refactoring

* update compare fn to return null if flavors don't match

* begin simplifying dependencies

* under construction

* wip

* add dependency metadata to CurrentDependencyInfo

* ditch inheritance for recursive VersionRange constructor. Recursive 'satisfiedBy' fn wip

* preprocess manifest

* misc fixes

* use sdk version as osVersion in manifest

* chore: Change the type to just validate and not generate all solutions.

* add publishedAt

* fix pegjs exports

* integrate exver into sdk

* misc fixes

* complete satisfiedBy fn

* refactor - use greaterThanOrEqual and lessThanOrEqual fns

* fix tests

* update dependency details

* update types

* remove interim types

* rename alt implementation to flavor

* cleanup os update

* format exver.ts

* add s9pk parsing endpoints

* fix build

* update to exver

* exver and bug fixes

* update static endpoints + cleanup

* cleanup

* update static proxy verification

* make mocks more robust; fix dep icon fallback; cleanup

* refactor alert versions and update fixtures

* registry bugfixes

* misc fixes

* cleanup unused

* convert patchdb ui seed to camelCase

* update otherVersions type

* change otherVersions: null to 'none'

* refactor and complete feature

* improve static endpoints

* fix install params

* mask systemd-networkd-wait-online

* fix static file fetching

* include non-matching versions in otherVersions

* convert release notes to modal and clean up displayExver

* alert for no other versions

* Fix ack-instructions casing

* fix indeterminate loader on service install

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-07-23 00:48:12 +00:00
Aiden McClelland
0fbb18b315 Merge branch 'master' into next/minor 2024-07-22 11:43:00 -06:00
Jade
3eb0093d2a feature: Adding in the stopping state (#2677)
* feature: Adding in the stopping state

* chore: Deal with timeout in the sigterm for main

* chore: Update the timeout

* Update web/projects/ui/src/app/pages/apps-routes/app-list/app-list-pkg/app-list-pkg.component.ts

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* Update web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-07-22 17:40:12 +00:00
Matt Hill
d159dde2ca Merge pull request #2676 from Start9Labs/wifi
chore: improve wifi icons
2024-07-19 07:33:45 -06:00
waterplea
729a510c5b chore: improve wifi icons 2024-07-19 12:25:50 +05:00
Matt Hill
196561fed2 init UI increase logs buffer and don't throw on websocket unsubscribe (#2669)
* init UI increase logs buffer and don't throw on websocket unsubscribe

* fix: remove smooth scroll for logs

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2024-07-19 03:49:31 +00:00
Jade
8f0bdcd172 Fix/backups (#2659)
* fix master build (#2639)

* feat: Change ts to use rsync
Chore: Update the ts to use types over interface

* feat: Get the rust and the js to do a backup

* Wip: Got the backup working?

* fix permissions

* remove trixie list

* update tokio to fix timer bug

* fix error handling on backup

* wip

* remove idmap

* run restore before init, and init with own version on restore

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-07-17 21:46:27 +00:00
Matt Hill
fffc7f4098 Merge pull request #2672 from Start9Labs/taiga-4
feat: update Taiga UI to 4 release candidate
2024-07-15 11:40:16 -06:00
waterplea
c7a2e7ada1 feat: update Taiga UI to 4 release candidate 2024-07-15 11:16:19 +05:00
Matt Hill
95611e9c4b Merge pull request #2668 from Start9Labs/fix/backup-create
solve infinite recursion and promise returning true
2024-07-12 11:16:00 -06:00
waterplea
62fc6afd8a fix: fix select on mobile 2024-07-12 12:46:07 +05:00
waterplea
0f5cec0a60 fix: fix wrong password messaging 2024-07-12 11:14:45 +05:00
Matt Hill
d235ebaac9 solve infinite recursion and promise returning true 2024-07-11 17:58:07 -06:00
Aiden McClelland
6def083b4f fix deadlock on install (#2667)
* fix deadlock on install

* improve pruning script

* bump tokio
2024-07-11 20:55:13 +00:00
Aiden McClelland
87322744d4 Feature/backup fs (#2665)
* port 040 config, WIP

* update fixtures

* use taiga modal for backups too

* fix: update Taiga UI and refactor everything to work

* chore: package-lock

* fix interfaces and mocks for interfaces

* better mocks

* function to transform old spec to new

* delete unused fns

* delete unused FE config utils

* fix exports from sdk

* reorganize exports

* functions to translate config

* rename unionSelectKey and unionValueKey

* new backup fs

* update sdk types

* change types, include fuse module

* fix casing

* rework setup wiz

* rework UI

* only fuse3

* fix arm build

* misc fixes

* fix duplicate server select

* fix: fix throwing inside dialog

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2024-07-11 17:32:46 +00:00
Matt Hill
f2a02b392e Merge pull request #2648 from Start9Labs/feat/boot-param
Boot param for logs subscription
2024-07-10 14:54:39 -06:00
Aiden McClelland
e6cedc257e add boot param to logs request 2024-07-10 13:00:02 -06:00
Aiden McClelland
1b5cf2d272 Merge branch 'next/minor' of github.com:Start9Labs/start-os into feat/boot-param 2024-07-10 12:18:48 -06:00
Matt Hill
f76e822381 port 040 config (#2657)
* port 040 config, WIP

* update fixtures

* use taiga modal for backups too

* fix: update Taiga UI and refactor everything to work

* chore: package-lock

* fix interfaces and mocks for interfaces

* better mocks

* function to transform old spec to new

* delete unused fns

* delete unused FE config utils

* fix exports from sdk

* reorganize exports

* functions to translate config

* rename unionSelectKey and unionValueKey

* Adding in the transformation of the getConfig to the new types.

* chore: add Taiga UI to preloader

---------

Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: J H <dragondef@gmail.com>
2024-07-10 17:58:02 +00:00
Matt Hill
a2b1968d6e Merge pull request #2632 from Start9Labs/tables
feat: add mobile view for all the tables
2024-07-10 11:49:24 -06:00
waterplea
398eb13a7f chore: remove test 2024-07-10 16:01:57 +05:00
waterplea
956c8a8e03 chore: more comments 2024-07-10 10:35:21 +05:00
waterplea
6aba166c82 chore: address comments 2024-07-09 13:45:04 +05:00
waterplea
fd7c7ea6b7 chore: compact cards 2024-07-05 18:27:40 +05:00
waterplea
d85e621bb3 chore: address comments 2024-07-05 18:23:18 +05:00
Aiden McClelland
822dd5e100 Feature/UI sideload (#2658)
* ui sideloading

* remove subtlecrypto import

* fix parser

* misc fixes

* allow docker pull during compat conversion
2024-06-28 21:03:01 +00:00
Matt Hill
25801f374c Merge pull request #2638 from Start9Labs/update/marketplace-for-brochure
misc fixes and backwards compatibility with new registry types for brochure
2024-06-28 11:52:06 -06:00
Lucy Cifferello
8fd2d0b35c Merge remote-tracking branch 'origin' into update/marketplace-for-brochure 2024-06-26 16:29:15 -04:00
Matt Hill
c16d8a1da1 fix setup wizard styles and remove diagnostic from angular.json (#2656) 2024-06-25 20:58:24 -06:00
Aiden McClelland
ab1fdf69c8 add docs for development environment (#2655) 2024-06-26 00:11:11 +00:00
Lucy Cifferello
dd196c0e11 remove mismatched type for now 2024-06-25 18:00:56 -04:00
Aiden McClelland
0e506f5716 fix container cli (#2654) 2024-06-25 18:34:47 +00:00
Matt Hill
0a98ccff0c Merge pull request #2653 from Start9Labs/fix/ca-and-snek
fix ca trust test and snek high score
2024-06-25 10:58:38 -06:00
Matt Hill
0c188f6d10 fix ca trust test and snek high score 2024-06-25 10:54:09 -06:00
Matt Hill
8009dd691b Merge pull request #2635 from Start9Labs/feature/registry-metrics
Feature/registry analytics
2024-06-25 10:10:29 -06:00
Aiden McClelland
13d0e9914b Merge branch 'next/minor' of github.com:Start9Labs/start-os into feature/registry-metrics 2024-06-24 16:24:31 -06:00
Aiden McClelland
9da49be44d Bugfix/patch db subscriber (#2652)
* fix socket sending empty patches

* do not timeout tcp connections, just poll them more

* switch from poll to tcp keepalive
2024-06-24 22:15:56 +00:00
Aiden McClelland
00f7fa507b remove analyticsd, clean up script 2024-06-24 16:15:32 -06:00
Jade
2c255b6dfe chore: Do some type cleanups (#2650)
chore: fix the WithProcedureId
2024-06-24 16:00:31 -06:00
Lucy Cifferello
6e2cf8bb3f fix version sorting and icon display for marketplace 2024-06-24 17:49:57 -04:00
Matt Hill
68ed1c80ce update todos 2024-06-22 21:47:18 -06:00
Matt Hill
e0d23f4436 bump patchDB dep 2024-06-22 11:33:30 -06:00
Matt Hill
509f8a5353 Merge pull request #2649 from Start9Labs/cyclic-dep
feat: get rid of cyclic dep between patch-db and api service
2024-06-21 21:26:38 -06:00
Shadowy Super Coder
b0c0cd7fda add script to cache registry db 2024-06-21 18:40:32 -06:00
Shadowy Super Coder
133dfd5063 match query to registry table 2024-06-21 18:39:05 -06:00
waterplea
e6abf4e33b feat: get rid of cyclic dep between patch-db and api service
Signed-off-by: waterplea <alexander@inkin.ru>
2024-06-21 15:51:04 +05:00
Mariusz Kogen
07104b18f5 Update workflows actions (#2628)
* Update workflows actions to the latest versions
2024-06-20 20:59:16 +02:00
Matt Hill
f39b85abf2 bump to 036 2024-06-20 10:08:00 -06:00
Matt Hill
c6c97491ac add boot param to logs subscription 2024-06-20 10:07:39 -06:00
Jade
355452cdb3 Feat/next packages (#2646)
* fix mac build

* wip

* chore: Update the effects to get rid of bad pattern

* chore: Some small changes

* wip

* fix: Health checks don't show during race

* fix: Restart working

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-06-19 17:30:05 -06:00
Matt Hill
da3720c7a9 Feat/combine uis (#2633)
* wip

* restructure backend for new ui structure

* new patchdb bootstrap, single websocket api, local storage migration, more

* update db websocket

* init apis

* update patch-db

* setup progress

* feat: implement state service, alert and routing

Signed-off-by: waterplea <alexander@inkin.ru>

* update setup wizard for new types

* feat: add init page

Signed-off-by: waterplea <alexander@inkin.ru>

* chore: refactor message, patch-db source stream and connection service

Signed-off-by: waterplea <alexander@inkin.ru>

* fix method not found on state

* fix backend bugs

* fix compat assets

* address comments

* remove unneeded styling

* cleaner progress

* bugfixes

* fix init logs

* fix progress reporting

* fix navigation by getting state after init

* remove patch dependency from live api

* fix caching

* re-add patchDB to live api

* fix metrics values

* send close frame

* add bootId and fix polling

---------

Signed-off-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: waterplea <alexander@inkin.ru>
2024-06-19 19:51:44 +00:00
Aiden McClelland
e92d4ff147 fix compat assets (#2645)
* fix compat assets

* return error on s9pk parse fail in sideload

* return parse error over websocket
2024-06-17 16:37:57 +00:00
Jade
bb514d6216 Chore/refactoring effects (#2644)
* fix mac build

* wip

* chore: Update the effects to get rid of bad pattern

* chore: Some small changes

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-06-14 20:16:12 +00:00
Aiden McClelland
3f380fa0da feature: pack s9pk (#2642)
* TODO: images

* wip

* pack s9pk images

* include path in packsource error

* debug info

* add cmd as context to invoke

* filehelper bugfix

* fix file helper

* fix exposeForDependents

* misc fixes

* force image removal

* fix filtering

* fix deadlock

* fix api

* chore: Up the version of the package.json

* always allow concurrency within same call stack

* Update core/startos/src/s9pk/merkle_archive/expected.rs

Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>

---------

Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>
2024-06-12 17:46:59 +00:00
Jade
5aefb707fa feat: Add the merge to the file. (#2643)
* feat: Add the merge to the file.

* chore: Fix the early escape
2024-06-11 04:38:12 +00:00
Shadowy Super Coder
4afd3c2322 move MAU tracking back to registry 2024-06-10 18:56:39 -06:00
Lucy Cifferello
b8eb8a90a5 fix hero icon 2024-06-07 14:59:43 -04:00
Jade
4d6cb091cc Feature/disk usage (#2637)
* feat: Add disk usage

* Fixed: let the set config work with nesting.

* chore: Changes

* chore: Add default route

* fix: Tor only config

* chore
2024-06-07 18:17:45 +00:00
Aiden McClelland
fc8b1193de fix master build (#2639) 2024-06-07 18:17:21 +00:00
Jade
2c12af5af8 Feature/network (#2622)
* Feature: Add in the clear bindings

* wip: Working on network

* fix: Make it so the config gives the url

* chore: Remove the repeated types

* chore: Add in the todo's here

* chore: UPdate and remove some poorly name var

* chore: Remove the clear-bindings impl

* chore: Remove the wrapper

* handle HostnameInfo for Host bindings

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* ??

* chore: Make the install work

* Fix: Url's not being created

* chore: Fix the local onion in url

* include port in hostname

* Chore of adding a comment just to modify.

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Jade <Blu-J@users.noreply.github.com>
2024-06-06 21:39:54 +00:00
Lucy Cifferello
bd4d89fc21 fixes and backwards compatability with new registry types 2024-06-06 16:57:51 -04:00
Shadowy Super Coder
9487529992 remove os version from activity 2024-06-04 11:54:49 -06:00
Shadowy Super Coder
fa347fd49d remove record_metrics fn 2024-06-04 11:53:30 -06:00
Shadowy Super Coder
8f7072d7e9 metrics wip 2024-06-04 09:21:55 -06:00
Aiden McClelland
412c5d68cc Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2024-06-03 11:35:28 -06:00
Aiden McClelland
e06b068033 Merge branch 'master' of github.com:Start9Labs/start-os into next/patch 2024-06-03 10:06:46 -06:00
waterplea
6234391229 feat: add mobile view for all the tables
Signed-off-by: waterplea <alexander@inkin.ru>
2024-06-03 15:10:49 +05:00
Aiden McClelland
2568bfde5e create skeleton 2024-05-31 13:46:58 -06:00
Aiden McClelland
fd7c2fbe93 Feature/registry package index (#2623)
* include system images in compat s9pk

* wip

* wip

* update types

* wip

* fix signature serialization

* Add SignatureHeader conversions

* finish display impl for get

---------

Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me>
2024-05-31 18:13:23 +00:00
Matt Hill
206c185a3b Merge pull request #2631 from Start9Labs/sections
chore: add sections
2024-05-30 06:29:02 -06:00
waterplea
7689cbbe0d chore: add sections
Signed-off-by: waterplea <alexander@inkin.ru>
2024-05-30 12:04:38 +01:00
Matt Hill
c832b5d29e Update README.md (#2630)
* Update README.md

* Update README.md
2024-05-29 20:07:36 +00:00
Matt Hill
b57a9351b3 Merge pull request #2629 from Start9Labs/navigation
refactor: change navigation
2024-05-28 21:18:44 -06:00
waterplea
f0ae9e21ae refactor: change navigation
Signed-off-by: waterplea <alexander@inkin.ru>
2024-05-28 13:20:25 +01:00
Matt Hill
9510c92288 Merge pull request #2626 from Start9Labs/comments
chore: address comments
2024-05-21 15:04:13 -06:00
waterplea
755f3f05d8 chore: input-file on mobile 2024-05-21 10:29:29 +01:00
waterplea
5d8114b475 chore: address comments 2024-05-20 21:59:46 +01:00
Aiden McClelland
0ccbb52c1f wait for whole session to exit when sigterm (#2620)
* wait for whole session to exit when sigterm

* fix lint

* rename poorly named variable
2024-05-17 01:54:36 +00:00
Matt Hill
85b39ecf99 Merge pull request #2621 from Start9Labs/paths
chore: types imports
2024-05-16 07:03:56 -06:00
waterplea
230838c22b chore: types imports 2024-05-16 12:28:59 +01:00
Matt Hill
a7bfcdcb01 Merge pull request #2618 from Start9Labs/service
refactor: change service page to the new design
2024-05-14 10:01:27 -06:00
Matt Hill
47ff630c55 fix dependency errors and navigation 2024-05-14 07:02:21 -06:00
waterplea
70dc53bda7 chore: add backups info 2024-05-14 11:34:14 +01:00
Jade
0b8a142de0 fix: Making the daemons keep up the status. (#2617)
* complete get_primary_url fn

* complete clear_network_interfaces fn

* formatting

* complete remove_address fn

* get_system_smtp wip

* complete get_system_smtp and set_system_smtp

* add SetSystemSmtpParams struct

* add set_system_smtp subcommand

* Remove 'Copy' implementation from `HostAddress`

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* Refactor `get_host_primary` fn and clone  resulting `HostAddress`

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* misc fixes and debug info

* seed hosts with a tor address

* fix: Making the daemons keep up the status.

* wipFix: Making a service start

* fix: Both the start + stop of the service.

* fix: Weird edge case of failure and kids

---------

Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-05-13 16:50:25 +00:00
waterplea
7e1b433c17 refactor: change service page to the new design 2024-05-12 16:53:01 +01:00
Dominion5254
800b0763e4 More svc effect handlers (#2610)
* complete get_primary_url fn

* complete clear_network_interfaces fn

* formatting

* complete remove_address fn

* get_system_smtp wip

* complete get_system_smtp and set_system_smtp

* add SetSystemSmtpParams struct

* add set_system_smtp subcommand

* Remove 'Copy' implementation from `HostAddress`

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* Refactor `get_host_primary` fn and clone  resulting `HostAddress`

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* misc fixes and debug info

* seed hosts with a tor address

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-05-10 19:20:24 +00:00
Jade
30aabe255b Feature/backup+restore (#2613)
* feat: Implementation on the backup for the service.

* wip: Getting the flow of backup/restore

* feat: Recover

* Feature: Commit the full pass on the backup restore.

* use special type for backup instead of special id (#2614)

* fix: Allow compat docker style to run again

* fix: Backup for the js side

* chore: Update some of the callbacks

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-05-06 21:46:36 +00:00
Aiden McClelland
9b14d714ca Feature/new registry (#2612)
* wip

* overhaul boot process

* wip: new registry

* wip

* wip

* wip

* wip

* wip

* wip

* os registry complete

* ui fixes

* fixes

* fixes

* more fixes

* fix merkle archive
2024-05-06 16:20:44 +00:00
Jade
8a38666105 Feature/sdk040dependencies (#2609)
* update registry upload to take id for new admin permissions (#2605)

* wip

* wip: Get the get dependencies

* wip check_dependencies

* wip: Get the build working to the vm

* wip: Add in the last of the things that where needed for the new sdk

* Add fix

* wip: implement the changes

* wip: Fix the naming

---------

Co-authored-by: Lucy <12953208+elvece@users.noreply.github.com>
2024-04-26 17:51:33 -06:00
Matt Hill
ec878defab Merge pull request #2604 from Start9Labs/metrics
feat: implement metrics on the dashboard
2024-04-26 09:07:45 -06:00
waterplea
1786b70e14 chore: add todo 2024-04-26 18:06:19 +03:00
waterplea
7f525fa7dc chore: fix comments 2024-04-26 13:17:25 +03:00
Dominion5254
e08d93b2aa complete export_service_interface and list_service_interfaces fns (#2595)
* complete export_service_interface fn

* refactor export_service_interface fn

* complete list_service_interfaces fn

* call insert on model and remove unnecessary code

* Refactor export_service_interface

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* Refactor list_service_interfaces

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* get ServiceInterfaceId and HostId from params

* formatting

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-04-25 17:16:20 -06:00
Lucy
df777c63fe fix type for query params (#2611) 2024-04-23 20:02:11 +00:00
Aiden McClelland
3a5ee4a296 kill process by session, and add timeout (#2608) 2024-04-23 20:01:40 +00:00
Aiden McClelland
7b8a0114f5 fix log response (#2607) 2024-04-23 20:01:29 +00:00
Aiden McClelland
003d110948 build multi-arch s9pks (#2601)
* build multi-arch s9pks

* remove images incrementally

* wip

* prevent rebuild

* fix sdk makefile

* fix hanging on uninstall

* fix build

* fix build

* fix build

* fix build (for real this time)

* fix git hash computation
2024-04-22 17:40:10 +00:00
Lucy
e9c9a67365 update registry upload to take id for new admin permissions (#2605) 2024-04-18 11:35:38 -06:00
waterplea
8b89e03999 feat: implement metrics on the dashboard 2024-04-18 13:45:35 +07:00
Jade
9eff920989 Feat/logging (#2602)
* wip: Working on something to help

* chore: Add in some of the logging now

* chore: fix the type to interned instead of id

* wip

* wip

* chore: fix the logging by moving levels

* Apply suggestions from code review

* mount at machine id for journal

* Persistant

* limit log size

* feat: Actually logging and mounting now

* fix: Get the logs from the previous versions of the boot

* Chore: Add the boot id

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-04-17 21:46:10 +00:00
Aiden McClelland
711c82472c Feature/debian runtime (#2600)
* wip

* fix build

* run debian update in systemd-nspawn

* bugfix

* fix build

* free up space before image build
2024-04-15 16:00:56 +00:00
Matt Hill
156bf02d21 Merge pull request #2599 from Start9Labs/bugfix/wifi
fix wifi types
2024-04-10 13:49:02 -06:00
Matt Hill
932b53d92d deprecate wifi 2024-04-09 21:06:06 -06:00
Matt Hill
2693b9a42d Merge pull request #2598 from Start9Labs/fix/preview-loader
fix preview loader
2024-04-09 20:03:43 -06:00
Aiden McClelland
e9166c4a7d fix wifi types 2024-04-09 15:24:05 -06:00
Aiden McClelland
2bc64920dd Merge branch 'next/minor' of github.com:Start9Labs/start-os into bugfix/wifi 2024-04-09 15:11:17 -06:00
Aiden McClelland
aee5500833 miscellaneous bugfixes (#2597)
* miscellaneous bugfixes

* misc fixes
2024-04-09 21:10:26 +00:00
Matt Hill
6b336b7b2f Merge pull request #2591 from Start9Labs/ionic
refactor: completely remove ionic
2024-04-09 14:28:24 -06:00
Aiden McClelland
f07992c091 misc fixes 2024-04-09 14:04:31 -06:00
Lucy Cifferello
3c0e77241d fix preview loader 2024-04-09 13:29:54 -04:00
Lucy Cifferello
87461c7f72 fix gap space 2024-04-09 12:42:28 -04:00
Lucy Cifferello
a67f2b4976 add back variables 2024-04-09 12:42:11 -04:00
waterplea
8594781780 refactor: completely remove ionic 2024-04-09 12:45:47 +07:00
Aiden McClelland
313e415ee9 miscellaneous bugfixes 2024-04-08 14:01:16 -06:00
Aiden McClelland
c13d8f3699 finish dependency autoconfig (#2596) 2024-04-08 18:07:56 +00:00
Aiden McClelland
e41f8f1d0f allow concurrency in service actor (#2592) 2024-04-08 17:53:35 +00:00
Matt Hill
b2c8907635 Merge pull request #2590 from Start9Labs/update/marketplace-shared
update marketplace/shared to sync with next/major and brochure
2024-04-08 11:46:02 -06:00
Lucy Cifferello
05f4df1a30 fix changig registry 2024-04-08 10:33:02 -04:00
Lucy Cifferello
35fe06a892 fix registry connect styles and remove view complete listing link 2024-04-05 16:56:06 -04:00
Dominion5254
75ff541aec complete get_service_port_forward fn (#2579)
* complete get_service_port_forward fn

* refactor get_service_port_forward and get_container_ip

* remove unused function

* move host_id to GetServicePortForwardParams

* replace match with deref

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* refactor get_container_ip to use deref

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2024-04-05 19:20:49 +00:00
Lucy Cifferello
cd933ce6e4 fix sideload display and other misc style adjustments 2024-04-05 14:14:23 -04:00
Lucy Cifferello
0b93988450 feedback fixes 2024-04-05 09:26:32 -04:00
Jade
056cab23e0 Fix: Configure was borken (#2589) 2024-04-04 19:17:11 +00:00
Jade
6bc8027644 Feat/implement rest of poly effects (#2587)
* feat: Add the implementation of the rest of the polyfillEffects

* chore: Add in the rsync

* chore: Add in the changes needed to indicate that the service does not need config

* fix: Vaultwarden sets, starts, stops, uninstalls

* chore: Update the polyFilleffect and add two more

* Update MainLoop.ts

* chore: Add in the set config of the deps on the config set
2024-04-04 09:09:59 -06:00
Matt Hill
3b9298ed2b Feature/dependency autoconfig (#2588)
* dependency autoconfig

* FE portion

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-04-03 11:48:26 -06:00
Lucy Cifferello
12a323f691 fix dependency icon and layout 2024-04-03 12:35:27 -04:00
Lucy Cifferello
9c4c211233 fix preview versions, icons, and misc styling 2024-04-03 12:34:46 -04:00
Lucy Cifferello
74ba68ff2c fix scroll areas and side menu 2024-04-03 12:32:57 -04:00
Lucy Cifferello
7273b37c16 cleanup dep item for new type 2024-04-01 18:10:16 -04:00
Lucy Cifferello
0d4ebffc0e marketplace release fixes and refactors 2024-04-01 18:09:28 -04:00
Matt Hill
352b2fb4e7 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2024-04-01 15:19:33 -06:00
Matt Hill
6e6ef57303 Merge pull request #2339 from Start9Labs/rebase/feat/domains
Most things FE 040
2024-04-01 15:12:02 -06:00
Aiden McClelland
cc1f14e5e9 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/minor 2024-04-01 14:57:20 -06:00
Aiden McClelland
1c419d5c65 Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2024-04-01 14:57:10 -06:00
Matt Hill
71b83245b4 Chore/unexport api ts (#2585)
* don't export api params

* import from SDK instead of BE

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-04-01 14:47:03 -06:00
Aiden McClelland
2b88555028 Merge branch 'master' of github.com:Start9Labs/start-os into next/patch 2024-04-01 14:46:17 -06:00
Aiden McClelland
f021ad9b0a export api types to ts (#2583) 2024-04-01 13:14:22 -06:00
Aiden McClelland
8884f64b4e Merge branch 'master' of github.com:Start9Labs/start-os into next/minor 2024-04-01 11:15:22 -06:00
Aiden McClelland
dd790dceb5 Chore/reorg backend ts (#2582)
* create index

* chore: Add the star exports for the bindings

---------

Co-authored-by: J H <dragondef@gmail.com>
2024-04-01 17:12:35 +00:00
Matt Hill
b80e41503f Merge branch 'next/minor' of github.com:Start9Labs/start-os into rebase/feat/domains 2024-03-30 21:14:53 -06:00
Matt Hill
8dfc5052e9 ditch more FE enums for clarity and cleanliness 2024-03-30 10:37:31 -06:00
Alex Inkin
7f28fc17ca feat: add mobile view for dashboard (#2581) 2024-03-30 08:48:36 -06:00
Aiden McClelland
2c308ccd35 Merge pull request #2512 from Start9Labs/integration/new-container-runtime
[feature]: new container runtime
2024-03-29 18:12:07 -06:00
Aiden McClelland
4d6dd44e10 allow downgrades 2024-03-29 15:35:33 -06:00
Aiden McClelland
b6992e32a5 yes 2024-03-29 14:42:33 -06:00
Aiden McClelland
ac080edb02 automatically accept clearing the log tree on btrfs repair (#2580) 2024-03-29 20:03:36 +00:00
Aiden McClelland
231859303d fix cargo dep 2024-03-29 13:49:05 -06:00
Aiden McClelland
1acdd67fd9 chown volume mountpoints 2024-03-29 13:41:41 -06:00
Aiden McClelland
bec63a9471 remove extra sdk test line 2024-03-29 13:06:51 -06:00
Aiden McClelland
44e856e8dc fix make -t 2024-03-29 12:18:40 -06:00
Aiden McClelland
3bab7678b7 install qemu as root 2024-03-29 10:05:24 -06:00
Aiden McClelland
61f68d9e1b install qemu 2024-03-29 09:49:05 -06:00
Aiden McClelland
94f1562ec5 choose base image by arch instead of platform 2024-03-29 09:16:15 -06:00
Aiden McClelland
46412acd13 add container runtime to compiled tar 2024-03-28 23:31:27 -06:00
Aiden McClelland
e7426ea365 touch bindings before make touch 2024-03-28 17:11:43 -06:00
Aiden McClelland
665eef68b9 fix unterminated quote 2024-03-28 16:36:58 -06:00
Aiden McClelland
7c63d4012f fix build 2024-03-28 15:31:54 -06:00
Aiden McClelland
92be4e774e build fixes 2024-03-28 14:48:45 -06:00
J H
2395502e60 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-28 13:37:21 -06:00
J H
9f3902b48d chore: Fix the last of the actions 2024-03-28 13:37:15 -06:00
Matt Hill
6e76bcb77e fix updates rendering bug 2024-03-28 11:59:42 -06:00
Aiden McClelland
e05a95dc2d Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-28 11:21:13 -06:00
Aiden McClelland
86d61d698a update types and format bindings 2024-03-28 11:20:20 -06:00
J H
8ce6535a7e chore: Update the types for container runtime 2024-03-28 10:51:51 -06:00
J H
65ca038eee chore: Update and fix the things 2024-03-28 10:40:47 -06:00
Aiden McClelland
f41f5ebebd export patchdb ts types from rust 2024-03-27 17:47:12 -06:00
J H
9cf62f03fa Add some extra export action 2024-03-27 15:28:54 -06:00
Aiden McClelland
f770d5072e export patchdb types 2024-03-27 13:58:42 -06:00
J H
5698b830ed Fix: Fix the issue where the restart after a service install and update,
would mak
the system crash
2024-03-27 12:40:23 -06:00
J H
bcc76dd60a fix: The db dump on the private 2024-03-27 11:11:55 -06:00
Matt Hill
70d4a0c022 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into rebase/feat/domains 2024-03-27 10:35:42 -06:00
Alex Inkin
8cfd994170 fix: address todos (#2578) 2024-03-27 10:27:51 -06:00
Matt Hill
22d8d08355 update patch types for current dependencies 2024-03-27 10:25:07 -06:00
Matt Hill
641e829e3f better interfaces abstractions 2024-03-26 16:37:06 -06:00
Aiden McClelland
f9edff8bf4 handle todos 2024-03-26 16:21:57 -06:00
Aiden McClelland
33e6be1ca6 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-26 15:17:37 -06:00
Aiden McClelland
e25c50a467 fix types to match 2024-03-26 10:46:46 -06:00
J H
f8441ab42e chore: Add in the fix for the test integration to the actual sdk 2024-03-26 10:37:22 -06:00
Aiden McClelland
4589d4b3f5 update ts-rs to 8.1 2024-03-26 10:26:44 -06:00
Aiden McClelland
9cf720e040 rename embassy to startos 2024-03-25 18:21:58 -06:00
Aiden McClelland
cf793f7f49 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-25 15:47:24 -06:00
Aiden McClelland
2b3fddfe89 use correct serverconfig type 2024-03-25 15:47:22 -06:00
J H
e148f143ea wip: Properties 2024-03-25 14:18:09 -06:00
Matt Hill
d202cb731d fix bugs 2024-03-25 13:31:30 -06:00
J H
299d9998ad chore: Making sure that the values that we are returning are valid now with the new types 2024-03-25 12:01:13 -06:00
J H
fba1484e2e fix: Bringing in a building for the browser 2024-03-25 11:13:17 -06:00
J H
4ab7300376 fix: Bringing in a building for the browser 2024-03-25 11:07:59 -06:00
Matt Hill
18cc5e0ee8 re-add ionic config 2024-03-25 10:28:49 -06:00
Matt Hill
af0cda5dbf update sdk imports 2024-03-24 13:27:13 -06:00
Matt Hill
a730a3719b Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into rebase/feat/domains 2024-03-24 12:19:37 -06:00
Matt Hill
3b669193f6 refactor downstream for 036 changes (#2577)
refactor codebase for 036 changes
2024-03-24 12:12:55 -06:00
Matt Hill
c782bab296 switch all FE to camelCase (#2576)
* switch all fe to camelCase

* switch to camelCase on backend

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2024-03-24 12:05:59 -06:00
Matt Hill
b14646ebd9 export tyeps from sdk 2024-03-24 11:57:39 -06:00
J H
7441de5fd9 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-23 09:13:00 -06:00
J H
f5360cb8d4 wip: Adding in properties and nested path 2024-03-23 09:03:56 -06:00
Matt Hill
22cd2e3337 Merge branch 'update/camelCase' of github.com:Start9Labs/start-os into rebase/feat/domains 2024-03-22 13:09:11 -06:00
Matt Hill
7e9d453a2c switch all fe to camelCase 2024-03-22 12:05:41 -06:00
Matt Hill
a4338b0d03 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into rebase/feat/domains 2024-03-22 10:10:55 -06:00
Aiden McClelland
a35baca580 update rust types to match sdk changes 2024-03-21 17:53:34 -06:00
Matt Hill
66b0108c51 revamp manifest types 2024-03-21 17:21:37 -06:00
Lucy
2021431e2f Update/marketplace (#2575)
* make category link generic

* fix ai category display and svg icons

* fix markdown display and ansi module; cleanup

* convert tailwindcss to scss in marketplace menu component

* convert tailwindcss to scss in marketplace categories component

* convert tailwindcss to scss in marketplace item component

* update launch icon to taiga icon

* convert tailwindcss to scss in marketplace search component + cleanup

* convert tailwindcss to scss in marketplace release notes component + cleanup

* convert tailwindcss to scss in marketplace about component + cleanup

* convert tailwindcss to scss in marketplace additional component

* convert tailwindcss to scss in marketplace dependencies component + misc style fixes

* convert tailwindcss to scss in marketplace hero component + misc style fixes

* convert tailwindcss to scss in marketplace screenshots component

* convert tailwindcss to scss in portal marketplace components

* remove the rest of tailwindscss and fix reset styles

* bump shared and marketplace package versions

* misc style + build fixes

* sync package lock

* fix markdown + cleanup

* fix markdown margins and git hash size

* fix mobile zindex for hero and mobile changing categories routing link
2024-03-21 12:23:28 -06:00
Shadowy Super Coder
ab836c6922 remove unneeded imports 2024-03-20 21:50:21 -06:00
Shadowy Super Coder
405b3be496 complete get_container_ip effect handler 2024-03-20 21:26:18 -06:00
J H
4a27128a1c chore: Update the types for changes that Matt wanted with sdk + examples 2024-03-20 20:28:31 -06:00
J H
c74bdc97ca fix: util -> utils in the container-runtime 2024-03-20 13:46:32 -06:00
Shadowy Super Coder
ddd5e4c76d blu-j paired changes 2024-03-20 13:43:34 -06:00
Matt Hill
5e6a7e134f merge 036, everything broken 2024-03-20 13:32:57 -06:00
J H
41bc519855 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-20 10:48:13 -06:00
J H
53d82618d9 chore: Update the types and get the container-runtime working 2024-03-20 10:48:03 -06:00
Aiden McClelland
57f548c6c0 fix certificate chain 2024-03-19 16:54:27 -06:00
J H
8d83f64aba chore: Update the types for the mocks in the services 2024-03-19 13:27:51 -06:00
J H
9162697117 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-19 12:44:56 -06:00
Aiden McClelland
47b19e3211 fix duplicate 2024-03-19 11:59:02 -06:00
J H
590f6d4c19 chore: Update the types 2024-03-19 11:58:38 -06:00
Aiden McClelland
53108e816f Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-19 11:55:40 -06:00
Aiden McClelland
3ac71e2f7f include sdk.Mounts 2024-03-19 11:55:38 -06:00
Alex Inkin
f4fadd366e feat: add new dashboard (#2574)
* feat: add new dashboard

* chore: comments

* fix duplicate

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-03-19 08:56:16 -06:00
Matt Hill
cc38dab76f Rework PackageDataEntry for new strategy (#2573)
* rework PackageDataEntry for new strategy

* fix type error

* fix issues with manifest fetching

* mock installs working
2024-03-19 08:38:04 -06:00
J H
c8be701f0e chore: Add in the mounts 2024-03-18 16:23:09 -06:00
J H
417befb2be Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-18 15:29:08 -06:00
J H
a0ce7f38e7 chore: Add in the thing to do the volumes correctly 2024-03-18 15:28:33 -06:00
Aiden McClelland
962e3d8e56 more specific rust type 2024-03-18 15:24:20 -06:00
J H
3a3df96996 fix: Test 2024-03-18 15:20:17 -06:00
Aiden McClelland
2ffa632796 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-18 15:15:55 -06:00
Aiden McClelland
3c6c0b253d move mounts to daemons constructor 2024-03-18 15:14:36 -06:00
J H
5f40fd6038 chore: Remove the utils 2024-03-18 14:31:01 -06:00
J H
8e2dc8b3ee chore: Fix the effects 2024-03-18 12:47:31 -06:00
Matt Hill
a02b531e47 update sdk 2024-03-18 12:37:50 -06:00
J H
a4cb2708cc Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-18 10:54:36 -06:00
J H
973284607d chore: Update the sdk to match the rust and vica verse 2024-03-18 10:53:38 -06:00
Matt Hill
28fd2f0314 More 036 Frontend changes (#2572)
* update patchDB for futuristic revisions

* interfaces display updates

* remove zram and move tor to settings
2024-03-16 13:09:17 -06:00
J H
9715873007 chore: Add in the rest of the effects for now 2024-03-15 14:29:08 -06:00
J H
18a20407f6 chore: Fix the build 2024-03-15 13:31:44 -06:00
Aiden McClelland
1a396cfc7b reorganize package data and write dependencies rpc (#2571)
* wip

* finish dependencies

* minor fixes
2024-03-15 19:02:47 +00:00
J H
e604c914d1 chore: UPdate to the make, getting rid of a circular dep 2024-03-15 11:25:52 -06:00
J H
a310c160a5 chore: Update the types hopefully 2024-03-14 15:29:01 -06:00
J H
45d50b12fd chore: Update the types for the sdk 2024-03-14 15:18:33 -06:00
J H
e87182264a chore: Fix the build for the start9labs/sdk was a new directory structure 2024-03-14 15:14:12 -06:00
J H
a089d544a5 chore: Add some of the fixes to make the build work !!! 2024-03-13 17:44:13 -06:00
J H
b6fe0be1b2 chore: Add in some more files for the testing of the sdk and the rust interface 2024-03-13 16:23:24 -06:00
J H
ba325b1581 feat: Move the store to private. 2024-03-12 11:58:13 -06:00
Aiden McClelland
1f47abf195 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-11 17:16:07 -06:00
Aiden McClelland
750f35bc36 add --include-private to db dump rpc 2024-03-11 17:15:18 -06:00
J H
c99d9d95c5 chore: Add in the properties to somewhere useful. 2024-03-11 17:06:00 -06:00
J H
4d402b2600 chore: Fix the issue that I made that made it impossible to start a service because that would do a set during a time when there was not even a installed state 2024-03-11 16:34:37 -06:00
Aiden McClelland
64fb002168 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-03-11 16:11:01 -06:00
Aiden McClelland
1308b5bcf3 wait up to 30s for ip address 2024-03-11 16:10:59 -06:00
J H
dc3dc4a1f0 chore: Update some of the system for the embassy properties to be filled with the correct properties.
git push
2024-03-11 15:47:22 -06:00
J H
99bb55af73 Update some of the types 2024-03-11 15:37:04 -06:00
J H
4a285225db chore: Update the version of the cargo 2024-03-08 14:46:44 -07:00
Aiden McClelland
d986bd2a6c sync ssh keys on add 2024-03-07 17:19:01 -07:00
Aiden McClelland
8665342edf fix deadlock 2024-03-07 16:43:13 -07:00
Aiden McClelland
2e7c3bf789 use dockerhub compat 2024-03-07 15:41:27 -07:00
Aiden McClelland
31ea0fe3fe fix async cycle 2024-03-07 14:57:41 -07:00
Aiden McClelland
e0c9f8a5aa Feature/remove postgres (#2570)
* wip: move postgres data to patchdb

* wip

* wip

* wip

* complete notifications and clean up warnings

* fill in user agent

* move os tor bindings to single call
2024-03-07 14:40:22 -07:00
J H
a17ec4221b chore: Remove some of the bad logging 2024-03-07 13:45:38 -07:00
J H
328beaba35 chore: Add in the possibility to get the status code from the executed health check 2024-03-07 13:36:38 -07:00
J H
efbbaa5741 feat: Get the health checks for the js 2024-03-07 11:38:59 -07:00
J H
14be2fa344 chore: Add in the ability to kill the tree of processes 2024-03-06 16:22:29 -07:00
J H
f3ccad192c chore: Add the process tree destroyer 2024-03-06 15:43:07 -07:00
Aiden McClelland
5e580f9372 Update firmware.json 2024-03-06 22:30:18 +00:00
J H
8410929e86 feat: Add the stop/start loop for the service 2024-03-06 10:55:21 -07:00
J H
093a5d4ddf chore: Simplify the state into one 2024-03-06 09:38:55 -07:00
J H
88028412bd chore: Add some documentation for the service actor seed 2024-03-04 14:18:20 -07:00
J H
11c93231aa fix: Let the service be able to be started 2024-03-04 13:37:48 -07:00
J H
5366b4c873 chore: Add another export 2024-02-27 13:25:58 -07:00
J H
171e0ed312 chore: Something 2024-02-27 13:20:55 -07:00
Alex Inkin
a5b1b4e103 refactor: remove ionic from remaining places (#2565) 2024-02-27 13:15:32 -07:00
J H
f50ddb436f chore: somethinng 2024-02-27 13:12:51 -07:00
J H
0b4b091580 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-02-27 13:11:09 -07:00
J H
2f6d7ac128 chore: Update to have the startsdk 2024-02-27 13:11:04 -07:00
J H
6b990e1cee chore: Up the version 2024-02-27 12:33:31 -07:00
Aiden McClelland
ddeed65994 remove workspace package json 2024-02-26 17:29:20 -07:00
Aiden McClelland
d87748fda1 add npm workspace file 2024-02-26 16:59:37 -07:00
J H
50f0ead113 Merge branch 'integration/new-container-runtime' of github.com:Start9Labs/start-os into integration/new-container-runtime 2024-02-23 15:32:06 -07:00
J H
4e3075aaba chore: Add in the ability to remove the bad sections? 2024-02-23 15:32:01 -07:00
Matt Hill
87d6684ca7 Frontend changes for 036 (#2554)
* new interfaces and remove tor http warnings

* move sigtermTimeout to stopping main status

* lightning, masked, schemeOverride, invert host-iface relationship

* update for new sdk

* update for latest SDK changes

* Update app-interfaces.page.ts

* Update config.service.ts
2024-02-23 10:38:50 -07:00
J H
3bd7596873 chore: Fix some issues in the installation of a package and other rpc things 2024-02-22 16:42:31 -07:00
Aiden McClelland
39964bf077 Feature/lxc container runtime (#2563)
* wip: context

* wip(fix) Sorta auth

* wip: warnings

* wip(fix): registry/admin

* wip(fix) marketplace

* wip(fix) Some more converted and fixed with the linter and config

* wip: Working on the static server

* wip(fix)static server

* wip: Remove some asynnc

* wip: Something about the request and regular rpc

* wip: gut install

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* wip: Convert the static server into the new system

* wip delete file

* test

* wip(fix) vhost does not need the with safe defaults

* wip: Adding in the wifi

* wip: Fix the developer and the verify

* wip: new install flow

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* fix middleware

* wip

* wip: Fix the auth

* wip

* continue service refactor

* feature: Service get_config

* feat: Action

* wip: Fighting the great fight against the borrow checker

* wip: Remove an error in a file that I just need to deel with later

* chore: Add in some more lifetime stuff to the services

* wip: Install fix on lifetime

* cleanup

* wip: Deal with the borrow later

* more cleanup

* resolve borrowchecker errors

* wip(feat): add in the handler for the socket, for now

* wip(feat): Update the service_effect_handler::action

* chore: Add in the changes to make sure the from_service goes to context

* chore: Change the

* refactor service map

* fix references to service map

* fill out restore

* wip: Before I work on the store stuff

* fix backup module

* handle some warnings

* feat: add in the ui components on the rust side

* feature: Update the procedures

* chore: Update the js side of the main and a few of the others

* chore: Update the rpc listener to match the persistant container

* wip: Working on updating some things to have a better name

* wip(feat): Try and get the rpc to return the correct shape?

* lxc wip

* wip(feat): Try and get the rpc to return the correct shape?

* build for container runtime wip

* remove container-init

* fix build

* fix error

* chore: Update to work I suppose

* lxc wip

* remove docker module and feature

* download alpine squashfs automatically

* overlays effect

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* chore: Add the overlay effect

* feat: Add the mounter in the main

* chore: Convert to use the mounts, still need to work with the sandbox

* install fixes

* fix ssl

* fixes from testing

* implement tmpfile for upload

* wip

* misc fixes

* cleanup

* cleanup

* better progress reporting

* progress for sideload

* return real guid

* add devmode script

* fix lxc rootfs path

* fix percentage bar

* fix progress bar styling

* fix build for unstable

* tweaks

* label progress

* tweaks

* update progress more often

* make symlink in rpc_client

* make socket dir

* fix parent path

* add start-cli to container

* add echo and gitInfo commands

* wip: Add the init + errors

* chore: Add in the exit effect for the system

* chore: Change the type to null for failure to parse

* move sigterm timeout to stopping status

* update order

* chore: Update the return type

* remove dbg

* change the map error

* chore: Update the thing to capture id

* chore add some life changes

* chore: Update the loging

* chore: Update the package to run module

* us From for RpcError

* chore: Update to use import instead

* chore: update

* chore: Use require for the backup

* fix a default

* update the type that is wrong

* chore: Update the type of the manifest

* chore: Update to make null

* only symlink if not exists

* get rid of double result

* better debug info for ErrorCollection

* chore: Update effects

* chore: fix

* mount assets and volumes

* add exec instead of spawn

* fix mounting in image

* fix overlay mounts

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* misc fixes

* feat: Fix two

* fix: systemForEmbassy main

* chore: Fix small part of main loop

* chore: Modify the bundle

* merge

* fixMain loop"

* move tsc to makefile

* chore: Update the return types of the health check

* fix client

* chore: Convert the todo to use tsmatches

* add in the fixes for the seen and create the hack to allow demo

* chore: Update to include the systemForStartOs

* chore UPdate to the latest types from the expected outout

* fixes

* fix typo

* Don't emit if failure on tsc

* wip

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* add s9pk api

* add inspection

* add inspect manifest

* newline after display serializable

* fix squashfs in image name

* edit manifest

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* wait for response on repl

* ignore sig for now

* ignore sig for now

* re-enable sig verification

* fix

* wip

* env and chroot

* add profiling logs

* set uid & gid in squashfs to 100000

* set uid of sqfs to 100000

* fix mksquashfs args

* add env to compat

* fix

* re-add docker feature flag

* fix docker output format being stupid

* here be dragons

* chore: Add in the cross compiling for something

* fix npm link

* extract logs from container on exit

* chore: Update for testing

* add log capture to drop trait

* chore: add in the modifications that I make

* chore: Update small things for no updates

* chore: Update the types of something

* chore: Make main not complain

* idmapped mounts

* idmapped volumes

* re-enable kiosk

* chore: Add in some logging for the new system

* bring in start-sdk

* remove avahi

* chore: Update the deps

* switch to musl

* chore: Update the version of prettier

* chore: Organize'

* chore: Update some of the headers back to the standard of fetch

* fix musl build

* fix idmapped mounts

* fix cross build

* use cross compiler for correct arch

* feat: Add in the faked ssl stuff for the effects

* @dr_bonez Did a solution here

* chore: Something that DrBonez

* chore: up

* wip: We have a working server!!!

* wip

* uninstall

* wip

* tes

* misc fixes

* fix cli

* replace interface with host

* chore: Fix the types in some ts files

* chore: quick update for the system for embassy to update the types

* replace br-start9 with lxcbr0

* split patchdb into public/private

* chore: Add changes for config set

* Feat: Adding some debugging for the errors

* wip: Working on getting the set config to work

* chore: Update and fix the small issue with the deserialization

* lightning, masked, schemeOverride, invert host-iface relationship

* feat: Add in the changes for just the sdk

* feat: Add in the changes for the new effects I suppose for now

* Some small changes ????

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: J H <Blu-J@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-02-22 22:37:11 +00:00
Aiden McClelland
089199e7c2 Feature/lxc container runtime (#2562)
* wip(fix): Dependencies

* wip: context

* wip(fix) Sorta auth

* wip: warnings

* wip(fix): registry/admin

* wip(fix) marketplace

* wip(fix) Some more converted and fixed with the linter and config

* wip: Working on the static server

* wip(fix)static server

* wip: Remove some asynnc

* wip: Something about the request and regular rpc

* wip: gut install

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* wip: Convert the static server into the new system

* wip delete file

* test

* wip(fix) vhost does not need the with safe defaults

* wip: Adding in the wifi

* wip: Fix the developer and the verify

* wip: new install flow

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* fix middleware

* wip

* wip: Fix the auth

* wip

* continue service refactor

* feature: Service get_config

* feat: Action

* wip: Fighting the great fight against the borrow checker

* wip: Remove an error in a file that I just need to deel with later

* chore: Add in some more lifetime stuff to the services

* wip: Install fix on lifetime

* cleanup

* wip: Deal with the borrow later

* more cleanup

* resolve borrowchecker errors

* wip(feat): add in the handler for the socket, for now

* wip(feat): Update the service_effect_handler::action

* chore: Add in the changes to make sure the from_service goes to context

* chore: Change the

* refactor service map

* fix references to service map

* fill out restore

* wip: Before I work on the store stuff

* fix backup module

* handle some warnings

* feat: add in the ui components on the rust side

* feature: Update the procedures

* chore: Update the js side of the main and a few of the others

* chore: Update the rpc listener to match the persistant container

* wip: Working on updating some things to have a better name

* wip(feat): Try and get the rpc to return the correct shape?

* lxc wip

* wip(feat): Try and get the rpc to return the correct shape?

* build for container runtime wip

* remove container-init

* fix build

* fix error

* chore: Update to work I suppose

* lxc wip

* remove docker module and feature

* download alpine squashfs automatically

* overlays effect

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* chore: Add the overlay effect

* feat: Add the mounter in the main

* chore: Convert to use the mounts, still need to work with the sandbox

* install fixes

* fix ssl

* fixes from testing

* implement tmpfile for upload

* wip

* misc fixes

* cleanup

* cleanup

* better progress reporting

* progress for sideload

* return real guid

* add devmode script

* fix lxc rootfs path

* fix percentage bar

* fix progress bar styling

* fix build for unstable

* tweaks

* label progress

* tweaks

* update progress more often

* make symlink in rpc_client

* make socket dir

* fix parent path

* add start-cli to container

* add echo and gitInfo commands

* wip: Add the init + errors

* chore: Add in the exit effect for the system

* chore: Change the type to null for failure to parse

* move sigterm timeout to stopping status

* update order

* chore: Update the return type

* remove dbg

* change the map error

* chore: Update the thing to capture id

* chore add some life changes

* chore: Update the loging

* chore: Update the package to run module

* us From for RpcError

* chore: Update to use import instead

* chore: update

* chore: Use require for the backup

* fix a default

* update the type that is wrong

* chore: Update the type of the manifest

* chore: Update to make null

* only symlink if not exists

* get rid of double result

* better debug info for ErrorCollection

* chore: Update effects

* chore: fix

* mount assets and volumes

* add exec instead of spawn

* fix mounting in image

* fix overlay mounts

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* misc fixes

* feat: Fix two

* fix: systemForEmbassy main

* chore: Fix small part of main loop

* chore: Modify the bundle

* merge

* fixMain loop"

* move tsc to makefile

* chore: Update the return types of the health check

* fix client

* chore: Convert the todo to use tsmatches

* add in the fixes for the seen and create the hack to allow demo

* chore: Update to include the systemForStartOs

* chore UPdate to the latest types from the expected outout

* fixes

* fix typo

* Don't emit if failure on tsc

* wip

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* add s9pk api

* add inspection

* add inspect manifest

* newline after display serializable

* fix squashfs in image name

* edit manifest

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* wait for response on repl

* ignore sig for now

* ignore sig for now

* re-enable sig verification

* fix

* wip

* env and chroot

* add profiling logs

* set uid & gid in squashfs to 100000

* set uid of sqfs to 100000

* fix mksquashfs args

* add env to compat

* fix

* re-add docker feature flag

* fix docker output format being stupid

* here be dragons

* chore: Add in the cross compiling for something

* fix npm link

* extract logs from container on exit

* chore: Update for testing

* add log capture to drop trait

* chore: add in the modifications that I make

* chore: Update small things for no updates

* chore: Update the types of something

* chore: Make main not complain

* idmapped mounts

* idmapped volumes

* re-enable kiosk

* chore: Add in some logging for the new system

* bring in start-sdk

* remove avahi

* chore: Update the deps

* switch to musl

* chore: Update the version of prettier

* chore: Organize'

* chore: Update some of the headers back to the standard of fetch

* fix musl build

* fix idmapped mounts

* fix cross build

* use cross compiler for correct arch

* feat: Add in the faked ssl stuff for the effects

* @dr_bonez Did a solution here

* chore: Something that DrBonez

* chore: up

* wip: We have a working server!!!

* wip

* uninstall

* wip

* tes

* misc fixes

* fix cli

* replace interface with host

* chore: Fix the types in some ts files

* chore: quick update for the system for embassy to update the types

* replace br-start9 with lxcbr0

* split patchdb into public/private

* chore: Add changes for config set

* Feat: Adding some debugging for the errors

* wip: Working on getting the set config to work

* chore: Update and fix the small issue with the deserialization

* lightning, masked, schemeOverride, invert host-iface relationship

* feat: Add in the changes for just the sdk

* feat: Add in the changes for the new effects I suppose for now

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: J H <Blu-J@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
2024-02-22 21:00:49 +00:00
Alex Inkin
7b41b295b7 chore: refactor install and setup wizards (#2561)
* chore: refactor install and setup wizards

* chore: return tui-root
2024-02-22 06:58:01 -07:00
Matt Hill
d7bc7a2d38 make service interfaces and hosts one to one 2024-02-19 12:40:52 -07:00
Matt Hill
eae75c13bb update network interfaces types 2024-02-17 13:07:41 -07:00
Aiden McClelland
fab13db4b4 Feature/lxc container runtime (#2514)
* wip: static-server errors

* wip: fix wifi

* wip: Fix the service_effects

* wip: Fix cors in the middleware

* wip(chore): Auth clean up the lint.

* wip(fix): Vhost

* wip: continue manager refactor

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* wip: service manager refactor

* wip: Some fixes

* wip(fix): Fix the lib.rs

* wip

* wip(fix): Logs

* wip: bins

* wip(innspect): Add in the inspect

* wip: config

* wip(fix): Diagnostic

* wip(fix): Dependencies

* wip: context

* wip(fix) Sorta auth

* wip: warnings

* wip(fix): registry/admin

* wip(fix) marketplace

* wip(fix) Some more converted and fixed with the linter and config

* wip: Working on the static server

* wip(fix)static server

* wip: Remove some asynnc

* wip: Something about the request and regular rpc

* wip: gut install

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* wip: Convert the static server into the new system

* wip delete file

* test

* wip(fix) vhost does not need the with safe defaults

* wip: Adding in the wifi

* wip: Fix the developer and the verify

* wip: new install flow

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* fix middleware

* wip

* wip: Fix the auth

* wip

* continue service refactor

* feature: Service get_config

* feat: Action

* wip: Fighting the great fight against the borrow checker

* wip: Remove an error in a file that I just need to deel with later

* chore: Add in some more lifetime stuff to the services

* wip: Install fix on lifetime

* cleanup

* wip: Deal with the borrow later

* more cleanup

* resolve borrowchecker errors

* wip(feat): add in the handler for the socket, for now

* wip(feat): Update the service_effect_handler::action

* chore: Add in the changes to make sure the from_service goes to context

* chore: Change the

* refactor service map

* fix references to service map

* fill out restore

* wip: Before I work on the store stuff

* fix backup module

* handle some warnings

* feat: add in the ui components on the rust side

* feature: Update the procedures

* chore: Update the js side of the main and a few of the others

* chore: Update the rpc listener to match the persistant container

* wip: Working on updating some things to have a better name

* wip(feat): Try and get the rpc to return the correct shape?

* lxc wip

* wip(feat): Try and get the rpc to return the correct shape?

* build for container runtime wip

* remove container-init

* fix build

* fix error

* chore: Update to work I suppose

* lxc wip

* remove docker module and feature

* download alpine squashfs automatically

* overlays effect

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* chore: Add the overlay effect

* feat: Add the mounter in the main

* chore: Convert to use the mounts, still need to work with the sandbox

* install fixes

* fix ssl

* fixes from testing

* implement tmpfile for upload

* wip

* misc fixes

* cleanup

* cleanup

* better progress reporting

* progress for sideload

* return real guid

* add devmode script

* fix lxc rootfs path

* fix percentage bar

* fix progress bar styling

* fix build for unstable

* tweaks

* label progress

* tweaks

* update progress more often

* make symlink in rpc_client

* make socket dir

* fix parent path

* add start-cli to container

* add echo and gitInfo commands

* wip: Add the init + errors

* chore: Add in the exit effect for the system

* chore: Change the type to null for failure to parse

* move sigterm timeout to stopping status

* update order

* chore: Update the return type

* remove dbg

* change the map error

* chore: Update the thing to capture id

* chore add some life changes

* chore: Update the loging

* chore: Update the package to run module

* us From for RpcError

* chore: Update to use import instead

* chore: update

* chore: Use require for the backup

* fix a default

* update the type that is wrong

* chore: Update the type of the manifest

* chore: Update to make null

* only symlink if not exists

* get rid of double result

* better debug info for ErrorCollection

* chore: Update effects

* chore: fix

* mount assets and volumes

* add exec instead of spawn

* fix mounting in image

* fix overlay mounts

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* misc fixes

* feat: Fix two

* fix: systemForEmbassy main

* chore: Fix small part of main loop

* chore: Modify the bundle

* merge

* fixMain loop"

* move tsc to makefile

* chore: Update the return types of the health check

* fix client

* chore: Convert the todo to use tsmatches

* add in the fixes for the seen and create the hack to allow demo

* chore: Update to include the systemForStartOs

* chore UPdate to the latest types from the expected outout

* fixes

* fix typo

* Don't emit if failure on tsc

* wip

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* add s9pk api

* add inspection

* add inspect manifest

* newline after display serializable

* fix squashfs in image name

* edit manifest

Co-authored-by: Jade <Blu-J@users.noreply.github.com>

* wait for response on repl

* ignore sig for now

* ignore sig for now

* re-enable sig verification

* fix

* wip

* env and chroot

* add profiling logs

* set uid & gid in squashfs to 100000

* set uid of sqfs to 100000

* fix mksquashfs args

* add env to compat

* fix

* re-add docker feature flag

* fix docker output format being stupid

* here be dragons

* chore: Add in the cross compiling for something

* fix npm link

* extract logs from container on exit

* chore: Update for testing

* add log capture to drop trait

* chore: add in the modifications that I make

* chore: Update small things for no updates

* chore: Update the types of something

* chore: Make main not complain

* idmapped mounts

* idmapped volumes

* re-enable kiosk

* chore: Add in some logging for the new system

* bring in start-sdk

* remove avahi

* chore: Update the deps

* switch to musl

* chore: Update the version of prettier

* chore: Organize'

* chore: Update some of the headers back to the standard of fetch

* fix musl build

* fix idmapped mounts

* fix cross build

* use cross compiler for correct arch

* feat: Add in the faked ssl stuff for the effects

* @dr_bonez Did a solution here

* chore: Something that DrBonez

* chore: up

* wip: We have a working server!!!

* wip

* uninstall

* wip

* tes

---------

Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: J H <Blu-J@users.noreply.github.com>
Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2024-02-17 18:14:14 +00:00
Matt Hill
69d5f521a5 remove tor http warnings 2024-02-16 14:12:10 -07:00
Alex Inkin
c0a55142b5 chore: refactor interfaces and remove UI routes (#2560) 2024-02-16 13:45:30 -07:00
Alex Inkin
513fb3428a feat: implement mobile header (#2559)
* feat: implement mobile header

* chore: remove remaining ties to old ui project

* chore: remove ionic from login page

* chore: address comments
2024-02-13 09:03:09 -07:00
Alex Inkin
9a0ae549f6 feat: refactor logs (#2555)
* feat: refactor logs

* chore: comments

* feat: add system logs

* feat: update shared logs
2024-02-05 19:26:00 -07:00
Lucy
4410d7f195 update angular in shared (#2556) 2024-01-31 11:25:25 -05:00
Alex Inkin
92aa70182d refactor: implement breadcrumbs (#2552) 2024-01-22 21:32:11 -05:00
Alex Inkin
90f5864f1e refactor: finalize new portal (#2543) 2023-12-22 16:22:16 -05:00
Aiden McClelland
d44de670cd Add socat to base dependencies (#2544) 2023-12-20 22:20:01 +00:00
J H
cb63025078 chore: Initial commit for the bump to 0.3.5.2 (#2541)
* chore: Initial commit for the bump

* wip(fix): build

* chore: Update the os welcome page to include the previous release of the 0.3.5.1
2023-12-20 14:58:24 -07:00
J H
685e865b42 fix: Docker stopping will include a timeout (#2540)
* fix sdk build script

* fix: Docker stopping will include a timeoute

So the timeout that was included in the original is not working therefore we move to a doublinig with a timeout

* fix: Adding in the missing suggestions that Aiden has poinited out

* Update install-sdk.sh

* Update install-sdk.sh

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-12-19 10:16:18 -07:00
Alex Inkin
e47f126bd5 feat(portal): refactor marketplace for new portal (#2539)
* feat(portal): refactor marketplace for new portal

* fix background position

* chore: refactor sidebar

* chore: small fix

---------

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2023-12-18 16:43:59 -05:00
Alex Inkin
ea6f70e3c5 chore: migrate to Angular 17 (#2538)
* chore: migrate to Angular 17

* chore: update
2023-12-11 07:06:55 -07:00
Lucy
0469aab433 Feature/marketplace redesign (#2395)
* wip

* update marketplace categories styling

* update logo icons

* add sort pipe

* update search component styling

* clean up categories component

* cleanup and remove unnecessary sort pipe

* query packages in selected category

* fix search styling

* add reg icon and font, adjust category styles

* fix build from rebasing integration/refactors

* adjust marketplace types for icon with store data, plus formatting

* formatting

* update categories and search

* hover styling for categories

* category styling

* refactor for category as a behavior subject

* more category styling

* base functionality with new marketplace components

* styling cleanup

* misc style fixes and fix category selection from package page

* fixes from review feedback

* add and style additional details

* implement release notes modal

* fix menu when on service show page mobile to display change marketplace

* style and responsiveness fixes

* rename header to sidebar

* input icon config to sidebar

* add mime type pipe and type fn

* review feedback fixes

* skeleton text, more abstraction

* reorder categories, clean up a little

* audit sidebar, categories, store-icon, marketplace-sidebar, search

* finish code cleanup and fix few bugs

* misc fixes and cleanup

* fix broken styles and markdown

* bump shared marketplace version

* more cleanup

* sync package lock

* rename sidebar component to menu

* wip preview sidebar

* sync package lock

* breakout package show elements into components

* link to brochure in preview; custom taiga button styles

* move marketplace preview component into ui; open preview when viewing service in marketplace

* sync changes post file struture rename

* further cleanup

* create service for sidebar toggle and cleanup marketplace components

* bump shared marketplace version

* bump shared for new images needed for brochure marketplace

* cleanup

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-12-08 13:12:38 -07:00
Alex Inkin
ad13b5eb4e feat(portal): refactor settings (#2536)
* feat(portal): refactor settings

* chore: refactor

* small updates

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-12-08 12:19:33 -07:00
Alex Inkin
7324a4973f feat(portal): add notifications sidebar (#2516)
* feat(portal): add notifications sidebar

* chore: add service

* chore: simplify style

* chore: fix comments

* WIP, moving notifications to patch-db

* revamp notifications

* chore: small adjustments

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-12-08 09:12:03 -07:00
Matt Hill
8bc93d23b2 Merge branch 'next/major' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-11-21 21:18:27 -07:00
Aiden McClelland
39de098461 fix sdk build script 2023-11-21 08:44:14 -07:00
Aiden McClelland
531f232418 Merge pull request #2513 from Start9Labs/next/patch
v0.3.5.1
2023-11-20 17:00:52 -07:00
Matt Hill
c708b685e1 fix type error 2023-11-20 15:30:53 -07:00
Aiden McClelland
65009e2f69 Merge branch 'next/minor' of github.com:Start9Labs/start-os into integration/new-container-runtime 2023-11-20 14:13:57 -07:00
Aiden McClelland
cbde91744f Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-20 13:21:04 -07:00
Aiden McClelland
4c8a92bb0c Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-20 13:20:42 -07:00
Aiden McClelland
5f047d22f4 fix ntp sync status check daemon (#2528) 2023-11-20 20:12:40 +00:00
Aiden McClelland
efdc558cba set content disposition for cert (#2527)
* set content disposition for cert
* update content type for cert
* remove unnecessary frontend download attr
2023-11-20 18:54:05 +00:00
Matt Hill
04bd1cfa41 fix docs links 2023-11-19 17:54:12 -07:00
Aiden McClelland
11a2e96d06 Merge branch 'next/minor' of github.com:Start9Labs/start-os into integration/new-container-runtime 2023-11-17 16:39:13 -07:00
Aiden McClelland
095c5e4f95 Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-17 16:38:48 -07:00
Aiden McClelland
aa2a2e12cc prevent hanging on reboot (#2526) 2023-11-17 23:37:25 +00:00
Aiden McClelland
8f231424d1 add cli to rotate key (#2525)
* rotate key

* handle service with no config
2023-11-17 23:27:08 +00:00
Aiden McClelland
069db28fb6 Merge branch 'next/minor' of github.com:Start9Labs/start-os into integration/new-container-runtime 2023-11-17 10:54:58 -07:00
Aiden McClelland
2e747d3ece Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-17 10:53:55 -07:00
Aiden McClelland
d03aadb367 improve robustness of install (#2524)
* perform old package cleanup after commit to patchdb
* unpack full s9pk on rebuild
2023-11-17 00:16:13 +00:00
Aiden McClelland
749cde13c4 redesign firmware updater (#2521)
* bump version

* Update image-recipe/build.sh

* fix podman repo

* improve firmware updater

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* checksum firmware

* include sha in json

* fix build

* fix semver parser, add rpc for manual trigger

---------

Co-authored-by: J H <Blu-J@users.noreply.github.com>
2023-11-16 22:49:03 +00:00
Aiden McClelland
0b43aab855 retry migration if incomplete (#2522) 2023-11-16 22:47:28 +00:00
Aiden McClelland
147e24204b Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-16 15:15:43 -07:00
Aiden McClelland
6580153f29 Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-16 15:11:10 -07:00
Aiden McClelland
fbc94cfbfc allow non-zero exit cpupower frequency-info -g (#2523)
* set better governor hierarchy and add cli command to change

* allow non-zero exit `cpupower frequency-info -g`
2023-11-16 21:48:33 +00:00
Matt Hill
e631b145b9 bump web manifest version 2023-11-16 11:06:24 -07:00
Aiden McClelland
8cf0ae0994 play song unconditionally (#2518)
* play song unconditionally

* double bep-bep frequency

* play song during firmware update

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-11-16 06:04:35 -07:00
Aiden McClelland
a551bc5375 bump version (#2520)
* bump version

* Update image-recipe/build.sh

* fix podman repo

* switch back to unstable for podman
2023-11-15 18:50:29 -07:00
Matt Hill
417053a6a2 FE version bump and minor copy updates (#2517)
version bump and minor copy updates
2023-11-15 19:17:33 +00:00
Aiden McClelland
a1495dd33d set better governor hierarchy and add cli command to change (#2519) 2023-11-15 19:17:10 +00:00
Matt Hill
13c50e428f Merge branch 'next/major' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-11-13 17:13:32 -07:00
Matt Hill
8403ccd3da fix ts errors 2023-11-13 16:58:55 -07:00
Aiden McClelland
c988bca958 Merge branch 'next/minor' of github.com:Start9Labs/start-os into integration/new-container-runtime 2023-11-13 16:42:06 -07:00
Aiden McClelland
e92bd61545 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-13 16:36:59 -07:00
Aiden McClelland
e84e8edb29 Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-13 16:35:08 -07:00
Aiden McClelland
5f3db8e567 fix make test 2023-11-13 16:34:52 -07:00
Aiden McClelland
8215e0221a Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-13 16:28:28 -07:00
Aiden McClelland
a4ef7205ca Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-13 16:26:00 -07:00
Aiden McClelland
43ecd8b362 Merge branch 'master' of github.com:Start9Labs/start-os into next/patch 2023-11-13 16:25:41 -07:00
Aiden McClelland
4b44d6fb83 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-13 16:25:24 -07:00
Aiden McClelland
ba8df96e41 Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-13 16:24:12 -07:00
Aiden McClelland
722a30812f fix make test 2023-11-13 16:23:52 -07:00
Aiden McClelland
0e2fc07881 remove js-engine 2023-11-13 16:22:35 -07:00
Matt Hill
0ae3e83ce4 fix makefile 2023-11-13 16:21:14 -07:00
Matt Hill
f4b573379d Merge branch 'next/major' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-11-13 16:14:31 -07:00
Matt Hill
862ca375ee rename frontend to web 2023-11-13 15:59:16 -07:00
Matt Hill
06bed20a2a Update README.md (#2511) 2023-11-13 15:52:02 -07:00
Aiden McClelland
5c578c0328 Merge branch 'next/minor' of github.com:Start9Labs/start-os into integration/new-container-runtime 2023-11-13 15:42:51 -07:00
Aiden McClelland
530de6741b Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-13 15:41:58 -07:00
Aiden McClelland
5f7ff460fb fix merge 2023-11-13 15:41:35 -07:00
Aiden McClelland
3b3e1e37b9 readd core/startos/src/s9pk/mod.rs 2023-11-13 15:38:44 -07:00
Aiden McClelland
5f40d9400c move container init system to project root 2023-11-13 15:29:27 -07:00
Aiden McClelland
fcdc642acb Merge branch 'next/minor' of github.com:Start9Labs/start-os into chore/removing-non-long-running 2023-11-13 15:26:04 -07:00
J H
46f594ab71 chore: Add in the changes that where discussed with @Dr_Bonez in the room 2023-11-13 15:18:51 -07:00
J H
e8684cbb9d Merge branch 'feature/start_init' into chore/removing-non-long-running 2023-11-13 15:16:25 -07:00
J H
a36ab71600 chore: Add some more comments for DrBones 2023-11-13 15:16:21 -07:00
Aiden McClelland
35c1ff9014 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-13 14:59:16 -07:00
Aiden McClelland
e4ce05f94d Merge branch 'next/patch' of github.com:Start9Labs/start-os into next/minor 2023-11-13 14:28:26 -07:00
Aiden McClelland
9a9eb57676 Merge branch 'master' of github.com:Start9Labs/start-os into next/patch 2023-11-13 14:25:05 -07:00
Matt Hill
86567e7fa5 rename frontend to web and update contributing guide (#2509)
* rename frontend to web and update contributing guide

* rename this time

* fix build

* restructure rust code

* update documentation

* update descriptions

* Update CONTRIBUTING.md

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-11-13 21:22:23 +00:00
J H
38a624fecf chore: Remove the todoes that we have done.
Leaving in the thing about  the rpc client because that will be part of the rewrite, and some of the previous logic should be usefull for the next version of the api. We do need a bidirection but that should world
2023-11-13 10:55:39 -07:00
Aiden McClelland
fd96859883 [feature]: s9pk v2 (#2507)
* feature: s9pk v2

wip

wip

wip

wip

refactor

* use WriteQueue

* fix proptest

* LoopDev
eager directory hash verification
2023-11-10 21:57:21 +00:00
Aiden McClelland
b7b022cc7b [chore]: fix automated tests (#2506)
* fix automated tests

* automated test gh workflow

* rename workflow

* ignore test that relies on physical hardware

* use HOME env var when relevant

* optimize

* fix test
2023-11-10 14:15:47 -07:00
J H
94d22ed1aa chore: Remove the other procedures since all are now via the js 2023-11-10 09:26:00 -07:00
Aiden McClelland
3f4caed922 Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major 2023-11-09 16:33:15 -07:00
Aiden McClelland
521014cd1f rename next 2023-11-09 16:29:22 -07:00
Matt Hill
09303ab2fb make it run 2023-11-09 16:04:18 -07:00
Matt Hill
df1ac8e1e2 makefile too 2023-11-09 15:36:20 -07:00
Matt Hill
7a55c91349 rebased and compiling again 2023-11-09 15:35:47 -07:00
Alex Inkin
c491dfdd3a feat: use routes for service sections (#2502)
* feat: use routes for service sections

* chore: fix comment
2023-11-09 12:23:58 -07:00
J H
b5da076e2c chore: Add in some modifications to make the sandboxed and execute in the container 2023-11-08 17:19:30 -07:00
J H
18cd6c81a3 chore: Make sure the test is testing something is correct shape 2023-11-08 15:53:29 -07:00
Matt Hill
d9cc21f761 merge from master and fix typescript errors 2023-11-08 15:44:05 -07:00
J H
40b19c5e67 chore: Remove the long running from the docker 2023-11-08 15:35:08 -07:00
Matt Hill
871f78b570 Feature/server status restarting (#2503)
* extend `server-info`

* add restarting, shutting down to FE status bar

* fix build

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-11-08 02:31:18 -07:00
Aiden McClelland
753fbc0c5c disable CoW for journal (#2501) 2023-11-07 18:16:02 +00:00
Aiden McClelland
748277aa0e do not wait for input on btrfs repair (#2500) 2023-11-07 09:21:32 -07:00
Aiden McClelland
bf40a9ef6d improve Invoke api (#2499)
* improve Invoke api

* fix formatting
2023-11-06 17:26:45 -07:00
Lucy
733000eaa2 fix docs links (#2498)
* fix docs links

* forgot to save file

* fix docs links and small updates to ca wizard

* add downloaded filename

* fix skip detail
2023-11-06 17:24:15 -07:00
Alex Inkin
06207145af refactor: refactor sideload page (#2475)
* refactor: refactor sideload page

* chore: improve ux

* chore: update

* chore: update
2023-11-06 12:05:05 -05:00
Lucy
6a399a7250 Fix/setup (#2495)
* move enter-click directive to shared

* allow enter click to continue to login in kiosk mode; adjust styling

* cleanup

* add styling to ca wizard

* rebase new changes

* mobile fixes

* cleanup

* cleanup

* update styling

* cleanup import

* minor css changes

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-11-02 17:35:55 -06:00
Aiden McClelland
7ba22f1a09 mute errors due to failed incoming network connections (#2497)
* mute errors due to failed incoming network connections

* fix log entry formatting

* Update cleanDanglingImages

* Update cleanDanglingImages
2023-11-02 17:33:41 -06:00
Aiden McClelland
f54f950f81 fix js backups (#2496) 2023-11-02 23:13:48 +00:00
Matt Hill
4625711606 better UX for http/https switching (#2494)
* open https in same tab

* open http in same tab, use windowRef instead of window
2023-11-02 09:34:00 -06:00
Aiden McClelland
5735ea2b3c change grub os selection to say "StartOS" (#2493)
* change grub os selection to say "StartOS"

* readd "v" to motd
2023-11-01 18:35:18 -06:00
Matt Hill
b597d0366a fix time display bug and type metrics (#2490)
* fix time display bug and type metrics

* change metrics response

* nullable temp

* rename percentage used

* match frontend types

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-11-01 22:30:54 +00:00
Matt Hill
9c6dcc4a43 use keys to complete setup and redesign final buttons (#2492) 2023-11-01 22:30:42 +00:00
Aiden McClelland
27c5464cb6 use low mem for all argon2 configs (#2491)
* reduce argon2 memory usage

* update FE argon2

* fix missing typedefs

* use low mem for all argon2 configs
2023-11-01 22:28:59 +00:00
Matt Hill
1dad7965d2 rework ca-wiz and add icons to menu for warnings (#2486)
* rework ca-wiz and add icons to menu for warnings

* remove root CA button from home page

* load fonts before calling complete in setup wiz
2023-11-01 19:36:56 +00:00
Aiden McClelland
c14ca1d7fd use existing dependency icon if available (#2489) 2023-11-01 19:23:14 +00:00
Mariusz Kogen
2b9e7432b8 Updated motd with new logo (#2488) 2023-11-01 19:22:49 +00:00
Aiden McClelland
547747ff74 continuous deployment (#2485)
* continuous deployment

* fix

* escape braces in format string

* Update upload-ota.sh

* curl fail on http error
2023-11-01 19:22:34 +00:00
J H
e5b137b331 fix: Logging in deno to filter out the info (#2487)
Co-authored-by: jh <jh@Desktop.hsd1.co.comcast.net>
2023-10-31 15:38:00 -06:00
Aiden McClelland
9e554bdecd cleanup network keys on uninstall (#2484) 2023-10-30 16:43:00 +00:00
Aiden McClelland
765b542264 actually enable zram during migration (#2483)
actually enable zram during mifration
2023-10-27 23:34:02 +00:00
Aiden McClelland
182a095420 use old secret key derivation function (#2482)
* use old secret key derivation function

* compat

* cargo
2023-10-27 23:32:21 +00:00
Aiden McClelland
0865cffddf add 1 day margin on start time (#2481) 2023-10-27 18:56:06 +00:00
Aiden McClelland
5a312b9900 use correct sigterm_timeout (#2480) 2023-10-27 18:55:55 +00:00
Matt Hill
af2b2f33c2 Fix/ntp (#2479)
* rework ntp faiure handling and display to user

* uptime in seconds

* change how we handle ntp

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-10-26 23:33:57 +00:00
Aaron Dewes
9aa08dfb9b Delete Cargo.lock (#2477) 2023-10-26 22:16:52 +00:00
Matt Hill
b28c673133 closes #2454 (#2478) 2023-10-26 16:02:53 -06:00
Matt Hill
9a545f176d diplay restoring when restoring (#2476) 2023-10-25 12:08:39 -06:00
Lucy
65728eb6ab allow tab completion on final setup stage in kiosk mode (#2473) 2023-10-25 00:24:11 -06:00
Aiden McClelland
531e037974 Bugfix/argon2 mem usage (#2474)
* reduce argon2 memory usage

* update FE argon2

* fix missing typedefs
2023-10-25 00:17:29 -06:00
Aiden McClelland
a96467cb3e fix raspi build (#2472)
* fix raspi build

* Update build.sh
2023-10-24 21:27:33 +00:00
Aiden McClelland
6e92a7d93d Bugfix/output timeout (#2471)
* Fix: Test with the buf reader never finishing

* fix NoOutput deserialization

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-10-23 21:46:46 -06:00
Aiden McClelland
740e63da2b enable zram by default (#2470) 2023-10-23 21:01:52 +00:00
J H
a69cae22dd chore: Cleaning up the stream to a regular stream (#2468) 2023-10-23 20:41:54 +00:00
Aiden McClelland
8ea3c3c29e consolidate and streamline build (#2469)
* consolidate and streamline build

* fix workflow syntax

* fix workflow syntax

* fix workflow syntax

* fix workflow syntax

* fix build scripts

* only build platform-specific system images

* fix build script

* more build fixes

* fix

* fix compat build for x86

* wat

* checkout

* Prevent rebuild of compiled artifacts

* Update startos-iso.yaml

* Update startos-iso.yaml

* fix raspi build

* handle missing platform better

* reduce arm vcpus

* remove arch and platform from fe config, add to patch db

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-10-23 20:40:00 +00:00
Alex Inkin
b195e3435f fix: fix discussed issues (#2467)
* fix: fix discussed issues

* chore: fix issues

* fix package lock

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-10-22 16:49:05 -06:00
Aiden McClelland
63ab739b3d update Cargo.lock 2023-10-19 09:08:15 -06:00
Aiden McClelland
34b4577c0b Merge branch 'next' of github.com:Start9Labs/start-os into rebase/integration/refactors 2023-10-18 17:55:09 -06:00
Aiden McClelland
58bb788034 chore: update dependencies (#2465)
* chore: update dependencies

* fix crypto

* update deno

* update release notes
2023-10-18 22:53:54 +00:00
J H
9e633b37e7 Fix/quarantine deno (#2466)
* fix: Move the deno embedded into a seperate binary.

This should be the quick hacky way of making sure that the memory leaks wont happen

* fix:
2023-10-18 22:02:45 +00:00
Lucy
bb6a4842bd Update/misc fe (#2463)
* update to use transparent icon; add icon to login

* update setup mocks to imitate reality

* update webmanifest version

* fix version in webmanifest

* reset icons with background; update login page style

* adjust login header

* cleanup + adjust icon size

* revert icon

* cleanup and reposition error message
2023-10-18 12:24:48 -06:00
Aiden McClelland
246727995d add tokio-console if unstable (#2461)
* add tokio-console if `unstable`

* instrument vhost controller
2023-10-17 19:25:44 +00:00
Aiden McClelland
202695096a Feature/simple syncdb (#2464)
* simplify db sync on rpc endpoints

* switch to patch-db master

* update fe for websocket only stream

* fix api

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-10-17 15:49:58 +00:00
J H
afbab293a8 Chore: remove an arc mutex that wasn't neccessary (#2462) 2023-10-16 22:26:59 +00:00
Aiden McClelland
78faf888af fix some causes of start wonkiness on update (#2458)
* fix some causes of start wonkiness on update

* fix race condition with manager

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* only restart if running

* fix start function

* clean up clode

* fix restart logic

---------

Co-authored-by: J H <Blu-J@users.noreply.github.com>
2023-10-16 18:34:12 +00:00
Matt Hill
5164c21923 stop while starting or restarting (#2460) 2023-10-16 18:23:12 +00:00
Aiden McClelland
edcd1a3c5b only use first sensor of each group for temp reporting (#2457) 2023-10-16 18:19:24 +00:00
Lucy
532ab9128f add apollo review badge and update badges with icons (#2456)
* add apollo review badge and update badges with icons

* fix mastodon
2023-10-16 12:16:44 -06:00
Aiden McClelland
a3072aacc2 add firmware updater (#2455) 2023-10-16 17:42:42 +00:00
Alex Inkin
8034e5bbcb refactor: refactor updates page to get rid of ionic (#2459) 2023-10-15 21:31:34 -06:00
Alex Inkin
df7a30bd14 refactor: refactor backups page to get rid of ionic (#2446) 2023-10-13 09:04:20 -06:00
Lucy
27296d8880 update docs links (#2452)
* update docs links

* update backups links

* add anchor tag back to trust root ca link

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-10-13 09:02:59 -06:00
J H
8549b9bc37 fix: Add in logging for the podman in the system logs (#2451)
* fix: Add in logging for the podman in the system logs

* https as default for main tor address

---------

Co-authored-by: agent <kn0wmad@protonmail.com>
2023-10-10 14:13:56 -06:00
Aiden McClelland
7632373097 fix cors middleware (#2450)
* fix cors response

* fix cors properly
2023-10-09 17:34:27 -06:00
Matt Hill
23b0674ac0 fix cert name and show ca wiz on http ip (#2448) 2023-10-06 16:40:11 -06:00
Matt Hill
01f0484a0e fix health check error (#2447) 2023-10-06 15:25:58 -06:00
Mariusz Kogen
3ca9035fdb Use the correct OS name (#2445)
Use correct OS name
2023-10-06 09:29:54 -06:00
Matt Hill
caaf9d26db Fix/patch fe (#2444)
* clear caches on logout

* fix uninstall pkg missing error
2023-10-05 19:04:10 -06:00
Aiden McClelland
eb521b2332 enable trimming in luks (#2443) 2023-10-05 23:40:44 +00:00
Aiden McClelland
68c29ab99e allow UNSET country code for wifi (#2442) 2023-10-05 22:14:51 +00:00
Matt Hill
f12b7f4319 fix cert endpoint 2023-10-05 14:42:41 -06:00
Aiden McClelland
7db331320a Update LICENSE (#2441)
* Update LICENSE

* update README.md

* update release notes
2023-10-05 19:37:31 +00:00
Aiden McClelland
97ad8a85c3 update cargo lock 2023-10-05 08:59:24 -06:00
Aiden McClelland
6f588196cb set governor to "performance" if available (#2438)
* set governor to "performance" if available

* add linux-cpupower

* fix: Boolean blindness, thanks @dr-bones

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-10-04 20:52:56 +00:00
Aiden McClelland
20241c27ee prevent stack overflow on shutdown (#2440)
* prevent stack overflow on shutdown

* fix

---------

Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-10-04 19:51:58 +00:00
Matt Hill
05d6aea37f remove hard coded timeout 2023-10-04 13:06:49 -06:00
Matt Hill
7e0e7860cd cancel old request and base interval on tor (#2439) 2023-10-04 13:00:49 -06:00
J H
a0afd7b8ed fixing: Reimplement https://github.com/Start9Labs/start-os/pull/2391 (#2437)
* fixing: Reimplement https://github.com/Start9Labs/start-os/pull/2391

* remove the none thing
2023-10-04 18:06:43 +00:00
Matt Hill
500369ab2b Update/logos (#2435)
* update logos to startos icon

* readme too

* fix spelling
2023-10-03 10:53:29 -06:00
Aiden McClelland
dc26d5c0c8 Bugfix/var tmp (#2434)
* mount /var/tmp to data drive

* clear var tmp on restart
2023-10-02 21:50:05 +00:00
Aiden McClelland
0def02f604 mount /var/tmp to data drive (#2433) 2023-10-02 21:18:39 +00:00
J H
0ffa9167da feat: Add in the ssl_size (#2432)
* feat: Add in the ssl_size

* chore: Changes for the naming and other things.
2023-10-02 21:15:24 +00:00
Aiden McClelland
a110e8f241 make migration more resilient 2023-10-02 10:02:40 -06:00
gStart9
491f363392 Shore up Firefox kiosk mode (#2422)
* Shore up Firefox kiosk mode

* Bash shell for kiosk user

* enable-kiosk script final-ish touches

* make script idempotent

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-09-30 00:32:15 +00:00
Matt Hill
33a67bf7b4 bump FE version and release notes (#2429)
* bump FE version and release notes

* change cargo.toml version

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-09-29 22:32:10 +00:00
Matt Hill
1e6f583431 only emit when things change (#2428)
* only emit when things change

* remove log

* remove test call

* more efficient, thanks BluJ

* point free
2023-09-29 14:36:40 -06:00
J H
5e3412d735 feat: Change all the dependency errors at once (#2427)
* feat: Change all the dependency errors at once

* remove deprecated dependency-errors field

* set pointers to [] by default

* chore: Something about fixing the build

* fix migration

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-09-29 12:08:53 -06:00
Matt Hill
e6e4cd63f3 fix welcome page 2023-09-28 14:54:20 -06:00
Matt Hill
d9dfacaaf4 fe fixes after merge 2023-09-28 14:10:04 -06:00
Aiden McClelland
d43767b945 Merge branch 'next' of github.com:Start9Labs/start-os into rebase/integration/refactors 2023-09-28 13:27:41 -06:00
Aiden McClelland
f5da5f4ef0 registry admin script (#2426)
* registryadmin scripts

Add `start-sdk publish` command which can potentially replace
the Haskell implementation of `registry-publish upload`

* restructure modules

---------

Co-authored-by: Sam Sartor <me@samsartor.com>
2023-09-28 17:19:31 +00:00
J H
9a202cc124 Refactor/patch db (#2415)
* the only way to begin is by beginning

* chore: Convert over 3444 migration

* fix imports

* wip

* feat: convert volume

* convert: system.rs

* wip(convert): Setup

* wip properties

* wip notifications

* wip

* wip migration

* wip init

* wip auth/control

* wip action

* wip control

* wiip 034

* wip 344

* wip some more versions converted

* feat: Reserialize the version of the db

* wip rest of the versions

* wip s9pk/manifest

* wip wifi

* chore: net/keys

* chore: net/dns

* wip net/dhcp

* wip manager manager-map

* gut dependency errors

* wip update/mod

* detect breakages locally for updates

* wip: manager/mod

* wip: manager/health

* wip: backup/target/mod

* fix: Typo addresses

* clean control.rs

* fix system package id

* switch to btreemap for now

* config wip

* wip manager/mod

* install wip

Co-authored-by: J H <Blu-J@users.noreply.github.com>

* chore: Update the last of the errors

* feat: Change the prelude de to borrow

* feat: Adding in some more things

* chore: add to the prelude

* chore: Small fixes

* chore: Fixing the small errors

* wip: Cleaning up check errors

* wip: Fix some of the issues

* chore: Fix setup

* chore:fix version

* chore: prelude, mod, http_reader

* wip backup_bulk

* chore: Last of the errors

* upadte package.json

* chore: changes needed for a build

* chore: Removing some of the linting errors in the manager

* chore: Some linting 101

* fix: Wrong order of who owns what

* chore: Remove the unstable

* chore: Remove the test in the todo

* @dr-bonez did a refactoring on the backup

* chore: Make sure that there can only be one override guard at a time

* resolve most todos

* wip: Add some more tracing to debug an error

* wip: Use a mv instead of rename

* wip: Revert some of the missing code segments found earlier

* chore: Make the build

* chore: Something about the lib looks like it iis broken

* wip: More instrument and dev working

* kill netdummy before creating it

* better db analysis tools

* fixes from testing

* fix: Make add start the service

* fix status after install

* make wormhole

* fix missing icon file

* fix data url for icons

* fix: Bad deser

* bugfixes

* fix: Backup

* fix: Some of the restor

* fix: Restoring works

* update frontend patch-db types

* hack it in (#2424)

* hack it in

* optimize

* slightly cleaner

* handle config pointers

* dependency config errs

* fix compat

* cache docker

* fix dependency expectation

* fix dependency auto-config

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: J H <Blu-J@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2023-09-27 21:46:48 +00:00
Aiden McClelland
c305deab52 do not require auth for cert (#2425)
* do not require auth for cert

* use unauthenticated cert path

---------

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2023-09-27 20:12:07 +00:00
Lucy
0daaf3b1ec enable switching to https on login page (#2406)
* enable switching to https on login page

* add trust Root CA to http login page

* add node-jose back for setup wiz

* add tooltips, branding, logic for launch box spinner display, and enable config to toggle https mode on mocks

* cleanup

* copy changes

* style fixes

* abstract component, fix https mocks

* always show login from localhost

* launch .local when on IP

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-09-26 12:47:47 -06:00
Alex Inkin
cb36754c46 refactor: refactor service page to get rid of ionic (#2421) 2023-09-26 12:37:46 -06:00
J H
8e21504bdb fix: initialize images before netdummy (#2418) 2023-09-14 20:06:44 +00:00
Alex Inkin
7e18aafe20 feat(portal): add scrolling to the desktop (#2410)
* feat(portal): add scrolling to the desktop

* chore: comments

* chore: fix
2023-09-13 12:52:25 -06:00
Mariusz Kogen
fcf1be52ac Add tor-check to CLI (#2412)
* Link tor-check

* Add tor-check.sh

* Improve code readability

* Link tor-check from postinst
2023-09-13 12:25:00 -06:00
Mariusz Kogen
394bc9ceb8 SDK install script fix (#2411) 2023-09-07 23:40:04 -06:00
Aiden McClelland
e3786592b2 Feature/remove bollard (#2396)
* wip

* remove bollard, add podman feature

* fix error message parsing

* fix subcommand

* fix typo

* use com.docker.network.bridge.name for podman

* fix parse error

* handle podman network interface nuance

* add libyajl2

* use podman repos

* manually add criu

* do not manually require criu

* remove docker images during cleanup stage

* force removal

* increase img size

* Update startos-iso.yaml

* don't remove docker
2023-08-24 19:20:48 -06:00
Aiden McClelland
d6eaf8d3d9 disable docker memory accounting (#2399) 2023-08-23 16:47:43 +00:00
J H
b1c23336e3 Refactor/service manager (#2401)
* wip: Pulling in the features of the refactor since march

* chore: Fixes to make the system able to build

* chore: Adding in the documentation for the manager stuff

* feat: Restarting and wait for stop

* feat: Add a soft shutdown not commit to db.

* chore: Remove the comments of bluj

* chore: Clean up some of the linting errors

* chore: Clean up the signal

* chore: Some more cleanup

* fix: The configure

* fix: A missing config

* fix: typo

* chore: Remove a comment of BLUJ that needed to be removed
2023-08-23 00:08:55 -06:00
Jadi
44c5073dea backend: sdk init: output file location. fixes #1854 (#2393)
* `start-sdk init` used to run completely silent. Now we are
  showing the current/generated developer.key.pem based on
  ticket https://github.com/Start9Labs/start-os/issues/1854
2023-08-17 22:24:03 +00:00
J H
b7593fac44 Fixes: Builds for the macs (#2397)
* Fixes: Builds for the macs

* misc: Allow the feature flags run during the build for the avahi tools
2023-08-17 22:23:33 +00:00
J H
7a31d09356 feature: Include the start init files.
This includes the docker commands to get things compressed.
And this is the start of the rpc, but needs lots of work, or very little, not sure yet anymore.
I beleive that the things that are missing are the rpc, and the effects. So, lots of work, but is still good to have I suppose.
2023-08-17 12:49:06 -06:00
J H
af116794c4 fix: Add in the code to create the life check for the ui to keep the … (#2391)
* fix: Add in the code to create the life check for the ui to keep the ws alive

* Update Cargo.toml

* Update rpc.rs
2023-08-16 18:43:17 +00:00
Jadi
88c85e1d8a frontend: ui: bugfix: consistent password length. (#2394)
fronend: ui: bugfix: consistent password length.

* The password set dialogue forces maxlenght=64 but when logging in,
  the dialogue does not forces this. This makes an issue when the user
  copy/pastes a longer than 64 character password in boxes. closes #2375
2023-08-16 07:59:05 -06:00
Matt Hill
f7b079b1b4 start menu lol (#2389)
* start menu lol

* add icons, abstract header menu

* chore: few tweaks

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2023-08-14 07:39:07 -06:00
Aiden McClelland
9322b3d07e be resilient to bad lshw output (#2390) 2023-08-08 17:36:14 -06:00
Aiden McClelland
72ffedead7 fix build 2023-08-08 12:03:54 -06:00
Matt Hill
cf3a501562 Merge branch 'rebase/integration/refactors' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-08-08 10:46:07 -06:00
Matt Hill
7becdc3034 remove qr from deprecated component 2023-08-08 10:43:16 -06:00
Aiden McClelland
f0d599781d Merge branch 'rebase/integration/refactors' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-08-08 10:17:28 -06:00
Aiden McClelland
3386105048 Merge branch 'next' of github.com:Start9Labs/start-os into rebase/integration/refactors 2023-08-08 10:08:59 -06:00
Lucy
3b8fb70db1 Fix/shared module build (#2385)
* update shared version so latest can be pulled into brochure marketplace project

* updated shared to work with new brochure marketplace
2023-08-08 09:52:00 -06:00
Matt Hill
c3ae146580 proxies (#2376)
* proxies

* OS outbound proxy. ugly, needs work

* abstract interface address management

* clearnet and outbound proxies for services

* clean up

* router tab

* smart launching of UIs

* update sdk types

* display outbound proxy on service show and rework menu
2023-08-07 15:14:03 -06:00
Alex Inkin
0d079f0d89 feat(portal): implement drag and drop add/remove (#2383) 2023-08-06 13:30:53 -06:00
Lucy
55f5329817 update readme layout and assets (#2382)
* update readme layout and assets

* Update README.md

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2023-08-02 21:45:14 -04:00
Matt Hill
79d92c30f8 Update README.md (#2381) 2023-08-02 12:37:07 -06:00
Aiden McClelland
73229501c2 Feature/hw filtering (#2368)
* update deno

* add proxy

* remove query params, now auto added by BE

* add hardware requirements and BE reg query params

* update query params for BE requests

* allow multiple arches in hw reqs

* explain git hash mismatch

* require lshw

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-08-02 09:52:38 -06:00
Reckless_Satoshi
32ca91a7c9 add qr code to insights->about->tor (#2379)
* add qr code to insights->about->tor

* fix address PR feedback from @elvece; inject modelCtrl in ctor
2023-08-01 17:06:47 -04:00
Alex Inkin
9f5a90ee9c feat(portal): implement adding/removing to desktop (#2374)
* feat(portal): implement adding/removing to desktop, reordering desktop items, baseline for system utils

* chore: fix comments

---------

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2023-07-27 12:51:15 -06:00
Matt Hill
a5307fd8cc modernize reset password flow for TUI 2023-07-26 11:53:29 -06:00
Matt Hill
180589144a fix server show type errors 2023-07-26 11:39:20 -06:00
Matt Hill
d9c1867bd7 Merge branch 'rebase/integration/refactors' of github.com:Start9Labs/start-os into rebase/feat/domains 2023-07-26 11:01:56 -06:00
Matt Hill
da37d649ec Merge branch 'master' of github.com:Start9Labs/start-os into rebase/integration/refactors 2023-07-26 10:48:45 -06:00
Aiden McClelland
9e03ac084e add cli & rpc to edit db with jq syntax (#2372)
* add cli & rpc to edit db with jq syntax

* build fixes

* fix build

* fix build

* update cargo.lock
2023-07-25 16:22:58 -06:00
Aiden McClelland
082c51109d fix missing parent dir (#2373) 2023-07-25 10:07:10 -06:00
Aiden McClelland
8f44c75dc3 switch back to github caching (#2371)
* switch back to github caching

* remove npm and cargo cache

* misc fixes
2023-07-25 10:06:57 -06:00
Alex Inkin
4204b4af90 feat(portal): basis for drawer and cards (#2370) 2023-07-20 18:17:32 -06:00
Aiden McClelland
234f0d75e8 mute unexpected eof & protect against fd leaks (#2369) 2023-07-20 17:40:30 +00:00
Lucy
564186a1f9 Fix/mistake reorganize (#2366)
* revert patch for string parsing fix due to out of date yq version

* reorganize conditionals

* use ng-container

* alertButton needs to be outside of template or container
2023-07-19 10:54:18 -06:00
Lucy
ccdb477dbb Fix/pwa refresh (#2359)
* fix ROFS error on os install

* attempt to prompt browser to update manifest data with id and modified start_url

* update icon with better shape for ios

* add additional options for refreshing on pwas

* add loader to pwa reload

* fix pwa icon and add icon for ios

* add logic for refresh display depending on if pwa

* fix build for ui; fix numeric parsing error on osx

* typo

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-07-19 09:11:23 -06:00
Aiden McClelland
5f92f9e965 fix ROFS error on os install (#2364) 2023-07-19 08:50:02 -06:00
Aiden McClelland
c2db4390bb single platform builds (#2365) 2023-07-18 19:50:27 -06:00
Matt Hill
11c21b5259 Fix bugs (#2360)
* fix reset tor, delete http redirect, show message for tor http, update release notes

* potentially fix doubel req to registries

* change language arund LAN and root ca

* link locally instead of docs
2023-07-18 12:38:52 -06:00
Aiden McClelland
3cd9e17e3f migrate tor address to https (#2358) 2023-07-18 12:08:34 -06:00
Aiden McClelland
1982ce796f update deno (#2361) 2023-07-18 11:59:00 -06:00
Mariusz Kogen
941650f668 Fix motd 2023-07-16 18:39:26 +02:00
Alex Inkin
9c0c6c1bd6 feat: basis for portal (#2352) 2023-07-16 09:50:56 -06:00
Aiden McClelland
825e18a551 version bump (#2357)
* version bump

* update welcome page

---------

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2023-07-14 14:58:19 -06:00
Aiden McClelland
9ff0128fb1 support http2 alpn handshake (#2354)
* support http2 alpn handshake

* fix protocol name

* switch to https for tor

* update setup wizard and main ui to accommodate https (#2356)

* update setup wizard and main ui to accommodate https

* update wording in download doc

* fix accidential conversion of tor https for services and allow ws still

* redirect to https if available

* fix replaces to only search at beginning and ignore localhost when checking for https

---------

Co-authored-by: Lucy <12953208+elvece@users.noreply.github.com>
2023-07-14 14:58:02 -06:00
Matt Hill
bd0ddafcd0 round out adding new domains 2023-07-14 12:53:26 -06:00
Matt Hill
36c3617204 permit IP for cifs backups (#2342)
* permit IP for cifs backups

* allow ip instead of hostname (#2347)

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-07-14 18:52:33 +00:00
Aiden McClelland
90a9db3a91 disable encryption for new raspi setups (#2348)
* disable encryption for new raspi setups

* use config instead of OS_ARCH

* fixes from testing
2023-07-14 18:30:52 +00:00
Aiden McClelland
59d6795d9e fix all references embassyd -> startd (#2355) 2023-07-14 18:29:20 +00:00
Aiden McClelland
2c07cf50fa better transfer progress (#2350)
* better transfer progress

* frontend for calculating transfer size

* fixes from testing

* improve internal api

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2023-07-13 19:40:53 -06:00
Aiden McClelland
cc0e525dc5 fix incoherent when removing (#2332)
* fix incoherent when removing

* include all packages for current dependents
2023-07-13 20:36:48 +00:00
Aiden McClelland
73bd973109 delete disk guid on reflash (#2334)
* delete disk guid on reflash

* delete unnecessary files before copy
2023-07-13 20:36:35 +00:00
Matt Hill
19f5e92a74 drop ipv4 from specific domain config 2023-07-12 17:09:49 -06:00
Aiden McClelland
a7e501d874 pack compressed assets into single binary (#2344)
* pack compressed assets into single binary

* update naming

* tweaks

* fix build

* fix cargo lock

* rename CLI

* remove explicit ref name
2023-07-12 22:51:05 +00:00
BluJ
3202c38061 chore: Remove some of the things that are missing 2023-07-12 14:01:56 -06:00
Matt Hill
4676f0595c add reset password to UI (#2341) 2023-07-11 17:23:40 -06:00
Alex Inkin
e35a8c942b fix: libraries build (#2346) 2023-07-11 17:28:05 -04:00
Matt Hill
31811eb91e fix errors in shared and marketplace 2023-07-11 12:53:42 -06:00
Alex Inkin
b9316a4112 Update angular (#2343)
* chore: update to Angular 15

* chore: update to Angular 16

* chore: update Taiga UI
2023-07-10 13:35:53 -06:00
BluJ
b7abd878ac chore: Use send_modify instead of send 2023-07-10 10:36:16 -06:00
Matt Hill
38c2c47789 Feat/domains
update FE types and unify sideload page with marketplace show

begin popover for UI launch select

update node version for github workflows

fix type errors

eager load more components

fix mocks for types

recalculate updates bad on pkg uninstall

chore: break form-object file structure

files for config

finish file upload API and implement for config

chore: break down form-object by type, part 1

remove NEW from config

comment entire setTimeout for new

generic form options

chore: break down form-object by type, part 2

headers for enums and unions

implement select and multiselect for config

update union types and camel case for specs

implement textarea config value

inputspec and required instead of nullable

remove subtype from list spec

update start-sdk

bump start-sdk

feat: use Taiga UI for config modal (#2250)

* feat: use Taiga UI for config modal

* chore: finish remaining changes

* chore: address comments

* bump sdk version

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

update package lock

update to sdk 20 and fix types

chore: update Taiga UI and migrate some more forms (#2252)

update form to latest sdk

validate length for textarea too

chore: accommodate new changes to the specs (#2254)

* chore: accommodate new changes to the specs

* chore: fix error

* chore: fix error

feat: add input color (#2257)

* feat: add input color

* patterns will always be there

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

chore: properly type pattern error

update to latest sdk

Add sans-serif font fallback (#2263)

* Add sans-serif font fallback

* Update frontend readme start scripts

feat: add datetime spec support (#2264)

Wifi optional (#2249)

* begin work

* allow enable and disable wifi

* nice styling

* done except for popover not dismissing

* update wifi.ts

* address comments

Feat/automated backups (#2142)

* initial restructuring

* very cool

* new structure in place

* delete unnecessary T

* down the rabbit hole

* getting better

* dont like it

* nice

* very nice

* sessions select all

* nice

* backup runs

* fix targets and more

* small improvements

* mostly working

* address PR comments

* fix error

* delete issue with merge

* fix checkboxes and add API for deleting backup runs

* better styling for checkboxes

* small button in ssh kpage too

* complete multiple UI launcher

* fix actions

* present error toast too

* fix target forms

Add logs window to setup wizard loading screen (#2076)

* add logs window to setup wizard loading screen

* fix type error

* Update frontend/projects/setup-wizard/src/app/services/api/live-api.service.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

---------

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

statically type server metrics and use websocket (#2124)

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

Feat/external-smtp (#1791)

* UI for EOS smtp, missing API layer

* implement api

* fix errors

* switch to external smtp creds

* fix things up

* fix types

* update types for new forms

* feat: add new form to emails and marketplace (#2268)

* import tuilet module

* feat: get rid of old form completely (#2270)

* move to builder spec and delete developer menu

* update sdk

* tiny

* getting better

* working

* done

* feat: add step to number config

* chore: small fixes

* update SDK and step for numbers

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>

latest sdk, fix build

update SDK for better disabled props

feat: implement `disabled`, `immutable` and `generate` (#2280)

* feat: implement `disabled`, `immutable` and `generate`

* chore: remove unnecessary code

* chore: add generate to textarea and implement immutable

* no generate for textarea

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

update lockfile

refactor: extract loading status to shared library (#2282)

* refactor: extract loading status to shared library

* chore: remove inline style

refactor: break routing down to apps level (#2285)

closes #2212 and closes #2214

Feat/credentials (#2290)

add credentials and remove properties

refactor: break ui up further down (#2292)

* refactor: break ui up further down

* permit loading even when authed

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

update patchdb for package compatability fixes

fix file structure

WIP

finish rebase

mvp complete

port forwards mvp

looking good

cleaner system page

move experimental features

manual port overrides

better info headers for jobs pages

refactor: move diagnostic-ui app under ui route (#2306)

* refactor: move diagnostic-ui app under ui route

* chore: hide navigation

* chore: remove ionic from diagnostic

* fix navbar showing on login

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

chore: partially remove ionic modals and loaders (#2308)

* chore: partially remove ionic modals and loaders

* change to snake

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

better session data fetching

abstract store icon component to shared marketplace project (#2311)

* abstract store icon component to shared marketplace project

* better than using a pipe

* minor cleanup

* chore: fix missing node types in libraries

* typo

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>

refactor: continue to get rid of ionic infrastructure (#2325)

refactor: finish removing ionic entities: (#2333)

* refactor: finish removing ionic entities:

ToastController
ErrorToastService
ModalController
AlertController
LoadingController

* chore: rollback testing code

* chore: fix comments

* minor form change

* chore: fix comments

* update clearnet address parts

* move around patchDB

* chore: fix comments

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

fixup after rebase
2023-07-07 12:59:31 -06:00
kn0wmad
1d3d70e8d6 Update README.md (#2337)
* Update README.md

* Update README.md
2023-07-07 10:23:31 -06:00
Aiden McClelland
c03778ec8b fixup after rebase 2023-07-07 09:53:03 -06:00
BluJ
29b0850a94 fix: Add in the sub repos 2023-07-06 15:16:17 -06:00
Matt Hill
712fde46eb fix file structure 2023-07-06 15:12:02 -06:00
Lucy Cifferello
c2e79ca5a7 update patchdb for package compatability fixes 2023-07-06 15:12:02 -06:00
Alex Inkin
c3a52b3989 refactor: break ui up further down (#2292)
* refactor: break ui up further down

* permit loading even when authed

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-07-06 15:12:02 -06:00
Matt Hill
7213d82f1b Feat/credentials (#2290)
add credentials and remove properties
2023-07-06 15:12:02 -06:00
Matt Hill
5bcad69cf7 closes #2212 and closes #2214 2023-07-06 15:12:02 -06:00
Alex Inkin
c9a487fa4d refactor: break routing down to apps level (#2285) 2023-07-06 15:11:13 -06:00
Alex Inkin
3804a46f3b refactor: extract loading status to shared library (#2282)
* refactor: extract loading status to shared library

* chore: remove inline style
2023-07-06 15:11:13 -06:00
Matt Hill
52c0bb5302 update lockfile 2023-07-06 15:10:56 -06:00
Alex Inkin
8aa19e6420 feat: implement disabled, immutable and generate (#2280)
* feat: implement `disabled`, `immutable` and `generate`

* chore: remove unnecessary code

* chore: add generate to textarea and implement immutable

* no generate for textarea

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-07-06 15:10:56 -06:00
Matt Hill
4d1c7a3884 update SDK for better disabled props 2023-07-06 15:10:56 -06:00
Matt Hill
25f2c057b7 latest sdk, fix build 2023-07-06 15:10:56 -06:00
Matt Hill
010be05920 Feat/external-smtp (#1791)
* UI for EOS smtp, missing API layer

* implement api

* fix errors

* switch to external smtp creds

* fix things up

* fix types

* update types for new forms

* feat: add new form to emails and marketplace (#2268)

* import tuilet module

* feat: get rid of old form completely (#2270)

* move to builder spec and delete developer menu

* update sdk

* tiny

* getting better

* working

* done

* feat: add step to number config

* chore: small fixes

* update SDK and step for numbers

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
2023-07-06 15:10:56 -06:00
Matt Hill
4c465850a2 lockfile 2023-07-06 15:10:56 -06:00
Aiden McClelland
8313dfaeb9 statically type server metrics and use websocket (#2124)
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-07-06 15:10:56 -06:00
Matt Hill
873f2b2814 Add logs window to setup wizard loading screen (#2076)
* add logs window to setup wizard loading screen

* fix type error

* Update frontend/projects/setup-wizard/src/app/services/api/live-api.service.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

---------

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2023-07-06 15:10:56 -06:00
Matt Hill
e53c90f8f0 Feat/automated backups (#2142)
* initial restructuring

* very cool

* new structure in place

* delete unnecessary T

* down the rabbit hole

* getting better

* dont like it

* nice

* very nice

* sessions select all

* nice

* backup runs

* fix targets and more

* small improvements

* mostly working

* address PR comments

* fix error

* delete issue with merge

* fix checkboxes and add API for deleting backup runs

* better styling for checkboxes

* small button in ssh kpage too

* complete multiple UI launcher

* fix actions

* present error toast too

* fix target forms
2023-07-06 15:10:56 -06:00
Matt Hill
9499ea8ca9 Wifi optional (#2249)
* begin work

* allow enable and disable wifi

* nice styling

* done except for popover not dismissing

* update wifi.ts

* address comments
2023-07-06 15:10:43 -06:00
Alex Inkin
f6c09109ba feat: add datetime spec support (#2264) 2023-07-06 15:10:43 -06:00
Benjamin B
273b5768c4 Add sans-serif font fallback (#2263)
* Add sans-serif font fallback

* Update frontend readme start scripts
2023-07-06 15:10:43 -06:00
Matt Hill
ee13cf7dd9 update to latest sdk 2023-07-06 15:10:43 -06:00
waterplea
fecbae761e chore: properly type pattern error 2023-07-06 15:10:43 -06:00
Alex Inkin
e0ee89bdd9 feat: add input color (#2257)
* feat: add input color

* patterns will always be there

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-07-06 15:10:43 -06:00
Alex Inkin
833c1f22a3 chore: accommodate new changes to the specs (#2254)
* chore: accommodate new changes to the specs

* chore: fix error

* chore: fix error
2023-07-06 15:10:43 -06:00
Matt Hill
6fed6c8d30 validate length for textarea too 2023-07-06 15:10:43 -06:00
Matt Hill
94cdaf5314 update form to latest sdk 2023-07-06 15:10:43 -06:00
Alex Inkin
f83ae27352 chore: update Taiga UI and migrate some more forms (#2252) 2023-07-06 15:10:43 -06:00
Matt Hill
6badf047c3 update to sdk 20 and fix types 2023-07-06 15:10:43 -06:00
Matt Hill
47de9ad15f update package lock 2023-07-06 15:10:43 -06:00
Alex Inkin
09b91cc663 feat: use Taiga UI for config modal (#2250)
* feat: use Taiga UI for config modal

* chore: finish remaining changes

* chore: address comments

* bump sdk version

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-07-06 15:10:43 -06:00
Matt Hill
ded16549f7 bump start-sdk 2023-07-06 15:10:43 -06:00
Matt Hill
c89e47577b update start-sdk 2023-07-06 15:10:43 -06:00
Matt Hill
bb50beb7ab remove subtype from list spec 2023-07-06 15:10:43 -06:00
Matt Hill
e4cd4d64d7 inputspec and required instead of nullable 2023-07-06 15:10:43 -06:00
Matt Hill
5675fc51a0 implement textarea config value 2023-07-06 15:10:43 -06:00
Matt Hill
c7438c4aff update union types and camel case for specs 2023-07-06 15:10:43 -06:00
Matt Hill
4a6a3da36c implement select and multiselect for config 2023-07-06 15:10:43 -06:00
Matt Hill
a657c332b1 headers for enums and unions 2023-07-06 15:10:43 -06:00
waterplea
cc9cd3fc14 chore: break down form-object by type, part 2 2023-07-06 15:10:43 -06:00
Matt Hill
234258a077 generic form options 2023-07-06 15:10:43 -06:00
Matt Hill
13cda80ee6 comment entire setTimeout for new 2023-07-06 15:10:43 -06:00
Matt Hill
f6e142baf5 remove NEW from config 2023-07-06 15:10:43 -06:00
waterplea
ddf1f9bcd5 chore: break down form-object by type, part 1 2023-07-06 15:10:43 -06:00
Matt Hill
aa950669f6 finish file upload API and implement for config 2023-07-06 15:10:43 -06:00
Matt Hill
dacd5d3e6b files for config 2023-07-06 15:09:48 -06:00
waterplea
e76ccba2f7 chore: break form-object file structure 2023-07-06 15:09:48 -06:00
Matt Hill
3933819d53 recalculate updates bad on pkg uninstall 2023-07-06 15:09:48 -06:00
Matt Hill
99019c2b1f fix mocks for types 2023-07-06 15:09:48 -06:00
Matt Hill
4bf5eb398b eager load more components 2023-07-06 15:09:48 -06:00
Matt Hill
dbfbac62c0 fix type errors 2023-07-06 15:09:48 -06:00
Lucy Cifferello
7685293da4 update node version for github workflows 2023-07-06 15:09:48 -06:00
Matt Hill
ee9c328606 begin popover for UI launch select 2023-07-06 15:09:48 -06:00
Matt Hill
cb7790ccba update FE types and unify sideload page with marketplace show 2023-07-06 15:09:48 -06:00
Matt Hill
6556fcc531 fix types 2023-07-06 15:08:30 -06:00
Aiden McClelland
178391e7b2 integration/refactors
wip: Refactoring the service

-> Made new skeleton
-> Added service manager
-> Manager Refactored
-> Cleanup
-> Add gid struct
-> remove synchronizer
-> Added backup into manager
-> Fix the configure signal not send
-> Fixes around backup and sync

wip: Moved over the config into the service manager

js effect for subscribing to config

js effect for subscribing to config

fix errors

chore: Fix some things in the manager for clippy

add interfaces from manifest automatically

make OsApi manager-based

wip: Starting down the bind for the effects

todo: complete a ip todo

chore: Fix the result type on something

todo: Address returning

chore: JS with callbacks

chore: Add in the chown and permissions

chore: Add in the binds and unbinds in

feat: Add in the ability to get configs

makefile changes

add start/stop/restart to effects

config hooks

fix: add a default always to the get status

chore: Only do updates when the thing is installed.

use nistp256 to satisfy firefox

use ed25519 if available

chore: Make the thing buildable for testing

chore: Add in the debugging

fix ip signing

chore: Remove the bluj tracing

fix SQL error

chore: Fix the build

update prettytable to fix segfault

Chore: Make these fn's instead of allways ran.

chore: Fix the testing

fix: The stopping/ restarting service

fix: Fix the restarting.

remove current-dependents, derive instead

remove pointers from current-dependencies

remove pointers and system pointers from FE

v0.3.4

remove health checks from manifest

remove "restarting" bool on "starting" status

remove restarting attr

update makefile

fix

add efi support

fix efi

add redirect if connecting to https over http

clean up

lan port forwarding

add `make update` and `make update-overlay`

fix migration

more protections

fix: Fix a lint

chore: remove the limit on the long-running

fix: Starting sometimes.

fix: Make it so the stop of the main works

fix: Bind local and tor with package.

wip: envs

closes #2152, closes #2155, closes #2157

fix TS error

import config types from sdk

update package.json
2023-07-06 15:08:30 -06:00
Aiden McClelland
18922a1c6d fixup after rebase 2023-07-06 15:08:30 -06:00
BluJ
5e9e26fa67 fix: Fix a lint
chore: remove the limit on the long-running

fix: Starting sometimes.

fix: Make it so the stop of the main works

fix: Bind local and tor with package.

wip: envs

fix TS error

import config types from sdk

update package.json
2023-07-06 15:08:30 -06:00
Aiden McClelland
f5430f9151 lan port forwarding 2023-07-06 15:08:30 -06:00
Aiden McClelland
4dfdf2f92f v0.3.4
remove health checks from manifest

remove "restarting" bool on "starting" status

remove restarting attr
2023-07-06 15:08:30 -06:00
Matt Hill
e4d283cc99 remove current-dependents, derive instead
remove pointers from current-dependencies

remove pointers and system pointers from FE
2023-07-06 15:08:30 -06:00
Aiden McClelland
8ee64d22b3 add start/stop/restart to effects
fix: add a default always to the get status

chore: Only do updates when the thing is installed.

chore: Make the thing buildable for testing

chore: Add in the debugging

chore: Remove the bluj tracing

chore: Fix the build

Chore: Make these fn's instead of allways ran.

chore: Fix the testing

fix: The stopping/ restarting service

fix: Fix the restarting.
2023-07-06 15:08:30 -06:00
Aiden McClelland
10e3e80042 makefile changes 2023-07-06 15:08:30 -06:00
BluJ
f77a208e2c feat: Add in the ability to get configs
config hooks
2023-07-06 15:07:53 -06:00
BluJ
9366dbb96e wip: Starting down the bind for the effects
todo: complete a ip todo

chore: Fix the result type on something

todo: Address returning

chore: JS with callbacks

chore: Add in the chown and permissions

chore: Add in the binds and unbinds in
2023-07-06 15:07:53 -06:00
Aiden McClelland
550b17552b make OsApi manager-based 2023-07-06 15:07:53 -06:00
Aiden McClelland
bec307d0e9 js effect for subscribing to config
fix errors

chore: Fix some things in the manager for clippy
2023-07-06 15:07:53 -06:00
BluJ
93c751f6eb wip: Refactoring the service
-> Made new skeleton
-> Added service manager
-> Manager Refactored
-> Cleanup
-> Add gid struct
-> remove synchronizer
-> Added backup into manager
-> Fix the configure signal not send
-> Fixes around backup and sync

wip: Moved over the config into the service manager
2023-07-06 15:07:53 -06:00
Mariusz Kogen
bada88157e Auto-define the OS_ARCH variable. (#2329) 2023-06-30 20:34:10 +00:00
J H
13f3137701 fix: Make check-version posix compliant (#2331)
We found that we couldn't compile this on the mac arm os
2023-06-29 22:28:13 +00:00
Aiden McClelland
d3316ff6ff make it faster (#2328)
* make it faster

* better pipelining

* remove unnecessary test

* use tmpfs for debspawn

* don't download intermediate artifacts

* fix upload dir path

* switch to buildjet

* use buildjet cache on buildjet runner

* native builds when fast

* remove quotes

* always use buildjet cache

* remove newlines

* delete data after done with it

* skip aarch64 for fast dev builds

* don't tmpfs for arm

* don't try to remove debspawn tmpdir
2023-06-28 13:37:26 -06:00
kn0wmad
1b384e61b4 maint/minor UI typo fixes (#2330)
* Minor copy fixes

* Contact link fixes
2023-06-28 13:03:33 -06:00
Matt Hill
addea20cab Update README 2023-06-27 10:10:01 -06:00
Matt Hill
fac23f2f57 update README 2023-06-27 10:06:42 -06:00
Aiden McClelland
bffe1ccb3d use a more resourced runner for production builds (#2322) 2023-06-26 16:27:11 +00:00
Matt Hill
e577434fe6 Update bug-report.yml 2023-06-25 13:38:26 -06:00
Matt Hill
5d1d9827e4 Update bug-report.yml 2023-06-25 13:35:45 -06:00
Aiden McClelland
dd28ad20ef use port instead of pidof to detect tor going down (#2320)
* use port instead of pidof to detect tor going down

* fix errors

* healthcheck timeout
2023-06-23 13:06:00 -06:00
Aiden McClelland
ef416ef60b prevent tor from spinning if a service is in a crash loop (#2316) 2023-06-22 18:09:59 +00:00
Aiden McClelland
95b3b55971 fix rootflags for btrfs update (#2315) 2023-06-21 15:26:27 +00:00
Aiden McClelland
b3f32ae03e don't use cp when over cifs 2023-06-21 00:36:36 +00:00
Aiden McClelland
c7472174e5 fix btrfs rootflags 2023-06-21 00:36:36 +00:00
gStart9
2ad749354d Add qemu-guest-agent for advanced VM shutdown options (#2309) 2023-06-21 00:36:36 +00:00
Aiden McClelland
4ed9d2ea22 add grub-common to build 2023-06-21 00:36:36 +00:00
Lucy Cifferello
280eb47de7 update marketplace project to include mime type pipe for icons 2023-06-21 00:36:36 +00:00
Aiden McClelland
324a12b0ff reset config after pg_upgrade 2023-06-21 00:36:36 +00:00
Aiden McClelland
a2543ccddc trim fs name 2023-06-21 00:36:36 +00:00
Aiden McClelland
22666412c3 use fsck instead of e2fsck 2023-06-21 00:36:36 +00:00
Aiden McClelland
dd58044cdf fix build 2023-06-21 00:36:36 +00:00
Aiden McClelland
10312d89d7 fix ipv6 2023-06-21 00:36:36 +00:00
Aiden McClelland
b4c0d877cb fix postgres migration 2023-06-21 00:36:36 +00:00
Aiden McClelland
e95d56a5d0 fix update-grub2 2023-06-21 00:36:36 +00:00
Aiden McClelland
90424e8329 install fixes 2023-06-21 00:36:36 +00:00
Aiden McClelland
1bfeb42a06 force btrfs creation 2023-06-21 00:36:36 +00:00
Aiden McClelland
a936f92954 use postgres user 2023-06-21 00:36:36 +00:00
Aiden McClelland
0bc514ec17 include old pg 2023-06-21 00:36:36 +00:00
Aiden McClelland
a2cf4001af improve invoke error reporting 2023-06-21 00:36:36 +00:00
Aiden McClelland
cb4e12a68c fix build 2023-06-21 00:36:36 +00:00
Aiden McClelland
a7f5124dfe postgresql migration 2023-06-21 00:36:36 +00:00
Aiden McClelland
ccbf71c5e7 fix ipv6 2023-06-21 00:36:36 +00:00
Aiden McClelland
04bf5f58d9 fix tor listener bug 2023-06-21 00:36:36 +00:00
Aiden McClelland
ab3f5956d4 ipv6 2023-06-21 00:36:36 +00:00
Aiden McClelland
c1fe8e583f backup target mount/umount 2023-06-21 00:36:36 +00:00
Lucy Cifferello
fd166c4433 do not load array buffer into memory 2023-06-21 00:36:36 +00:00
Aiden McClelland
f29c7ba4f2 don't wait for install to complete on sideload 2023-06-21 00:36:36 +00:00
Aiden McClelland
88869e9710 gpu acceleration 2023-06-21 00:36:36 +00:00
Aiden McClelland
f8404ab043 btrfs 2023-06-21 00:36:36 +00:00
Aiden McClelland
9fa5d1ff9e suite independent 2023-06-21 00:36:36 +00:00
Aiden McClelland
483f353fd0 backup luks headers 2023-06-21 00:36:36 +00:00
Aiden McClelland
a11bf5b5c7 bookworm 2023-06-21 00:36:36 +00:00
Aiden McClelland
d4113ff753 re-add server version and version range 2023-06-21 00:36:36 +00:00
Aiden McClelland
1969f036fa deser full server info 2023-06-21 00:36:36 +00:00
Matt Hill
8c90e01016 hide range ip addresses, update release notes 2023-06-15 13:20:37 -06:00
Matt Hill
756c5c9b99 small spelling mistake 2023-06-11 15:04:59 -06:00
Lucy Cifferello
ee54b355af fix compliation error on widgets page 2023-06-11 15:04:59 -06:00
Lucy Cifferello
26cbbc0c56 adjust start9 registry icon 2023-06-11 15:04:59 -06:00
Aiden McClelland
f4f719d52a misc fixes 2023-06-11 15:04:59 -06:00
Aiden McClelland
f2071d8b7e update zram bool 2023-06-11 15:04:59 -06:00
Aiden McClelland
df88a55784 v0.3.4.3 2023-06-11 15:04:59 -06:00
Matt Hill
3ccbc626ff experimental features for zram and reset tor (#2299)
* experimental features for zram and reset tor

* zram backend

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-06-11 15:04:59 -06:00
Aiden McClelland
71a15cf222 add diskUsage effect (#2297) 2023-06-11 15:04:59 -06:00
Aiden McClelland
26ddf769b1 remove overload restart rule 2023-06-11 15:04:59 -06:00
Aiden McClelland
3137387c0c only set static hostname 2023-06-11 15:04:59 -06:00
Aiden McClelland
fc142cfde8 reset tor (#2296)
* reset tor

* Update tor.rs

* timeout connect

* handle stuck bootstrapping
2023-06-11 15:04:59 -06:00
Aiden McClelland
b0503fa507 Bugfix/incoherent (#2293)
* debug incoherent error

* fix incoherent error

* use new debspawn
2023-06-11 15:04:59 -06:00
Matt Hill
b86a97c9c0 add resetTor to rpc client 2023-06-11 15:04:59 -06:00
Lucy Cifferello
eb6cd23772 update registry icon 2023-06-11 15:04:59 -06:00
Matt Hill
efae1e7e6c add Tor logs to UI 2023-06-11 15:04:59 -06:00
Lucy Cifferello
19d55b840e add registry icon to preloader 2023-06-11 15:04:59 -06:00
Lucy Cifferello
cc0c1d05ab update frontend to 0.3.4.3 2023-06-11 15:04:59 -06:00
Lucy Cifferello
f088f65d5a update branding 2023-06-11 15:04:59 -06:00
Lucy Cifferello
5441b5a06b add missing items to preloader 2023-06-11 15:04:59 -06:00
gStart9
efc56c0a88 Add crda to build/lib/depends (#2283) 2023-05-24 15:54:33 -07:00
kn0wmad
321fca2c0a Replace some user-facing Embassy language (#2281) 2023-05-22 13:23:20 -06:00
Matt Hill
bbd66e9cb0 fix nav link (#2279) 2023-05-18 18:11:27 -06:00
Aiden McClelland
eb0277146c wait for tor (#2278) 2023-05-17 22:17:27 -06:00
Aiden McClelland
10ee32ec48 always generate snake-oil (#2277) 2023-05-17 15:09:27 -06:00
Aiden McClelland
bdb4be89ff Bugfix/pi config (#2276)
* move some install scripts to init

* fix pi config.txt

* move some image stuff to the squashfs build

* no need to clean up fake-apt

* use max temp
2023-05-16 16:06:25 -06:00
Aiden McClelland
61445e0b56 build fixes (#2275)
* move some install scripts to init

* handle fake-apt in init

* rename
2023-05-15 16:34:30 -06:00
Aiden McClelland
f15a010e0e Update build badge (#2274)
Update README.md
2023-05-14 00:01:58 -06:00
Lucy C
58747004fe Fix/misc frontend (#2273)
* update pwa icon to official latest

* fix bug if icon is null in assets

* dismiss modal when connecting to a new registry
2023-05-12 14:48:16 -06:00
Lucy C
e7ff1eb66b display icons based on mime type (#2271)
* display icons based on mime type

* Update frontend/projects/marketplace/src/pipes/mime-type.pipe.ts

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* fixes

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2023-05-12 12:20:05 -06:00
Matt Hill
4a00bd4797 ensure lan address present before getting cert name (#2272) 2023-05-12 12:18:39 -06:00
Aiden McClelland
2e6fc7e4a0 v0.3.4.2 (#2269) 2023-05-12 00:35:50 -06:00
Aiden McClelland
4a8f323be7 external rename (#2265)
* backend rename

* rename embassy and closes #2179

* update root ca name on disk

* update MOTD

* update readmes

* your server typo

* another tiny typo

* fix png name

* Update backend/src/net/wifi.rs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* changes needed due to rebase

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2023-05-11 16:48:52 -06:00
Aiden McClelland
c7d82102ed Bugfix/gpt reflash (#2266)
* debug entry

* update magic numbers

* remove dbg

* fix hostname

* fix reinstall logic
2023-05-11 14:16:19 -06:00
Aiden McClelland
068b861edc overhaul OS build (#2244)
* create init resize for pi

* wip

* defer to OS_ARCH env var

* enable password auth in live image

* use correct live image path

* reorder dependencies

* add grub-common as dependency

* add more depends

* reorder grub

* include systemd-resolved

* misc fixes

* remove grub from dependencies

* imports

* ssh and raspi builds

* fix resolvectl

* generate snake-oil on install

* update raspi build process

* script fixes

* fix resize and config

* add psmisc

* new workflows

* include img

* pass through OS_ARCH env var

* require OS_ARCH

* allow dispatching production builds

* configurable environment

* pass through OS_ARCH on compat build

* fix syntax error

* crossbuild dependencies

* include libavahi-client for cross builds

* reorder add-arch

* add ports

* switch existing repos to amd64

* explicitly install libc6

* add more bullshit

* fix some errors

* use ignored shlibs

* remove ubuntu ports

* platform deb

* Update depends

* Update startos-iso.yaml

* Update startos-iso.yaml

* require pi-beep

* add bios boot, fix environment

* Update startos-iso.yaml

* inline deb

* Update startos-iso.yaml

* allow ssh password auth in live build

* sync hostname on livecd

* require curl
2023-05-05 00:54:09 -06:00
kn0wmad
3c908c6a09 Update README.md (#2261)
Minor typo fix
2023-05-02 06:26:54 -06:00
Lucy C
ba3805786c Feature/pwa (#2246)
* setup ui project with pwa configurations

* enable service worker config to work with ionic livereload

* fix service worker key placement

* update webmanifest names

* cleanup

* shrink logo size

* fix package build

* build fix

* fix icon size in webmanifest
2023-04-11 10:36:25 -06:00
Aiden McClelland
70afb197f1 don't attempt docker load if s9pk corrupted (#2236) 2023-03-21 11:23:44 -06:00
Aiden McClelland
d966e35054 fix migration 2023-03-17 18:58:49 -06:00
Aiden McClelland
1675570291 fix test 2023-03-17 14:42:32 -06:00
Aiden McClelland
9b88de656e version bump (#2232)
* version bump

* welcome notes

* 0341 release notes

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-03-17 12:55:21 -06:00
Aiden McClelland
3d39b5653d don't blow up if s9pk fails to load (#2231) 2023-03-17 12:09:24 -06:00
J H
eb5f7f64ad feat: Default to no owner for rsync (#2230) 2023-03-17 12:09:13 -06:00
Aiden McClelland
9fc0164c4d better logging of health (#2228) 2023-03-17 12:09:01 -06:00
Aiden McClelland
65eb520cca disable apt and add script for persisting apt pkgs (#2225)
* disable apt and add script for persisting apt pkgs

* fix typo

* exit 1 on fake-apt

* readd fake-apt after upgrade

* fix typo

* remove finicky protection

* fix build
2023-03-17 12:08:49 -06:00
Aiden McClelland
f7f07932b4 update registry rsync script (#2227) 2023-03-17 10:05:58 -06:00
Aiden McClelland
de52494039 fix loading authcookie into cookie store on ssh (#2226) 2023-03-17 10:05:12 -06:00
Matt Hill
4d87ee2bb6 update display obj on union change (#2224)
* update display obj on union change

* deelete unnecessary changes

* more efficient

* fix: properly change height of form object

* more config examples

---------

Co-authored-by: waterplea <alexander@inkin.ru>
2023-03-17 11:57:26 -04:00
Matt Hill
d0ba0936ca remove taiga icons (#2222) 2023-03-15 12:29:24 -06:00
Matt Hill
b08556861f Fix/stupid updates (#2221)
one more thing
2023-03-15 12:23:25 -06:00
Aiden McClelland
c96628ad49 do not log parameters 2023-03-15 12:19:11 -06:00
Matt Hill
a615882b3f fix more bugs with updates tab... (#2219) 2023-03-15 11:33:54 -06:00
Matt Hill
2bcc8e0d30 only when version higher and show after login (#2217)
* only when version higher and show after login

* unused import
2023-03-14 11:24:54 -06:00
Aiden McClelland
de519edf78 fix caching (#2216) 2023-03-13 17:25:10 -06:00
Lucy C
caf47943c3 Fix/misc UI (#2215)
* add courier new as asset

* fix login button on mobile
2023-03-13 17:24:59 -06:00
Aiden McClelland
427ab12724 wait for time sync before starting tor (#2209)
* wait for time sync before starting tor

* don't initialize /var/lib/docker
2023-03-13 15:45:36 -06:00
Matt Hill
eba16c0cc3 Fix/more UI (#2213)
* fix badge counter...again

* remove taiga styles from angular json

* better syntax
2023-03-13 15:29:39 -06:00
Aiden McClelland
a485de6359 let final build-image step create nc-broadcast (#2210) 2023-03-13 15:23:46 -06:00
Matt Hill
1a985f7e82 Fix updates badge and rework updates page (#2205)
* fix updates badge and rework updates page

* resize icons

* better language around browser tab title

* no period

* updates tab more fixes
2023-03-13 12:15:43 -06:00
Aiden McClelland
7867411095 fix stack overflow on shutdown (#2208) 2023-03-13 12:13:14 -06:00
Aiden McClelland
2f6ebd16c1 use yesterday for not_before on ssl certs (#2204) 2023-03-13 11:43:10 -06:00
Aiden McClelland
878b235614 x86 build for compat (#2203) 2023-03-10 17:11:15 -07:00
Aiden McClelland
75f9c6b0fb fix raspi kernel upgrades (#2202)
* fix build

* use same node versions

* lock kernel to 5.15.76
2023-03-10 17:11:06 -07:00
Lucy C
7c1e2bf96f fix spacing and font size (#2199)
* fix spacing and font size

* fix spacing reverted by linting

* fix styles and event propagation on updates tab

* fix login theme

* remove global font setting

* remove taiga theming for now

* move website button and bump shared and marketplace libs

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-03-10 11:24:58 -07:00
Alex Inkin
181b44e117 chore: update Taiga UI and remove unnecessary styles (#2200)
* chore: update Taiga UI and remove unnecessary styles

* update workflow and package lock

---------

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2023-03-10 10:15:38 -07:00
Aiden McClelland
f7793976fb export cert correctly 2023-03-09 18:10:52 -07:00
J H
8ffcd9b60a fix: Br is too slow, removed from encoding (#2197) 2023-03-09 15:37:41 -07:00
kn0wmad
52d3c4d62d Update CHANGELOG to v0.3.3 (#2196) 2023-03-09 15:33:45 -07:00
Aiden McClelland
0fb3e75253 fix display for SANInfo 2023-03-09 15:08:39 -07:00
Matt Hill
2c40e403c4 misc 0.3.4 bugfixes (#2193)
* display message not object on login page

* more release notes

* fix firefox ssl issue

* fix no pubkey error

* Fix/missing main (#2194)

fix: Main during migration

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
2023-03-09 12:34:48 -07:00
Aiden McClelland
d1c519ed0d remove system rebuild 2023-03-09 10:56:55 -07:00
Aiden McClelland
27470ef934 fix http -> https redirect 2023-03-09 10:45:22 -07:00
Aiden McClelland
8a1da87702 fix img naming 2023-03-09 10:12:03 -07:00
Lucy C
c8d89f805b Update/misc frontend (#2191)
* update version to 0.3.4

* update release  guide with sdk instructions

* remove comment

* update page styling

* closes #2152, closes #2155, closes #2157

* move marketing site link to description block

* re-arrange setup wizard recovery options

* move divider for update list item

* fix bug in mocks to display lnd as aavailable for update

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-03-09 07:02:48 -07:00
Aiden McClelland
c9fceafc16 Feature/efi (#2192)
* update makefile

* fix

* add efi support

* fix efi

* clean up

* add `make update` and `make update-overlay`

* more protections

* update package lock

* rename reflash to indicate it isn't real

* fix authcookie

* Update product.yaml
2023-03-09 00:10:37 -07:00
Aiden McClelland
bbb9980941 Refactor/networking (#2189)
* refactor networking and account

* add interfaces from manifest automatically

* use nistp256 to satisfy firefox

* use ed25519 if available

* fix ip signing

* fix SQL error

* update prettytable to fix segfault

* fix migration

* fix migration

* bump welcome-ack

* add redirect if connecting to https over http

* misc rebase fixes

* fix compression

* bump rustc version
2023-03-08 19:30:46 -07:00
J H
da55d6f7cd feat: Add in the chmod + chown to libs::js_engine (#2185)
* feat: Add in the chmod + chown to libs::js_engine

* fix: Build
2023-03-08 14:50:56 -07:00
Aiden McClelland
eeacdc1359 support path routing (#2188) 2023-03-08 14:50:27 -07:00
J H
ee1e92e1cb feat: No pemissions for the rsync (#2187)
* feat: No pemissions for the rsync

* chore: Fix the build for missing a property
2023-03-08 12:48:47 -07:00
Aiden McClelland
705802e584 gzip and brotli (#2186) 2023-03-08 12:48:21 -07:00
J H
b2e509f055 chore: Update version to 0.3.4" (#2184)
* chore: Update version to 0.3.4"

* chore: Update others to the latest code

* release notes

* registry not marketplace

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-03-08 10:58:03 -07:00
Lucy C
cca70764d4 update packages (#2183) 2023-03-08 09:08:23 -07:00
Aiden McClelland
3ac94710fb relocate usermod 2023-03-08 08:22:25 -07:00
Aiden McClelland
ca73a47785 Update pureos-iso.yaml 2023-03-08 07:55:45 -07:00
Aiden McClelland
1ef67fc8e9 fix typo and update hash 2023-03-08 00:00:48 -07:00
Aiden McClelland
8f3c2f4f3d bump version 2023-03-07 21:00:43 -07:00
Aiden McClelland
e42b98ec17 new debspawn version 2023-03-07 20:18:32 -07:00
Alex Inkin
efb318a979 feat: lazy loading node-jose (#2177) 2023-03-07 19:09:10 -07:00
Alex Inkin
3c0a82293c Night theme (#2137)
* feat: add themes

* fix: remove obvious issues with light theme

* chore: improve light theme a bit

* comment out theme swticher

* chore: make login dark

* add theme and widgets to seeds

* add theme and widgets to migration

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2023-03-07 19:09:10 -07:00
Matt Hill
e867f31c31 Next (#2170)
* feat: add widgets (#2034)

* feat: add Taiga UI library (#1992)

* feat: add widgets

* update patchdb

* right resizable sidebar with widgets

* feat: add resizing directive

* chore: remove unused code

* chore: remove unnecessary dep

* feat: `ResponsiveCol` add directive for responsive grid

* feat: add widgets edit mode and dialogs

* feat: add widgets model and modal

* chore: fix import

* chore: hide mobile widgets behind flag

* chore: add dummy widgets

* chore: start working on heath widget and implement other comments

* feat: health widget

* feat: add saving widgets and sidebar params to patch

* feat: preemptive UI update for widgets

* update health widget with more accurate states and styling (#2127)

* feat: `ResponsiveCol` add directive for responsive grid

* chore: some changes after merge

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* fix(shared): `ElasticContainer` fix collapsing margin (#2150)

* fix(shared): `ElasticContainer` fix collapsing margin

* fix toolbar height so titles not chopped

---------

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* feat: make widgets sidebar width togglable (#2146)

* feat: make widgets sidebar width togglable

* feat: move widgets under header

* chore: fix wide layout

* fix(shared): `ResponsiveCol` fix missing grid steps (#2153)

* fix widget flag and refactor for non-persistence

* default widget flag to false

* fix(shared): fix responsive column size (#2159)

* fix(shared): fix responsive column size

* fix: add responsiveness to all pages

* fix responsiveness on more pages

* fix: comments

* revert some padding changes

---------

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* chore: add analyzer (#2165)

* fix list styling to previous default (#2173)

* fix list styling to previous default

* dont need important flag

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2023-03-07 19:09:10 -07:00
kn0wmad
aeb6da111b Minor README Update (#2158) 2023-03-07 19:09:10 -07:00
J H
2736fa5202 feat: Add in the read dir. (#2141)
* feat: Add in the read dir.

Have a test that proves that this is working.

* chore: Let the read dir work while in a read only mode

* revert: To old sync
2023-03-07 19:09:10 -07:00
Matt Hill
4d3df867da Better Updates Tab and updates count (#2151)
* wip

* should be working now

* delete unused function

* delete 2 more unused functions

* update fixture to include beta registry

* address comments

* wait for connection to get local packages
2023-03-07 19:09:10 -07:00
Matt Hill
62f78e4312 invert conditional (#2138) 2023-03-07 19:09:10 -07:00
Matt Hill
d223ac4675 Config refactor (#2128)
* prevent excessive nesting for unions, closes #2107, and genrally refactor config

* a littel cleaner

* working but with inefficiencies

* remove warning from union list

* introduce messaging for config with only pointers

* feat(shared): `ElasticContainer` add new component (#2134)

* feat(shared): `ElasticContainer` add new component

* chore: fix imports

* revert to 250 for resize

* remove logs

Co-authored-by: Alex Inkin <alexander@inkin.ru>
2023-03-07 19:09:10 -07:00
Matt Hill
c16404bb2d dont hard code alpha and beta, use substring detection instead (#2135) 2023-03-07 19:09:10 -07:00
Matt Hill
cf70933e21 Only show alpha and beta in updates with dev tools enabled (#2132)
only show alpha and beta in updates with dev tools
2023-03-07 19:09:10 -07:00
Matt Hill
46222e9352 Feat/marketplace show links (#2105)
* closes #2084, rearranges marketplace show, app show, and donation link for Start9

* use url query param if present when fetching license and instructions

* remove log

* chore: Add some checking

* chore: Update something about validation

* chore: Update to use correct default

Co-authored-by: BluJ <mogulslayer@gmail.com>
2023-03-07 19:09:10 -07:00
J M
212e94756b fix: Zero op new dir dies. (#2122) 2023-03-07 19:09:10 -07:00
gStart9
b42abbd4a2 Always invoke fdisk with sudo fdisk in build/raspberry-pi/make-image.sh (#2123)
Always invoke fdisk with sudo fdisk
2023-03-07 19:09:10 -07:00
Matt Hill
730a55e721 re-add community marketplace and handle missing dependency (#2110)
* re-add community marketplace and handle missing dependency

* feat: Add in the community to migration

* chore: Add in the community marketplace_url update

* change var name to hidden

* chore: Add in the down

Co-authored-by: BluJ <mogulslayer@gmail.com>
2023-03-07 19:09:10 -07:00
Matt Hill
06cf83b901 WIP: IP, pubkey, system time, system uptime, ca fingerprint (#2091)
* closes #923, #2063, #2012, #1153

* add ca fingerprint

* add `server.time`

* add `ip-info` to `server-info`

* add ssh pubkey

* support multiple IPs

* rename key

* add `ca-fingerprint` and `system-start-time`

* fix off-by-one

* update compat cargo lock

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-03-07 19:09:10 -07:00
J M
673e5af030 Feat/logging local (#2103)
* wip: Working on sockets, but can't connect?

* simplify unix socket connection

* wip: Get responses back from the server at least once.

* WIP: Get the sockets working'

* feat: Sockets can start/ stop/ config/ properites/ uninstall

* fix: Restart services

* Fix: Sockets work and can stop main and not kill client

* chore: Add logging to service

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-03-07 19:09:10 -07:00
Aiden McClelland
a0bc16c255 risk mitigation (#2115)
* don't lock db on shutdown

* reorder init
2023-03-07 19:09:10 -07:00
Matt Hill
76b5234f7b alphabetize backup select and recovery select (#2113) 2023-03-07 19:09:10 -07:00
J M
928de47d1d Feat/long running sockets (#2090)
* wip: Working on sockets, but can't connect?

* simplify unix socket connection

* wip: Get responses back from the server at least once.

* WIP: Get the sockets working'

* feat: Sockets can start/ stop/ config/ properites/ uninstall

* fix: Restart services

* Fix: Sockets work and can stop main and not kill client

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-03-07 19:09:10 -07:00
Aiden McClelland
274db6f606 use a vec instead of set for ip (#2112) 2023-03-07 19:08:59 -07:00
Aiden McClelland
89ca0ca927 fix docker storage driver (#2111) 2023-01-12 09:56:54 -07:00
Matt Hill
8047008fa5 Add system rebuild and disk repair to Diagnostic UI (#2093)
* add system rebuild and disk repair to diagnostic

* add `diagnostic.rebuild`

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2023-01-10 15:02:16 -07:00
Matt Hill
f914110626 Feat/logs revamp (#2075)
auto reconnect to logs websocket and hopefully fix scrolling issues
2023-01-10 14:55:11 -07:00
Matt Hill
5656fd0b96 fix config bug for number 0 and also maybe conenction icon (#2098)
* fix config bug for number 0 and also maybe conenction icon

* add max password length to confimation input
2023-01-10 14:53:57 -07:00
Aiden McClelland
c3d8c72302 remove tor health daemon (#2101) 2023-01-10 14:34:48 -07:00
J M
1eefff9025 fix: Manager's exit not stopping (#2104) 2023-01-09 16:33:17 -07:00
Aiden McClelland
1dc7c7b0a4 only do standby mode for pi (#2102) 2023-01-09 16:21:30 -07:00
Aiden McClelland
011bac7b4f pin nextest to 0.9.47 (#2099) 2023-01-06 17:24:29 -07:00
Aiden McClelland
dc2d6e60d8 double bep instead of circle of 5ths (#2085) 2022-12-23 11:55:44 -07:00
Aiden McClelland
7809b6e50f delete logs from other machine ids (#2086) 2022-12-23 11:55:33 -07:00
Matt Hill
f7f0370bf5 add nyx (#2064) 2022-12-19 13:42:31 -07:00
Matt Hill
6300fc5364 UI multiple bug fixes (#2072)
* fixes #2071 #2068

* closes #2070

* closes #2046

* fixes #2074

* closes #2045

* closes #2077. Use LAN address instead of IP when opening https
2022-12-19 13:42:05 -07:00
Lucy C
16270cbd1a fix typo for os arch default type (#2079) 2022-12-19 13:41:14 -07:00
Aiden McClelland
3b226dd2c0 fix 0.3.3 OTA update flow for pi (#2048)
* feat: Conver from the copy all bytes over to file-file transer

* use pi-beep

* fix minor mistakes

* recursive rm

* add fs resize

Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-12-15 13:50:21 -07:00
Mariusz Kogen
4ac61d18ff 📊 include htop (#2042) 2022-12-15 12:04:11 -07:00
Matt Hill
fd7abdb8a4 don't be so fragile when comparing marketplace URLs (#2040)
* don't be so fragile when comparing marketplace URLs

* handle more edges

* minor

* clean up a little
2022-12-15 12:00:01 -07:00
Lucy C
92cd85b204 fix error and display of unknown font weight on success page (#2038) 2022-12-06 16:00:02 -07:00
J M
4bb7998208 fix: Make the restores limited # restore at a time (#2037)
* hack: Make the restores single restore at a time

* chore: Fix the build

* chore: Convert to using concurrent

* fix: Don't spawn for the tasks
2022-12-06 15:36:36 -07:00
J M
91b22311af fix: Ensure that during migration we make the urls have a trailing slash (#2036)
This is to fix a bug in the UI
2022-12-06 13:27:10 -07:00
Matt Hill
ddd00d4c25 remove write lock during backup (#2033)
* remove write lock during backup

* remove whole line
2022-12-05 22:49:04 -07:00
Matt Hill
428997f26a take one from server info to prevent multiple reqs to registries (#2032) 2022-12-05 22:48:56 -07:00
Matt Hill
c9d35d8096 take(1) for recover select (#2030)
take for recover select
2022-12-05 19:16:04 -07:00
Lucy C
761b3bd591 make procfs an optional dependency so sdk can build on macos (#2028)
* make procfs an optional dependency so sdk can build on macos

* flag dependency as linux only

* remove optional procfs dep

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-12-05 18:54:17 -07:00
Aiden McClelland
a440e6f115 initialize embassy before restoring packages (#2029) 2022-12-05 18:22:59 -07:00
Lucy C
837b1a9a73 update link rename from embassy -> system (#2027) 2022-12-05 11:34:12 -07:00
J M
bed37184d1 fix: Cifs not working because rw (#2025) 2022-12-04 15:23:10 -07:00
J M
785ed480bb fix: Undoing the breaking introduced by trying to stopp (#2023)
* fix: Undoing the breaking introduced by trying to stopp

* add check for exists
2022-12-03 17:50:25 -07:00
Mariusz Kogen
d8c39c42a1 🛡️ links update (#2018) 2022-12-03 12:29:33 -07:00
J M
4b06138d35 fix: Stop service before (#2019) 2022-12-03 12:17:46 -07:00
Lucy C
bd5668d15d UI fixes (#2014)
* fix html displaying in marketplace banner description

* always bold install risk copy

* display correct pkg in marketplace when diff registry, copy changes

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2022-12-02 23:20:01 -07:00
Chris Guida
1d6c61cc5b wait for monitor to be attached before launching firefox (#2005)
* wait for monitor to be attached before launching firefox

* add code to kill firefox on monitor disconnect

* fix detection for the pi

* Remove Pi only logic

* chore: Remove the kiosk mode

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-12-01 16:41:08 -07:00
Matt Hill
ed22e53cb6 make downloaded page a full html doc (#2011)
* make downloaded page a full html doc

* revert testing
2022-12-01 14:28:14 -07:00
Matt Hill
d18a34785c dont add updates cat (#2009) 2022-12-01 10:02:30 -07:00
Matt Hill
79fb8de7b7 lowercase service for alphabetic sorting (#2008) 2022-12-01 08:13:54 -07:00
Aiden McClelland
07f5f3f1bb fix partition type (#2007) 2022-12-01 08:04:43 -07:00
Matt Hill
8fffa40502 fix bug with showing embassy drives and center error text (#2006)
* fix bug with showing embassy drives and center error text

* cleaner

* even more cleaner
2022-12-01 08:04:21 -07:00
Aiden McClelland
6680b32579 fix regex in image rip script (#2002)
* fix regex in image rip script

* gitignore debian dir

* instructions

* put titles in code spans
2022-11-30 16:12:07 -07:00
Matt Hill
af618f42bd user must click continue in kiosk on success page (#2001)
* user must click continue in kiosk on success page

* hide source disk when target list for transfer and shpw indeterminate bar when 100%

* minor copy

* also check for guid on disk

* reuse va
2022-11-30 14:42:30 -07:00
Aiden McClelland
aafcce871e do not start progress at 0 before diff complete (#1999)
* do not start progress at 0 before diff complete

* fix: Test rsync

* don't report progress of 0

* drop initialization value from progress stream

Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-11-29 19:13:32 -07:00
Aiden McClelland
71d1418559 use squashfs for rpi updates (#1998) 2022-11-29 19:12:47 -07:00
Matt Hill
e0678cc869 preload icons and pause on setup complete for kiosk mode (#1997)
* preload two icons

* pause on setup complete for 4 seconds before redirecting kiosk mode
2022-11-29 18:59:17 -07:00
Aiden McClelland
74ddf7114c bump cargo version (#1995) 2022-11-29 11:54:08 -07:00
Aiden McClelland
837d4c1597 better migration progress bar (#1993)
* better migration progress bar

* show different messages based on setup type and fix modal height

* type safety

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 11:45:46 -07:00
Matt Hill
ccb85737f7 fix marketplace search and better category disabling (#1991)
* fix marketplace search and better category disabling

* bump marketplace version

* fix issue with marketplace settings and absent community reg
2022-11-29 09:43:54 -07:00
Aiden McClelland
f9a4699e84 check environment (#1990)
* check environment

* fix tests

* don't rebuild sources

* I'm going insane

* WTF

* Update check-environment.sh

* Update product.yaml

* Update write-image.sh
2022-11-29 09:43:54 -07:00
Matt Hill
bab3aea8ff bump shared and marketplace lib versions 2022-11-29 09:43:54 -07:00
Matt Hill
c52cf1fc3f remove community registry from FE defaults (#1988)
* remove community registry from FE defaults

* fix: Changes requested from matt (#1989)

* fix: Changes requested from matt

* chore: Remove more of the migration for the community

Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
3fe43a5b57 include OS_ARCH in raspi make install 2022-11-29 09:43:54 -07:00
Aiden McClelland
1a8b6d2fe7 just mess with the timestamps 2022-11-29 09:43:54 -07:00
Aiden McClelland
570a4b7915 extract meta-files from frontend.tar 2022-11-29 09:43:54 -07:00
Aiden McClelland
63859b81ad run dev builds in ci 2022-11-29 09:43:54 -07:00
Aiden McClelland
d8d13f8bf6 do not error if cannot determine live usb device (#1986) 2022-11-29 09:43:54 -07:00
Aiden McClelland
c3ce44e202 force docker image removal (#1985) 2022-11-29 09:43:54 -07:00
Lucy C
3372cdc0df Update/marketplace info (#1983)
* ensure arch is calways present in config

* add eos version to params when fetching marketplace info

* fix build script

* choose arch based on make goals

* conditionally send different arch param to registry

* better type for qp

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-11-29 09:43:54 -07:00
Aiden McClelland
82fc945d73 switch patch-db to master 2022-11-29 09:43:54 -07:00
Matt Hill
040bd52705 revert app show to use header and fix back button (#1984) 2022-11-29 09:43:54 -07:00
Aiden McClelland
415cfcb72f fix websocket hangup error (#1981) 2022-11-29 09:43:54 -07:00
Aiden McClelland
2b0efb32c1 fuckit: no patch db locks (#1969)
* fuck it: no patchdb locks

* fix: Add the locking to the package during the backup. (#1979)

* fix: Add the locking to the package during the backup.

* fix: Lock for the uninstall of the package

* switch patch-db to next

Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
a3a4fdd7fc restore interfaces before creating manager (#1982) 2022-11-29 09:43:54 -07:00
Aiden McClelland
78f6bbf7fe remove dbg 2022-11-29 09:43:54 -07:00
Aiden McClelland
43606d26e4 fix http upgrades (#1980)
* fix http upgrades

* use addr as authority directly

* move code to fn in net_utils

Co-authored-by: Stephen Chavez <stephen.chavez12@gmail.com>
2022-11-29 09:43:54 -07:00
Matt Hill
b77c409257 fix styling for http app shopw 2022-11-29 09:43:54 -07:00
Aiden McClelland
96f77a6275 filter out usb stick during install (#1974)
* filter out usb stick during install

* remove duplicate error kind

* clean out newline
2022-11-29 09:43:54 -07:00
Matt Hill
2336e36314 Multiple bugs and styling (#1975)
* remove updates from marketplace, fix search, link updates to marketplace, styling

* add dependency checks and error handling to updates tab

* add circle around back buttons
2022-11-29 09:43:54 -07:00
Lucy C
9146c31abf get pubkey and encrypt password on login (#1965)
* get pubkey and encrypt password on login

* only encrypt password if insecure context

* fix logic

* fix secure context conditional

* get-pubkey to auth api

* save two lines

* feat: Add the backend to the ui (#1968)

* hide app show if insecure and update copy for LAN

* show install progress when insecure and prevent backup and restore

* ask remove USB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
J M
bd4c431eb4 chore: Make validation reject containers (#1970)
* chore: Make validation reject containers

* chore: Add flag for removing in non js_engine
2022-11-29 09:43:54 -07:00
Aiden McClelland
b620e5319a add VERSION.txt 2022-11-29 09:43:54 -07:00
J M
f12df8ded4 Fix/migrate (#1962)
* fix: Locale issue from importing from pi

* fix: Need to mount the migrate correctly

* fix: Build.

* chore: remove version hack
2022-11-29 09:43:54 -07:00
Aiden McClelland
0ecd920ad9 feature: 0.3.2 -> 0.3.3 upgrade (#1958)
* 0.3.2 -> 0.3.3 upgrade script

* fix upgrade

* integrated image

* fix rip-image

* no U option on older rsync

* permissions and cleanup

* fixes

* label fs

* fix progress reporting

* only create rootfs for lite upgrade

* shrink image after creating

* fix for `blue` partitions
2022-11-29 09:43:54 -07:00
Stephen Chavez
b40be8c494 Embassy-init typo (#1959)
* fixes a typo.

* fixing build error

* undo tokio change

* undo change

* undo change

* undo disk.rs

* fixes a typo.

* undo disk.rs

* test
2022-11-29 09:43:54 -07:00
Lucy C
f7c5e64fbc Update/misc UI fixes (#1961)
* fix login error message spacing and ensure not longer than 64 chars

* spinner color to tertiary

* totally responsive homepage cards

* copy changes, back button for marketplace, minor styling

* center setup wizard tiles; adjust external link style

* remove cert note from setup success

* convert launch card to go to login button

* change system settings to system; update icons

* refactor card widget input as full card details; more card resizing for home page

* cleanup

* clean up widget params

* delete contructor

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Matt Hill
6eea2526f6 fix accessing dev tools (#1966) 2022-11-29 09:43:54 -07:00
J M
be9db47276 Fix millis (#1960) 2022-11-29 09:43:54 -07:00
Lucy C
35cb81518c Feature/homepage (#1956)
* add  new card widget for empty services page

* add homepage

* fix icons

* copy and arrangement changes

* minor changes

* edit login page

* rcreate widget list component

* cchange change detection strategy

* show header in home, welcome in list (#1957)

* show hear in home but not in list

* adjust padding

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Lucy C
4042b8f026 Update setup wizard styling (#1954)
* base srevampof home page

* update sembassy page

* update all  ephemeral pages

* matrix animation working

* wip success

* refactor styling  of success page

* modal and mobile adjustments

* cleanup

* make chnages to styles and copy (#1955)

* make chnages to styles and copy

* fix responsiveness of downloadable page

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>

* refactor success page

* cleanup headers

* revert isKiosk testing

* udpate patch DB

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
J M
a3d1b2d671 fix: Cleanup by sending a command and kill when dropped (#1945)
* fix: Cleanup by sending a command and kill when dropped

* chore: Fix the loadModule run command

* fix: cleans up failed health

* refactor long-running

* chore: Fixes?"

* refactor

* run iso ci on pr

* fix debuild

* fix tests

* switch to libc kill

* kill process by parent

* fix graceful shutdown

* recurse submodules

* fix compat build

* feat: Add back in the timeout

* chore: add the missing types for the unnstable

* inherited logs

Co-authored-by: J M <Blu-J@users.noreply.github.com>

* fix deleted code

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: J M <Blu-J@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Matt Hill
eec8c41e20 Hard code registry icons (#1951)
* component for store icons

* order registries and abstract registry urls

* use helper functionm
2022-11-29 09:43:54 -07:00
Mariusz Kogen
4f9fe7245b Create mountpoints first (#1949) 2022-11-29 09:43:54 -07:00
Aiden McClelland
6e1ae69691 disable telemetry reporting 2022-11-29 09:43:54 -07:00
Aiden McClelland
65a1fcfda5 remove kexec 2022-11-29 09:43:54 -07:00
Stephen Chavez
373e11495d changing ip addr type (#1950)
* changing ip addr type

* fixing parse fn and improving proxy fn

* Update net_controller.rs

* remove extra fn call
2022-11-29 09:43:54 -07:00
Aiden McClelland
8b6eac3c1c create dpkg and iso workflows (#1941)
* create dpkg workflow

* run workflow on this branch for now

* fix formatting

* install dependencies

* add debhelper

* fix upload

* add iso build

* fix syntax error

* docker buildx

* cache key

* pureos specific dependencies

* Update pureos-iso.yaml

* Update pureos-iso.yaml

* allow downgrades

* enable kvm

* no fakemachine

* disable kvm

* use pureos debspawn

* apt update still

* sudo

* with init

* use debspawn 0.6.0

* fix download link
2022-11-29 09:43:54 -07:00
Matt Hill
43bae7fb01 Fix/app show hidden (#1948)
* fix bug with blank app show and dont double update from patchDB
2022-11-29 09:43:54 -07:00
Matt Hill
18ee1e2685 Feat/update progress (#1944)
* uodate FE to show progress once calculated

* update mocks

* only show progress when known

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-11-29 09:43:54 -07:00
J M
5b91b5f436 feat: For ota update using rsyncd (#1938)
* feat: For ota update using rsyncd

* chore: Fix where we rsync to.

* chore: Getting rsync to work

* chore: Add in the is raspberry pi

* chore: Update is raspberry pi
2022-11-29 09:43:54 -07:00
Matt Hill
54749dfd1e bump marketplace and shared libs 2022-11-29 09:43:54 -07:00
Matt Hill
f86212dfe1 bump marketplace lib to 034 2022-11-29 09:43:54 -07:00
Alex Inkin
9ed2e2b0ca feat(shared): Ticker add new component and use it in marketplace (#1940) 2022-11-29 09:43:54 -07:00
Aiden McClelland
a29cd622c3 refactor setup wizard (#1937)
* refactor setup backend

* rework setup wizard according to new scheme

* fix bug with partitions in SW and warning message in IW

* treat localhost as LAN for launching services

* misc backend fixes

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Stephen Chavez
6cea0139d1 add localhost support to the http server (#1939) 2022-11-29 09:43:54 -07:00
Matt Hill
45a6a930c9 Add guid to partition type (#1932)
* add guid to partitions and implement pipe in shared to return guid for any disk

* fix bug and clean up
2022-11-29 09:43:54 -07:00
Aiden McClelland
22b273b145 fix migration to support portable fatties (#1935)
* load docker images directly from s9pk to ensure fatties can be loaded across platform

* don't migrate tmpdir

* init after package data transfer

* set default rsync options
2022-11-29 09:43:54 -07:00
Aiden McClelland
ca71c88744 wait for url to be available before launching kiosk (#1933) 2022-11-29 09:43:54 -07:00
Stephen Chavez
20b93e9fba Tor daemon fix (#1934)
* tor restart fix poc

* code cleanup

* Update backend/src/net/tor.rs

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* add info statement

* Update backend/src/net/tor.rs

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
05b29a7e9a disable efi (#1931) 2022-11-29 09:43:54 -07:00
Aiden McClelland
913ef5c817 silence service crash notifications (#1929) 2022-11-29 09:43:54 -07:00
Aiden McClelland
60534597e0 wait for network online before launching init (#1930) 2022-11-29 09:43:54 -07:00
Aiden McClelland
a7173b6bc9 fix build 2022-11-29 09:43:54 -07:00
Aiden McClelland
6deb51428a fix error handling when store unreachable (#1925)
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
2f00a642be bump shared and marketplace npm versions (#1924)
* bump shared and marketplace npm versions

* bump marketplace npm version

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
4e47960440 Feature/install wizard disk info (#1923)
* update disk res for install wizard (#1914)

* change types to match setup api

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
J M
67b54ac1eb feat: Exposing the rsync that we have to the js (#1907)
chore: Make the commit do by checksum.

chore: Remove the logging at the start

chore: use the defaults of the original.

chore: Convert the error into just the source.

chore: Remove some of the unwraps
2022-11-29 09:43:54 -07:00
Aiden McClelland
0e82b6981f Bugfix/0.3.3 migration (#1922)
* feat: Change migration to use empty name

* chore: Add in the default routes just in case

* Fix/remove merge with seed during init (#1917)

* fix kiosk

* chore: Remove the duplicate loggging information that is making usele… (#1912)

chore: Remove the duplicate loggging information that is making useless noise in the system.

* fix: Remove the init merge with seed

Co-authored-by: Aiden McClelland <me@drbonez.dev>

Co-authored-by: BluJ <mogulslayer@gmail.com>
Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
d6bf52c11f feature/marketplace icons (#1921)
* add registry icons, update links, clean up code (#1913)

* add registry icons, update links, clean up code

* remove seeding of registry icon and name

* fix install wizard copy

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* remove references to bep and chime

* fix shutdown language and remove chime from initializing screen

* fix type error

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
c1ac66f6e5 closes #1900 (#1920)
* closes #1900

* fix refresh bug

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
b9e4a66fdc Feature/git hash (#1919)
* display git hash in marketplace show and app show. Add additional info to app show

* bump marketplace lib version

* disbaled links if site not provided, fix bug with license-instructions

* fix import

* stupid

* feat: Add in the packing side git hash

* chore: Remove the test that is breaking the build.

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-11-29 09:43:54 -07:00
Matt Hill
9c363be16f set custom meta title (#1915) 2022-11-29 09:43:54 -07:00
Alex Inkin
affab384cf fix(marketplace): loosen type in categories component (#1918) 2022-11-29 09:43:54 -07:00
Stephen Chavez
0fc546962e Http proxy (#1772)
* adding skeleton for new http_proxy.

* more stuff yay

* more stuff yay

* more stuff

* more stuff

* "working" poc

* more stuff

* more stuff

* fix mored stuff

* working proxy

* moved to handler style for requests

* clean up

* cleaning stuff up

* more stuff

* refactoring code

* more changes

* refactoring handle

* refactored code

* more stuff

* Co-authored-by: J M <Blu-J@users.noreply.github.com>

* Co-authored-by: J M <Blu-J@users.noreply.github.com>

* more stuff

* more stuff

* working main ui handle

* Implement old code to handler in static server

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patch DB

* workring http server

* Feat/community marketplace (#1790)

* add community marketplace

* Update embassy-mock-api.service.ts

* expect ui/marketplace to be undefined

* possible undefined from getpackage

* fix marketplace pages

* rework marketplace infrastructure

* fix bugs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* remove unwrap

* cleanup code

* d

* more stuff

* fix: make `shared` module independent of `config.js` (#1870)

* cert stuff WIP

* MORE CERT STUFF

* more stuff

* more stuff

* more stuff

* abstract service fn

* almost ssl

* fix ssl export

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patch DB

* Feat/community marketplace (#1790)

* add community marketplace

* Update embassy-mock-api.service.ts

* expect ui/marketplace to be undefined

* possible undefined from getpackage

* fix marketplace pages

* rework marketplace infrastructure

* fix bugs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* fix: make `shared` module independent of `config.js` (#1870)

* fix: small fix for marketplace header styles (#1873)

* feat: setup publishing of share and marketplace packages (#1874)

* inlcude marketplace in linter

* fix npm publish scrips and bump versions of libs

* feat: add assets to published packages and fix peerDeps versions (#1875)

* bump peer dep

* fix: add assets to published paths (#1876)

* allow ca download over lan (#1877)

* only desaturate when logged in and not fully

* Feature/multi platform (#1866)

* wip

* wip

* wip

* wip

* wip

* wip

* remove debian dir

* lazy env and git hash

* remove env and git hash on clean

* don't leave project dir

* use docker for native builds

* start9 rust

* correctly mount registry

* remove systemd config

* switch to /usr/bin

* disable sound for now

* wip

* change disk list

* multi-arch images

* multi-arch system images

* default aarch64

* edition 2021

* dynamic wifi interface name

* use wifi interface from config

* bugfixes

* add beep based sound

* wip

* wip

* wip

* separate out raspberry pi specific files

* fixes

* use new initramfs always

* switch journald conf to sed script

* fixes

* fix permissions

* talking about kernel modules not scripts

* fix

* fix

* switch to MBR

* install to /usr/lib

* fixes

* fixes

* fixes

* fixes

* add media config to cfg path

* fixes

* fixes

* fixes

* raspi image fixes

* fix test

* fix workflow

* sync boot partition

* gahhhhh

* more stuff

* remove restore warning and better messaging for backup/restore (#1881)

* Update READMEs (#1885)

* docs

* fix host key generation

* debugging eos with tokio console

* fix recursive default

* build improvements (#1886)

* build improvements

* no workdir

* kiosk fully working

* setup profile prefs

* Feat/js long running (#1879)

* wip: combining the streams

* chore: Testing locally

* chore: Fix some lint

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* wip: making the mananger create

* wip: Working on trying to make the long running docker container command

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* feat: Use the long running feature in the manager

* remove recovered services and drop reordering feature (#1829)

* wip: Need to get the initial docker command running?

* chore: Add in the new procedure for the docker.

* feat: Get the system to finally run long

* wip: Added the command inserter to the docker persistance

* wip: Added the command inserter to the docker persistance

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patchDB

* feat: Move the run_command into the js

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patch DB

* chore: Change the error catching for the long running to try all

* Feat/community marketplace (#1790)

* add community marketplace

* Update embassy-mock-api.service.ts

* expect ui/marketplace to be undefined

* possible undefined from getpackage

* fix marketplace pages

* rework marketplace infrastructure

* fix bugs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* WIP: Fix the build, needed to move around creation of exec

* wip: Working on solving why there is a missing end.

* fix: make `shared` module independent of `config.js` (#1870)

* feat: Add in the kill and timeout

* feat: Get the run to actually work.

* chore: Add when/ why/ where comments

* feat: Convert inject main to use exec main.

* Fix: Ability to stop services

* wip: long running js main

* feat: Kill for the main

* Fix

* fix: Fix the build for x86

* wip: Working on changes

* wip: Working on trying to kill js

* fix: Testing for slow

* feat: Test that the new manifest works

* chore: Try and fix build?

* chore: Fix? the build

* chore: Fix the long input dies and never restarts

* build improvements

* no workdir

* fix: Architecture for long running

* chore: Fix and remove the docker inject

* chore: Undo the changes to the kiosk mode

* fix: Remove the it from the prod build

* fix: Start issue

* fix: The compat build

* chore: Add in the conditional compilation again for the missing impl

* chore: Change to aux

* chore: Remove the aux for now

* chore: Add some documentation to docker container

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>

* use old resolv.conf until systemd is on

* update patchdb

* update patch db submodule

* no x11 wrapper config

* working poc

* fixing misc stuff

* switch patchdb to next

* Feat/update tab (#1865)

* implement updates tab for viewing all updates from all marketplaces in one place

* remove auto-check-updates

* feat: implement updates page (#1888)

* feat: implement updates page

* chore: comments

* better styling in update tab

* rework marketplace service (#1891)

* rework marketplace service

* remove unneeded ?

* fix: refactor marketplace to cache requests

Co-authored-by: waterplea <alexander@inkin.ru>

Co-authored-by: Alex Inkin <alexander@inkin.ru>

* misc fixes (#1894)

* changing hostname stuff

* changes

* move marketplace settings into marketplace tab (#1895)

* move marketplace settings into marketplace tab

* Update frontend/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* bump marketplace version

* removing oldd code

* working service proxy

* fqdn struct wwip

* new types for ssl proxy

* restructure restore.rs and embassyd.rs

* adding dbg

* debugging proxy handlers

* add lots of debugging for the svc handler removal bug

* debugging

* remove extra code

* fixing proxy and removing old debug code

* finalizing proxy code to serve the setup ui and diag ui

* final new eos http proxy

* remove uneeded trace error

* remove extra file

* not needed flags

* clean up

* Fix/debug (#1909)

chore: Use debug by default"

* chore: Fix on the rsync not having stdout. (#1911)

* install wizard project (#1893)

* install wizard project

* reboot endpoint

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* update build

* fix build

* backend portion

* increase image size

* loaded

* dont auto resize

* fix install wizard

* use localhost if still in setup mode

* fix compat

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>

* fix kiosk

* integrate install wizard

* fix build typo

* no nginx

* fix build

* remove nginx stuff from build

* fixes

Co-authored-by: Stephen Chavez <stephen@start9labs.com>
Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
2022-11-29 09:43:54 -07:00
J M
d215d96b9b chore: Remove the duplicate loggging information that is making usele… (#1912)
chore: Remove the duplicate loggging information that is making useless noise in the system.
2022-11-29 09:43:54 -07:00
Aiden McClelland
327e873ef6 fix kiosk 2022-11-29 09:43:54 -07:00
Matt Hill
a2f65de1ce install wizard project (#1893)
* install wizard project

* reboot endpoint

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* Update frontend/projects/install-wizard/src/app/pages/home/home.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* update build

* fix build

* backend portion

* increase image size

* loaded

* dont auto resize

* fix install wizard

* use localhost if still in setup mode

* fix compat

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-11-29 09:43:54 -07:00
J M
bc23129759 chore: Fix on the rsync not having stdout. (#1911) 2022-11-29 09:43:54 -07:00
J M
3e7b184ab4 Fix/debug (#1909)
chore: Use debug by default"
2022-11-29 09:43:54 -07:00
Aiden McClelland
fe0b0d1157 add systemd-timesyncd as dependency 2022-11-29 09:43:54 -07:00
J M
55b1c021ec wip: Making Injectable exec (#1897)
* wip: Making Injectable exec

* chore: Cleanup dup code.

* chore: Fixes for consistancy.

* Fix: BUild and the join handle in the join_main
2022-11-29 09:43:54 -07:00
Aiden McClelland
21cf4cd2ce make js cancellable (#1901) 2022-11-29 09:43:54 -07:00
J M
defc98ab0e Feat/patch migration (#1890)
* feat: Most of the ui conversions and removing the package-recovered

* chore: Include the down process.

* feat: Add in the potential community packages.

* chore: Add in the services

* Make it so we skip rebuil.

* update version to 033 in FE

* chore: Revert to next version for patch-db

* fix: Build and check

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Lucy C
74af03408f Feature/setup migrate (#1841)
* add migrate component

* finish out migrate page and adjust recover options

* fix typo

* rename migrate -> transfer, adjust copy and typos, update transfer component logic

* add alert for old drive data when transferring

* comments for clarity

* auto adjust swiper slide height

* cleanup uneeded imports from transfer module

* pr feedback suggestions

* remove 02x from setup wiz

* clean up copy/styling for recover flow

* add support for migrating from old drive

* add RecoverySource lifted type

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-11-29 09:43:54 -07:00
Matt Hill
1d151d8fa6 bump marketplace version 2022-11-29 09:43:54 -07:00
Matt Hill
e5aeced045 move marketplace settings into marketplace tab (#1895)
* move marketplace settings into marketplace tab

* Update frontend/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Aiden McClelland
17d39143ac misc fixes (#1894) 2022-11-29 09:43:54 -07:00
Matt Hill
26c37ba824 Feat/update tab (#1865)
* implement updates tab for viewing all updates from all marketplaces in one place

* remove auto-check-updates

* feat: implement updates page (#1888)

* feat: implement updates page

* chore: comments

* better styling in update tab

* rework marketplace service (#1891)

* rework marketplace service

* remove unneeded ?

* fix: refactor marketplace to cache requests

Co-authored-by: waterplea <alexander@inkin.ru>

Co-authored-by: Alex Inkin <alexander@inkin.ru>
2022-11-29 09:43:54 -07:00
Matt Hill
d380cc31fa switch patchdb to next 2022-11-29 09:43:54 -07:00
Aiden McClelland
aa2fedee9d no x11 wrapper config 2022-11-29 09:43:54 -07:00
Matt Hill
14fa0e478a update patch db submodule 2022-11-29 09:43:54 -07:00
Matt Hill
ac878d46a5 update patchdb 2022-11-29 09:43:54 -07:00
Aiden McClelland
6da0a473be use old resolv.conf until systemd is on 2022-11-29 09:43:54 -07:00
J M
2642ec85e5 Feat/js long running (#1879)
* wip: combining the streams

* chore: Testing locally

* chore: Fix some lint

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* wip: making the mananger create

* wip: Working on trying to make the long running docker container command

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* feat: Use the long running feature in the manager

* remove recovered services and drop reordering feature (#1829)

* wip: Need to get the initial docker command running?

* chore: Add in the new procedure for the docker.

* feat: Get the system to finally run long

* wip: Added the command inserter to the docker persistance

* wip: Added the command inserter to the docker persistance

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patchDB

* feat: Move the run_command into the js

* Feat/long running (#1676)

* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* remove recovered services and drop reordering feature (#1829)

* chore: Convert the migration to use receipt. (#1842)

* feat: remove ionic storage (#1839)

* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>

* update patch DB

* chore: Change the error catching for the long running to try all

* Feat/community marketplace (#1790)

* add community marketplace

* Update embassy-mock-api.service.ts

* expect ui/marketplace to be undefined

* possible undefined from getpackage

* fix marketplace pages

* rework marketplace infrastructure

* fix bugs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

* WIP: Fix the build, needed to move around creation of exec

* wip: Working on solving why there is a missing end.

* fix: make `shared` module independent of `config.js` (#1870)

* feat: Add in the kill and timeout

* feat: Get the run to actually work.

* chore: Add when/ why/ where comments

* feat: Convert inject main to use exec main.

* Fix: Ability to stop services

* wip: long running js main

* feat: Kill for the main

* Fix

* fix: Fix the build for x86

* wip: Working on changes

* wip: Working on trying to kill js

* fix: Testing for slow

* feat: Test that the new manifest works

* chore: Try and fix build?

* chore: Fix? the build

* chore: Fix the long input dies and never restarts

* build improvements

* no workdir

* fix: Architecture for long running

* chore: Fix and remove the docker inject

* chore: Undo the changes to the kiosk mode

* fix: Remove the it from the prod build

* fix: Start issue

* fix: The compat build

* chore: Add in the conditional compilation again for the missing impl

* chore: Change to aux

* chore: Remove the aux for now

* chore: Add some documentation to docker container

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
2022-11-29 09:43:54 -07:00
Aiden McClelland
26d2152a36 build improvements (#1886)
* build improvements

* no workdir

* kiosk fully working

* setup profile prefs
2022-11-29 09:43:54 -07:00
Aiden McClelland
1cfd404321 Update READMEs (#1885)
* docs

* fix host key generation
2022-11-29 09:43:54 -07:00
Matt Hill
207020b7a0 remove restore warning and better messaging for backup/restore (#1881) 2022-11-29 09:43:54 -07:00
Aiden McClelland
6ad9a5952e Feature/multi platform (#1866)
* wip

* wip

* wip

* wip

* wip

* wip

* remove debian dir

* lazy env and git hash

* remove env and git hash on clean

* don't leave project dir

* use docker for native builds

* start9 rust

* correctly mount registry

* remove systemd config

* switch to /usr/bin

* disable sound for now

* wip

* change disk list

* multi-arch images

* multi-arch system images

* default aarch64

* edition 2021

* dynamic wifi interface name

* use wifi interface from config

* bugfixes

* add beep based sound

* wip

* wip

* wip

* separate out raspberry pi specific files

* fixes

* use new initramfs always

* switch journald conf to sed script

* fixes

* fix permissions

* talking about kernel modules not scripts

* fix

* fix

* switch to MBR

* install to /usr/lib

* fixes

* fixes

* fixes

* fixes

* add media config to cfg path

* fixes

* fixes

* fixes

* raspi image fixes

* fix test

* fix workflow

* sync boot partition

* gahhhhh
2022-11-29 09:43:54 -07:00
Matt Hill
0511680fc5 only desaturate when logged in and not fully 2022-11-29 09:43:54 -07:00
Matt Hill
ad14503e9f allow ca download over lan (#1877) 2022-11-29 09:43:54 -07:00
Alex Inkin
9221f25e35 fix: add assets to published paths (#1876) 2022-11-29 09:43:54 -07:00
Matt Hill
95eec90a62 bump peer dep 2022-11-29 09:43:54 -07:00
Alex Inkin
927cb51b5d feat: add assets to published packages and fix peerDeps versions (#1875) 2022-11-29 09:43:54 -07:00
Matt Hill
9f4025fdfb fix npm publish scrips and bump versions of libs 2022-11-29 09:43:54 -07:00
Matt Hill
b57336f6cf inlcude marketplace in linter 2022-11-29 09:43:54 -07:00
Alex Inkin
6e1c2fd7fd feat: setup publishing of share and marketplace packages (#1874) 2022-11-29 09:43:54 -07:00
Alex Inkin
50e3b7cd5a fix: small fix for marketplace header styles (#1873) 2022-11-29 09:43:54 -07:00
Alex Inkin
8beda5b0ae fix: make shared module independent of config.js (#1870) 2022-11-29 09:43:54 -07:00
Matt Hill
9998ed177b Feat/community marketplace (#1790)
* add community marketplace

* Update embassy-mock-api.service.ts

* expect ui/marketplace to be undefined

* possible undefined from getpackage

* fix marketplace pages

* rework marketplace infrastructure

* fix bugs

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Matt Hill
e2db3d84d8 update patch DB 2022-11-29 09:43:54 -07:00
Alex Inkin
141a390105 feat: remove ionic storage (#1839)
* feat: remove ionic storage

* grayscal when disconncted, rename local storage service for clarity

* remove storage from package lock

* update patchDB

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-11-29 09:43:54 -07:00
J M
78ad5d5879 chore: Convert the migration to use receipt. (#1842) 2022-11-29 09:43:54 -07:00
Matt Hill
2ddd38796d remove recovered services and drop reordering feature (#1829) 2022-11-29 09:43:54 -07:00
J M
35b220d7a5 Feat/long running (#1676)
* feat: Start the long running container

* feat: Long running docker, running, stoping, and uninstalling

* feat: Just make the folders that we would like to mount.

* fix: Uninstall not working

* chore: remove some logging

* feat: Smarter cleanup

* feat: Wait for start

* wip: Need to kill

* chore: Remove the bad tracing

* feat: Stopping the long running processes without killing the long
running

* Mino Feat: Change the Manifest To have a new type (#1736)

* Add build-essential to README.md (#1716)

Update README.md

* write image to sparse-aware archive format (#1709)

* fix: Add modification to the max_user_watches (#1695)

* fix: Add modification to the max_user_watches

* chore: Move to initialization

* [Feat] follow logs (#1714)

* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>

* Update README.md (#1728)

* fix build for patch-db client for consistency (#1722)

* fix cli install (#1720)

* highlight instructions if not viewed (#1731)

* wip:

* [ ] Fix the build (dependencies:634 map for option)

* fix: Cargo build

* fix: Long running wasn't starting

* fix: uninstall works

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>

* chore: Fix a dbg!

* chore: Make the commands of the docker-inject do inject instead of exec

* chore: Fix compile mistake

* chore: Change to use simpler

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2022-11-29 09:43:54 -07:00
Thomas Moerkerken
8093faee19 Update build pipeline (#1896)
* bump action versions to fix build warnings

* resolve warning on set-output

* Replace replace toolchain action with rustup cmd

* fix syntax

* run apt-get update before installing

* use apt-get
2022-10-31 14:30:58 -06:00
kn0wmad
10a7bd2eff Minor typo fixes (#1887)
Typo fix "loosing" -> "losing"
2022-10-24 16:51:29 -06:00
Aiden McClelland
2f8a25ae26 bump version (#1871) 2022-10-11 12:15:42 -06:00
Aiden McClelland
19bf80dfaf increase maximum avahi entry group size (#1869) 2022-10-10 16:50:33 -06:00
Lucy C
fbfaac9859 Update index.html copy and styling (#1855)
* Update index.html

Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
2022-10-06 14:35:43 -06:00
Aiden McClelland
0c3d0dd525 disable concurrency and delete tmpdir before retry (#1846)
* disable concurrency and delete tmpdir before retry

* undo retry

* really limit usage of pgloader

* configurable

* no migrate notifications
2022-10-04 15:14:15 -06:00
Mariusz Kogen
1388632562 📸 screenshots update (#1853)
* images update

* proper file rename
2022-10-04 09:36:01 -06:00
Matt Hill
771ecaf3e5 update patch db (#1852) 2022-10-03 12:17:12 -06:00
Mariusz Kogen
2000a8f3ed 💫 Rebranding to embassyOS (#1851)
* name change to embassyOS

* filename change

* motd ASCII update

* some leftovers
2022-10-03 12:13:48 -06:00
Matt Hill
719cd5512c show connection bar right away (#1849) 2022-10-03 09:59:49 -06:00
Aiden McClelland
afb4536247 retry pgloader up to 5x (#1845) 2022-09-29 13:45:28 -06:00
Aiden McClelland
71b19e6582 handle multiple image tags having the same hash and increase timeout (#1844) 2022-09-29 09:52:04 -06:00
Lucy C
f37cfda365 update ts matches to fix properties ordering bug (#1843) 2022-09-29 08:42:26 -06:00
Aiden McClelland
f63a841cb5 reduce patch-db log level to warn (#1840) 2022-09-28 10:12:00 -06:00
Aiden McClelland
d469e802ad update patch db and enable logging (#1837) 2022-09-27 15:36:42 -06:00
Lucy C
1702c07481 Seed patchdb UI data (#1835)
* adjust types
for patchdb ui data and create seed file

* feat: For init and the migration use defaults

* fix update path

* update build for ui seed file

* fix accidential revert

* chore: Convert to do during the init

* chore: Update the commit message

Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-09-26 17:36:37 -06:00
Aiden McClelland
31c5aebe90 play song during update (#1832)
* play song

* change song
2022-09-26 16:52:12 -06:00
Matt Hill
8cf84a6cf2 give name to logs file (#1833)
* give name to logs file
2022-09-26 15:40:38 -06:00
Aiden McClelland
18336e4d0a update patch-db (#1831) 2022-09-26 14:45:16 -06:00
Thomas Moerkerken
abf297d095 Bugfix/correctly package backend job (#1826)
* use makefile to create backend tar in pipeline

* correct for multiple architecture builds

* move duplication to shared workflow
2022-09-26 13:59:14 -06:00
Matt Hill
061a350cc6 Multiple (#1823)
* display preference for suto check and better messaging on properties page

* improve logs by a lot

* clean up

* fix searchbar and url in marketplace
2022-09-23 14:51:28 -06:00
Aiden McClelland
c85491cc71 ignore file not found error for delete (#1822) 2022-09-23 10:08:33 -06:00
Aiden McClelland
8b794c2299 perform system rebuild after updating (#1820)
* perform system rebuild after updating

* cleanup
2022-09-22 12:05:25 -06:00
Matt Hill
11b11375fd update license (#1819)
* update license

* update date
2022-09-22 12:03:44 -06:00
Aiden McClelland
c728f1a694 restructure initialization (#1816)
* reorder enabling of systemd-resolved

* set dns at end

* don't disable interfaces

* let networkmanager manage ifupdown

* restructure initialization

* use pigz when available

* cleanup

* fetch key before adding registry

* fix build

* update patch-db

* fix build

* fix build

* wait for network reinit

* add dynamic wait for up to 60s for network to reinit
2022-09-22 11:40:36 -06:00
Lucy C
28f9fa35e5 Fix/encryption (#1811)
* change encryption to use pubkey and only encrypt specific fields

* adjust script names for convenience

* remove unused fn

* fix build script name

* augment mocks

* remove log

* fix prod build

* feat: backend keys

* fix: Using the correct name with the public key

* chore: Fix the type for the encrypted

* chore: Add some tracing

* remove aes-js from package lock file

Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-09-21 14:03:05 -06:00
Lucy C
f8ea2ebf62 add descriptions to marketplace list page (#1812)
* add descriptions to marketplace list page

* clean up unused styling

* rip descriptions from registry marketplace, use binary choice custom default and alternative messages

* cleanup

* fix selected type and remove uneeded conditional

* conditional color

* cleanup

* better comparision of marketplace url duplicates

* add logic to handle marketplace description display based on url

* decrease font size

* abstract helper fn to get url hostname; add error toast when adding duplicate marketplace

* move helper function to more appropriate file location

* rework marketplace list and don't worry about patch db firing before bootstrapped

* remove aes-js

* reinstall aes just to please things for now

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-09-21 12:41:19 -06:00
Mariusz Kogen
7575e8c1de 🏦 Start as embassy hostname from the begining (#1814)
* 🏦 start as embassy hostname from the begining

By this, we are limiting the number of hostname changes (from 3 to 2) during the first initial Embassy startup.

* Hostname change no longer needed
2022-09-21 10:56:52 -06:00
Mariusz Kogen
395db5f1cf 🧅 replace instead of adding tor repository (#1813)
I also removed the src line because we won't use the tor source repository anytime soon if ever.
2022-09-21 10:56:01 -06:00
J M
ee1acda7aa fix: Minor fix that matt wanted (#1808)
* fix: Minor fix that matt wanted

* Update backend/src/hostname.rs
2022-09-19 13:05:38 -06:00
Matt Hill
1150f4c438 clean up code and logs (#1809)
abstract base64 functions and clean up console logs
2022-09-19 12:59:41 -06:00
Matt Hill
f04b90d9c6 fix mrketplace swtiching (#1810) 2022-09-19 12:59:29 -06:00
Lucy C
53463077df Bugfix/marketplace add (#1805)
* remove falsey check when getting marketplaces, as no alts could exist

* filter boolean but start with object

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-09-15 13:30:49 -06:00
Matt Hill
e326c5be4a better RPC error message (#1803) 2022-09-15 13:30:27 -06:00
Aiden McClelland
e199dbc37b prevent cfg str generation from running forever (#1804) 2022-09-15 13:29:46 -06:00
J M
2e8bfcc74d fix: Deep is_parent was wrong and could be escapped (#1801)
* fix: Deep is_parent was wrong and could be escapped

* Update lib.rs
2022-09-15 12:53:56 -06:00
Aiden McClelland
ca53793e32 stop leaking avahi clients (#1802)
* stop leaking avahi clients

* separate avahi to its own binary
2022-09-15 12:53:46 -06:00
Mariusz Kogen
a5f31fbf4e 🎚️ reclaiming that precious RAM memory (#1799)
* 🎚️ reclaiming that precious RAM memory

This adds 60MB of usable RAM

* 🎚️ reclaiming that precious RAM memory - sudo

* Update build/write-image.sh

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-09-14 11:24:43 -06:00
Matt Hill
40d47c9f44 fix duplicate patch updates, add scroll button to setup success (#1800)
* fix duplicate patch updates, add scroll button to setup success

* update path

* update patch

* update patch
2022-09-14 11:24:22 -06:00
J M
67743b37bb fix: Bad cert of *.local.local is now fixed to correct. (#1798) 2022-09-12 16:27:46 -06:00
Aiden McClelland
36911d7ed6 use base64 for HTTP headers (#1795)
* use base64 for HTTP headers

* fe for base64 headers

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-09-12 13:20:49 -06:00
Aiden McClelland
5564154da2 update backend dependencies (#1796)
* update backend dependencies

* update compat
2022-09-12 13:20:40 -06:00
Matt Hill
27f9869b38 fix search to return more accurate results (#1792) 2022-09-10 13:31:39 -06:00
Aiden McClelland
f274747af3 fix init to exit on failure (#1788) 2022-09-10 13:31:03 -06:00
Matt Hill
05832b8b4b expect ui marketplace to be undefined (#1787) 2022-09-09 12:24:30 -06:00
Aiden McClelland
b9ce2bf2dc 0.3.2 final cleanup (#1782)
* bump version with stubbed release notes

* increase BE timeout

* 032 release notes

* hide developer menu for now

* remove unused sub/import

* remoce reconnect from disks res in setup wiz

* remove quirks

* flatten drives response

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-09-08 16:14:42 -06:00
J M
5442459b2d fix: Js deep dir (#1784)
* fix: Js deep dir

* Delete broken.log

* Delete test.log

* fix: Remove  the == parent
2022-09-08 13:57:13 -06:00
Stephen Chavez
f0466aaa56 pinning cargo dep versions for CLI (#1775)
* pinning cargo dep versions for CLI

* add --locked to the workflow

Co-authored-by: Stephen Chavez <stephen@start9labs.com>
2022-09-07 09:25:14 -06:00
Matt Hill
50111e37da remove product key from setup flow (#1750)
* remove product key flow from setup

* feat: backend turned off encryption + new Id + no package id

* implement new encryption scheme in FE

* decode response string

* crypto not working

* update setup wizard closes #1762

* feat: Get the encryption key

* fix: Get to recovery

* remove old code

* fix build

* fix: Install works for now

* fix bug in config for adding new list items

* dismiss action modal on success

* clear button in config

* wip: Currently broken in avahi mdns

* include headers with req/res and refactor patchDB init and usage

* fix: Can now run in the main

* flatline on failed init

* update patch DB

* add last-wifi-region to data model even though not used by FE

* chore: Fix the start.

* wip: Fix wrong order for getting hostname before sql has been
created

* fix edge case where union keys displayed as new when not new

* fix: Can start

* last backup color, markdown links always new tab, fix bug with login

* refactor to remove WithRevision

* resolve circular dep issue

* update submodule

* fix patch-db

* update patchDB

* update patch again

* escape error

* decodeuricomponent

* increase proxy buffer size

* increase proxy buffer size

* fix nginx

Co-authored-by: BluJ <mogulslayer@gmail.com>
Co-authored-by: BluJ <dragondef@gmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-09-07 09:25:01 -06:00
Aiden McClelland
76682ebef0 switch to postgresql (#1763)
switch sqlx to postgresql
2022-09-01 10:32:01 -06:00
Matt Hill
705653465a use hostname from patchDB as default server name (#1758)
* replace offline toast with global indicator

* use hostname from patchDB as default server name

* add alert to marketplace delete and reword logout alert
2022-08-29 14:59:09 -06:00
Lucy C
8cd2fac9b9 Fix/empty properties (#1764)
* refactor properties utilities with updated ts-matches and allow for a null file

* update pacakges
2022-08-29 09:58:49 -06:00
Aiden McClelland
b2d7f4f606 [feat]: resumable downloads (#1746)
* optimize tests

* add test

* resumable downloads
2022-08-24 15:22:49 -06:00
Stephen Chavez
2dd31fa93f Disable bluetooth properly #862 (#1745)
add disable cmd for uart

Co-authored-by: Stephen Chavez <stephen@start9labs.com>
2022-08-22 14:16:11 -06:00
Thomas Moerkerken
df20d4f100 Set pipeline job timeouts and add ca-certificates to test container (#1753)
* set job timeout

* add ca-cert package to test container

* enable unittest

* include apt update

* set yes

* skip logs::test_logs unittest
2022-08-22 13:43:29 -06:00
Matt Hill
3ddeb5fa94 [Fix] websocket connecting and patchDB connection monitoring (#1738)
* refactor how we handle rpc responses and patchdb connection monitoring

* websockets only

* remove unused global error handlers

* chore: clear storage inside auth service

* feat: convert all global toasts to declarative approach (#1754)

* no more reference to serverID

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: waterplea <alexander@inkin.ru>
2022-08-22 10:53:52 -06:00
Thomas Moerkerken
70baed88f4 add x86 build and run unittests to backend pipeline (#1682)
* add build backend for x86_64

* remove unnecessary build steps

* install backend dependency

* build and run backend unittest

* fix cache key

* buildx is required, qemu is not.

* Add missing steps from Makefile

* fix build_command var is unused

* select more common test env

* update pipeline names and docs

* use variable for node version

* use correct artifact name

* update pipeline references

* skip unittest that needs ca-cert installed

* correct pipeline name

* use nextest pre-built binary; add term color

* fix cache permissions warning

* update documentation
2022-08-18 10:24:17 -06:00
Aiden McClelland
5ba0d594a2 Bugfix/dns (#1741)
* keep openresolv

* fix init
2022-08-18 10:23:04 -06:00
Stephen Chavez
6505c4054f Feat: HttpReader (#1733)
* The start of implementing http_reader, issue #1644

* structure done

* v1 of http_reader

* first http_header poc

* Add AsyncSeek trait

* remove import

* move import

* fix typo

* add error checking for async seek

* fix handling of positions

* rename variables

* Update backend/src/util/http_reader.rs

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* clean up work

* improve error handling, and change if statement.

Co-authored-by: Stephen Chavez <stephen@start9labs.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-08-18 10:22:51 -06:00
Matt Hill
e1c30a918b highlight instructions if not viewed (#1731) 2022-08-15 11:03:11 -06:00
Chris Guida
f812e208fa fix cli install (#1720) 2022-08-10 18:03:20 -05:00
Lucy C
9e7526c191 fix build for patch-db client for consistency (#1722) 2022-08-10 16:48:44 -06:00
Aiden McClelland
07194e52cd Update README.md (#1728) 2022-08-10 16:35:53 -06:00
Chris Guida
2f8d825970 [Feat] follow logs (#1714)
* tail logs

* add cli

* add FE

* abstract http to shared

* batch new logs

* file download for logs

* fix modal error when no config

Co-authored-by: Chris Guida <chrisguida@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
Co-authored-by: BluJ <mogulslayer@gmail.com>
2022-08-03 12:06:25 -06:00
J M
c44eb3a2c3 fix: Add modification to the max_user_watches (#1695)
* fix: Add modification to the max_user_watches

* chore: Move to initialization
2022-08-02 10:44:49 -06:00
Aiden McClelland
8207770369 write image to sparse-aware archive format (#1709) 2022-08-01 15:39:36 -06:00
Chris Guida
365952bbe9 Add build-essential to README.md (#1716)
Update README.md
2022-08-01 15:38:05 -06:00
Matt Hill
5404ebce1c observe response not events in http reqs to effectively use firstValueFrom 2022-07-29 17:43:23 -06:00
Matt Hill
13411f1830 closes #1710 2022-07-29 12:45:21 -06:00
Matt Hill
43090c9873 closes #1706 2022-07-29 12:45:21 -06:00
Matt Hill
34000fb9f0 closes #1711 2022-07-29 12:45:21 -06:00
Matt Hill
c2f9c6a38d display logs in local time while retaining iso format 2022-07-29 12:45:21 -06:00
Alex Inkin
a5c97d4c24 feat: migrate to Angular 14 and RxJS 7 (#1681)
* feat: migrate to Angular 14 and RxJS 7

* chore: update ng-qrcode

* chore: update patch-db

* chore: remove unnecessary generics
2022-07-27 21:31:46 -06:00
Aiden McClelland
9514b97ca0 Update README.md (#1703) 2022-07-27 18:10:52 -06:00
kn0wmad
22e84cc922 Update README.md (#1705)
* Update README.md

Updated release to 0.3.1

* use tag called latest

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-07-27 18:10:06 -06:00
Aiden McClelland
13b97296f5 formatting (#1698) 2022-07-27 18:00:48 -06:00
Aiden McClelland
d5f7e15dfb fix typo (#1702) 2022-07-26 17:32:37 -06:00
Aiden McClelland
7bf7b1e71e NO_KEY for CI images (#1700) 2022-07-26 17:32:28 -06:00
Matt Hill
7b17498722 set Matt as default assignee (#1697) 2022-07-26 15:12:31 -06:00
Aiden McClelland
3473633e43 sync blockdev after update (#1694) 2022-07-26 10:34:23 -06:00
Aiden McClelland
f455b8a007 ask for sudo password immediately during make (#1693) 2022-07-26 10:32:32 -06:00
Aiden McClelland
daabba12d3 honor shutdown from diagnostic ui (#1692) 2022-07-25 20:21:15 -06:00
Matt Hill
61864d082f messaging for restart, shutdown, rebuild (#1691)
* messaging for restart, shutdown, rebuild

* fix typo

* better messaging
2022-07-25 15:28:53 -06:00
Aiden McClelland
a7cd1e0ce6 sync data to fs before shutdown (#1690) 2022-07-25 15:23:40 -06:00
Matt Hill
0dd6d3a500 marketplace published at for service (#1689)
* at published timestamp to marketplace package show

* add todo
2022-07-25 12:47:50 -06:00
Aiden McClelland
bdb906bf26 add marketplace_url to backup metadata for service (#1688) 2022-07-25 12:43:40 -06:00
Aiden McClelland
61da050fe8 only validate mounts for inject if eos >=0.3.1.1 (#1686)
only validate mounts for inject if `>=0.3.1.1`
2022-07-25 12:20:24 -06:00
Matt Hill
83fe391796 replace bang with question mark in html (#1683) 2022-07-25 12:05:44 -06:00
Aiden McClelland
37657fa6ad issue notification when individual package restore fails (#1685) 2022-07-25 12:02:41 -06:00
Aiden McClelland
908a945b95 allow falsey rpc response (#1680)
* allow falsey rpc response

* better check for rpc error and remove extra function

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-07-25 10:16:04 -06:00
Aiden McClelland
36c720227f allow server.update to update to current version (#1679) 2022-07-22 14:10:09 -06:00
J M
c22c80d3b0 feat: atomic writing (#1673)
* feat: atomic writing

* Apply suggestions from code review

* clean up temp files on error

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-07-22 14:08:49 -06:00
Aiden McClelland
15af827cbc add standby mode (#1671)
* add standby mode

* fix standby mode to go before drive mount
2022-07-22 13:13:49 -06:00
Matt Hill
4a54c7ca87 draft releases notes for 0311 (#1677) 2022-07-22 11:17:18 -06:00
Alex Inkin
7b8a0eadf3 chore: enable strict mode (#1569)
* chore: enable strict mode

* refactor: remove sync data access from PatchDbService

* launchable even when no LAN url

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-07-22 09:51:08 -06:00
Aiden McClelland
9a01a0df8e refactor build process (#1675)
* add nc-broadcast to view initialization.sh logs

* include stderr

* refactor build

* add frontend/config.json as frontend dependency

* fix nc-broadcast

* always run all workflows

* address dependabot alerts

* fix build caching

* remove registries.json

* more efficient build
2022-07-21 15:18:44 -06:00
Aiden McClelland
ea2d77f536 lower log level for docker deser fallback message (#1672) 2022-07-21 12:13:46 -06:00
Aiden McClelland
e29003539b trust local ca (#1670) 2022-07-21 12:11:47 -06:00
Lucy C
97bdb2dd64 run build checks only when relevant FE changes (#1664) 2022-07-20 20:22:26 -06:00
Aiden McClelland
40d446ba32 fix migration, add logging (#1674)
* fix migration, add logging

* change stack overflow to runtime error
2022-07-20 16:00:25 -06:00
J M
5fa743755d feat: Make the rename effect (#1669)
* feat: Make the rename effect

* chore: Change to dst and src

* chore: update the remove file to use dst src
2022-07-20 13:42:54 -06:00
J M
0f027fefb8 chore: Update to have the new version 0.3.1.1 (#1668) 2022-07-19 10:03:14 -06:00
Matt Hill
56acb3f281 Mask chars beyond 16 (#1666)
fixes #1662
2022-07-18 18:31:53 -06:00
Lucy C
5268185604 add readme to system-images folder (#1665) 2022-07-18 15:48:42 -06:00
J M
635c3627c9 feat: Variable args (#1667)
* feat: Variable args

* chore: Make the assert error message not wrong
2022-07-18 15:46:32 -06:00
Chris Guida
009f7ddf84 sdk: don't allow mounts in inject actions (#1653) 2022-07-18 12:26:00 -06:00
J M
4526618c32 fix: Resolve fighting with NM (#1660) 2022-07-18 09:44:33 -06:00
Matt Hill
6dfd46197d handle case where selected union enum is invalid after migration (#1658)
* handle case where selected union enum is invalid after migration

* revert necessary ternary and fix types

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-07-17 13:42:36 -06:00
Aiden McClelland
778471d3cc Update product.yaml (#1638) 2022-07-13 11:15:45 -06:00
Aiden McClelland
bbcf2990f6 fix build (#1639) 2022-07-13 11:14:50 -06:00
Aiden McClelland
ac30ab223b return correct error on failed os download (#1636) 2022-07-12 12:48:18 -06:00
J M
50e7b479b5 Fix/receipts health (#1616)
* release lock on update progress (#1614)

* chore: remove the receipt

* chore: Remove the receipt

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-07-12 12:48:01 -06:00
Aiden McClelland
1367428499 update backend dependencies (#1637) 2022-07-12 12:18:12 -06:00
Mariusz Kogen
e5de91cbe5 🐋 docker stats fix (#1630)
* entry obsolete...

* 🐋 docker stats fix
2022-07-11 18:18:22 -06:00
J M
244260e34a chore: updating lock just from make clean; make (#1631) 2022-07-08 16:07:34 -06:00
Lucy C
575ed06225 fix display of comma between breakages (#1628) 2022-07-07 17:08:06 -06:00
Mariusz Kogen
b6fdc57888 Tor repository fix for arm64 (#1623)
When doing `sudo apt update` you get this:
`N: Skipping acquire of configured file 'main/binary-armhf/Packages' as repository 'https://deb.torproject.org/torproject.org bullseye InRelease' doesn't support architecture 'armhf'`
2022-07-07 15:34:54 -06:00
Aiden McClelland
758d7d89c2 keep status if package has no config (#1626) 2022-07-07 15:34:06 -06:00
Aiden McClelland
2db31b54e8 fix icons for sideloaded packages (#1624) 2022-07-07 15:33:53 -06:00
Thomas Moerkerken
99d16a37d5 Fix/adjust pipeline (#1619)
* use the correct frontend make target

* allow interactive tty if available

* fix syntax on pipeline trigger paths
2022-07-06 17:10:35 -06:00
Lucy C
449968bc4e Fix/misc UI (#1622)
* show available marketplace updates in menu

* complete feature

* delete unused class

* update tsmatches to remove console log

* fix merge conflict

* change config header font size

* fix new options emission for config elements

* delete unecessary import

* add custom modal for service marketplace conflict action

* cleanup

* remove unecessary imports

* pr cleanup of unused imports and classes

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-07-06 17:10:22 -06:00
Aiden McClelland
b0a55593c1 handle current-dependents properly during update (#1621) 2022-07-06 10:34:03 -06:00
Lucy C
17ef97c375 remove beta flag actions from UI config build (#1617)
* remove beta flag

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-07-05 13:49:53 -06:00
Thomas Moerkerken
36e0ba0f06 Add basic GitHub workflows builds (#1578)
* add easy target for backend build

* add reusable backend build workflow

* add reusable frontend build workflow

* add full build workflow

* add some comments
2022-07-05 13:46:06 -06:00
gStart9
b365a60c00 Default to https:// urls for repositories, remove apt-transport-https (#1610)
As of apt 1.5 (released 2017), the package apt-transport-https is no longer required because https:// is supported out of the box.
Reference: https://packages.debian.org/bullseye/apt-transport-https "This is a dummy transitional package - https support has been moved into the apt package in 1.5. It can be safely removed."  Apt is currently at 2.2.4.

Use a sed one-liner to convert all repos in /etc/apt/sources.list and /etc/apt/sources.list.d/*.list that are http:// to https:// (https:// is available for all http:// URLs currently referenced in EmbassyOS).
2022-07-05 13:45:10 -06:00
Lucy C
88afb756f5 show available marketplace updates in menu (#1613)
* show service updates in menu
2022-07-05 13:02:32 -06:00
Aiden McClelland
e2d58c2959 release lock on update progress (#1614) 2022-07-05 12:01:54 -06:00
Lucy C
3cfc333512 fix conditional display state (#1612)
* fix conditional display state

* fix footer

* fix empty case

* remove select all from backup restore

* fix styling and add warning message to service restore

* update copy
2022-07-04 15:06:23 -06:00
J M
89da50dd37 fix: Closed file (#1608) 2022-07-04 14:17:43 -06:00
Matt Hill
9319314672 display bottom item in backup list and refactor for cleanliness (#1609)
* display bottom item in backup list and refactor for cleanliness

* fix spelling mistake

* display initial toggle to deselect all, as all are selected by default

* add select/deselect all to backup restore and handle backup case when no services intalled

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-07-04 14:16:18 -06:00
Lucy C
6d805ae941 Fix/UI misc (#1606)
* stop expansion when description icon clicked

* add test for ensuring string sanitization

* rename log out to terminate in sessions component and remove sanitization bypass as unneeded

* remove unecessary instances of safe string
2022-07-01 18:25:45 -06:00
J M
8ba932aa36 feat: fetch effect (#1605)
* feat: fetch effect

* fix: Make not available in sandbox

* chore: Update to use text(), and to use headers

* chore: use the postman echo for testing

* chore: add json

* chore: Testing the json

* chore: Make the json lazy
2022-07-01 17:05:01 -06:00
Aiden McClelland
b580f549a6 actually purge old current-dependents 2022-07-01 16:06:01 -06:00
Lucy C
cb9c01d94b strip html from colors from logs (#1604) 2022-07-01 15:41:09 -06:00
Aiden McClelland
f9b0f6ae35 don't crash service if io-format is set for main (#1599) 2022-07-01 09:29:11 -06:00
Lucy C
1b1ff05c81 fix html parsing in logs (#1598) 2022-06-30 16:41:55 -06:00
Matt Hill
7b465ce10b nest new entries and message updates better (#1595)
* nest new entries and message updates better

* pass has new upward

* fix bulb display to make everyone happy
2022-06-30 15:32:54 -06:00
J M
ee66395dfe chore: commit the snapshots (#1592) 2022-06-30 12:39:51 -06:00
J M
31af6eeb76 fix: Stop the buffer from dropped pre-maturly (#1591) 2022-06-30 12:14:57 -06:00
Lucy C
e9a2d81bbe add select/deselect all to backups and enum lists (#1590) 2022-06-30 12:02:16 -06:00
Aiden McClelland
7d7f03da4f filter package ids when backing up (#1589) 2022-06-30 11:23:01 -06:00
Lucy C
8966b62ec7 update patchdb for array patch fix (#1588) 2022-06-29 17:51:20 -06:00
Aiden McClelland
ec8d9b0da8 switch to utc 2022-06-29 15:43:01 -06:00
Matt Hill
38ba1251ef turn chevron red in config if error (#1586) 2022-06-29 14:55:39 -06:00
Matt Hill
005c46cb06 preload redacted and visibility hidden (#1584)
* preload redacted and visibility hidden

* remove comment

* update patchdb

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-06-29 09:13:52 -06:00
Aiden McClelland
4b0ff07d70 Bugfix/backup lock order (#1583)
* different fix

* Revert "fix backup lock ordering (#1582)"

This reverts commit f1e065a448.
2022-06-29 09:03:10 -06:00
Aiden McClelland
f1e065a448 fix backup lock ordering (#1582) 2022-06-28 15:10:26 -06:00
J M
c82c6eaf34 fix: Properties had a null description (#1581)
* fix: Properties had a null description

* Update frontend/projects/ui/src/app/util/properties.util.ts
2022-06-28 13:57:51 -06:00
Matt Hill
b8f3759739 update welcome notes for 031 (#1580) 2022-06-28 13:41:05 -06:00
kn0wmad
70aba1605c Feat/use modern tor (#1575)
* Add guardian project repo and install latest stable tor

* Apt appendage
2022-06-28 12:28:08 -06:00
Matt Hill
2c5aa84fe7 selective backups and better drive selection interface (#1576)
* selective backups and better drive selection interface

* fix disabled checkbox and backup drives menu styling

* feat: package-ids

* only show services that are backing up on backup page

* refactor for performace and cleanliness

Co-authored-by: Matt Hill <matthill@Matt-M1.start9.dev>
Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
Co-authored-by: J M <mogulslayer@gmail.com>
2022-06-28 12:14:26 -06:00
Aiden McClelland
753f395b8d add avahi conditional compilation flags to dns (#1579) 2022-06-28 10:42:54 -06:00
Lucy C
f22f11eb58 Fix/sideload icon type (#1577)
* add content type to icon dataURL

* better handling of blob reading; remove verifying loader and reorganize html

* clean up PR feedback and create validation fn instead of boolean

* grpup upload state into one type

* better organize validation

* add server id to eos check for updates req

* fix patchdb to latest

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
2022-06-27 15:25:42 -06:00
Lucy C
123f71cb86 Fix/mask generic inputs (#1570)
* add masking to generic input component

* clear inputs after submission

* adjust convenience FE make steps

* cleaner masking

* remove mask pipe from module

* switch to redacted font
2022-06-27 13:51:35 -06:00
Aiden McClelland
22af45fb6e add dns server to embassy-os (#1572)
* add dns server to embassy-os

* fix initialization

* multiple ip addresses
2022-06-27 10:53:06 -06:00
Matt Hill
0849df524a fix connection failure display monitoring and other style changes (#1573)
* fix connection failure display monitoring and other style chnages

* display updates more clearly in marketplace

* remove scrolling from release notes and long description

* remove unnecessary bangs

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
Co-authored-by: Matt Hill <matthill@Matt-M1.start9.dev>
2022-06-27 10:44:12 -06:00
Lucy C
31952afe1e adjust service marketplace button for installation source relevance (#1571)
* adjust service marketplace button for installation source relevance

* cleanup

* show marketplace name instead of url; cleanup from PR feedback

* fix spacing

* further cleanup
2022-06-27 10:09:27 -06:00
Matt Hill
83755e93dc kill all sessions and remove ripple effect (#1567)
* button to kill all sessions, session sorting, remove ripple effect from buttons

* pr cleanup

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-06-23 16:59:13 -06:00
J M
0fbcc11f99 fix: Make it so we only need the password on the backup (#1566)
* fix: Make it so we only need the password on the backup

* chore: Remove the rewrite of password
2022-06-23 10:25:47 -06:00
Matt Hill
d431fac7de fix bugs with config and clean up dev options (#1558)
* fix bugs with config and clean up dev options

* dont down down arrow in logs prematurely

* change config error border to match error text red color

* change restart button color

* fix error when sideloading and update copy

* adds back in param cloning as this bug creeped up again

* make restarting text match button color

* fix version comparision for updates category

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-06-22 18:26:10 -06:00
Alex Inkin
53ca9b0420 refactor(patch-db): use PatchDB class declaratively (#1562)
* refactor(patch-db): use PatchDB class declaratively

* chore: remove initial source before init

* chore: show spinner

* fix: show Connecting to Embassy spinner until first connection

* fix: switching marketplaces

* allow for subscription to end with take when installing a package

* update patchdb

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-06-22 16:09:14 -06:00
BitcoinMechanic
a8749f574a fixed sentence that didn't make sense (#1565) 2022-06-22 09:57:10 -07:00
J M
a9d839fd8f fix: Missing a feature flat cfg (#1563) 2022-06-21 10:34:03 -06:00
J M
477d37f87d feat: Make sdk (#1564) 2022-06-21 10:25:54 -06:00
Matt Hill
d2195411a6 Reset password through setup wizard (#1490)
* closes FE portion of  #1470

* remove accidental commit of local script

* add reset password option (#1560)

* fix error code for incorrect password and clarify codes with comments

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-06-20 16:48:32 -06:00
J M
1f5e6dbff6 chore: Add tracing for debuging the js procedure slowness (#1552)
* chore: Add tracing for debuging the js procedure slowness

* chore: Make the display to reduce vertical clutter
2022-06-20 16:22:19 -06:00
Lucy C
09c0448186 update should send version not version spec (#1559) 2022-06-20 14:18:20 -06:00
Lucy C
b318bf64f4 fix backend builds for safe git config (#1549) 2022-06-19 14:25:39 -06:00
Lucy Cifferello
af1d2c1603 update welcome message 2022-06-19 13:46:09 -06:00
Lucy Cifferello
1c11d3d08f update patch db 2022-06-19 13:46:09 -06:00
Lucy C
a4a8f33df0 Feature/restart service (#1554)
* add restart button to service show page and restart rpc api

* Feature/restart rpc (#1555)

* add restart rpc and status

* wire up rpc

* add restarting bool

Co-authored-by: Aiden McClelland <me@drbonez.dev>

* check if service is restarting

* filter package when restarting to avoid glitch

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2022-06-19 13:46:09 -06:00
Lucy Cifferello
889cf03c1c fix circular images in instructions markdown modal 2022-06-19 13:46:09 -06:00
Matt Hill
0ac5b34f2d Remove app wiz and dry calls (#1541)
* no more app wiz or dry calls

* change spinner type

* better display for update available

* reintroduce dep breakages for update/downgrade and style alerts everywhere

* only show install alert on first install

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
Co-authored-by: Matt Hill <matthill@Matt-M1.start9.dev>
2022-06-19 13:46:09 -06:00
Lucy Cifferello
37304a9d92 chore: cleanup and small misc fixes
display success alert if on latest EOS after check for update

fix bug with loader dismiss after alert present

fix restart button on update complete alert and fix mocks to account for this state

fix make clean and adjust default registry names
2022-06-19 13:46:09 -06:00
Matt Hill
4ad9886517 refactor app wizards completely (#1537)
* refactor app wizards completely

* display new and new options in config

Co-authored-by: Matt Hill <matthill@Matt-M1.start9.dev>
2022-06-19 13:46:09 -06:00
Matt Hill
8e9d2b5314 chore: cleanup - show spinner on service list when transitioning
config add new list items to end and auto scroll

remove js engine artifacts

fix view button in notification toast
2022-06-19 13:46:09 -06:00
Lucy C
7916a2352f Feature/sideload (#1520)
* base styling and action placeholders for package sideload

* apparently didnt add new folder

* wip

* parse manifest and icon from s9pk to upload

* wip handle s9pk upload

* adjust types, finalize actions, cleanup

* clean up and fix data clearing and response

* include rest rpc in proxy conf sample

* address feedback to use shorthand falsy coercion

* update copy and invalid package file ux

* do not wait package upload, instead show install progress

* fix proxy for rest rpc

rename sideload package page titles
2022-06-19 13:46:09 -06:00
Matt Hill
2b92d0f119 Swtich certain inputs and displays to courier for readability (#1521)
swtich certain inputs and displays to courier for readability

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
2022-06-19 13:46:09 -06:00
Matt Hill
961a9342fa display QR code for interfaces (#1507)
* display QR code for interfaces

* add play-outline to preloader

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
2022-06-19 13:46:09 -06:00
Lucy C
3cde39c7ed Feature/copy logs (#1491)
* make text selectable on mobile

* make logs copyable and adjust copy format

* fix linting

* fix linting further

* linting

* add formatting to copied logs

* fix copy abstraction and add formatting for server log copy
2022-06-19 13:46:09 -06:00
Matt Hill
09922c8dfa Rework install progress types and pipes for clarity (#1513)
* rework install progress types and pipes for clarity

* rework marketplace show display

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
2022-06-19 13:46:09 -06:00
waterplea
0390954a85 feat: enable strictNullChecks
feat: enable `noImplicitAny`

chore: remove sync data access

fix loading package data for affected dependencies

chore: properly get alt marketplace data

update patchdb client to allow for emit on undefined values
2022-06-19 13:46:09 -06:00
J M
948fb795f2 feat: uid/gid/mode added to metadata (#1551) 2022-06-17 12:16:04 -06:00
J M
452c8ea2d9 Feat/js metadata (#1548)
* feat: metadata effect

* feat: Metadata for effects

* chore: Add in the new types
2022-06-16 15:58:48 -06:00
Aiden McClelland
9c41090a7a add textarea to ValueSpecString (#1534) 2022-06-16 13:14:18 -06:00
Aiden McClelland
59eee33767 fix dependency/dependent id issue (#1546) 2022-06-16 13:14:05 -06:00
Aiden McClelland
cc5e60ed90 fix incorrect error message for deserialization in ValueSpecString (#1547) 2022-06-16 13:13:50 -06:00
J M
27bc493884 Feat: Make the js check for health (#1543)
* Feat: Make the js check for health

* chore: Add in the migration types

* feat: type up the migration
2022-06-16 11:58:55 -06:00
J M
75a2b2d2ab chore: Update the lite types to include the union and enum (#1542) 2022-06-15 19:31:47 -06:00
J M
0b7d8b4db0 fix: found a unsaturaded args fix 2022-06-15 14:40:42 -06:00
J M
d05cd7de0d chore: Update types to match embassyd (#1539)
* chore: Update types to match embassyd

* chore: Undo the optional
2022-06-15 14:39:20 -06:00
Aiden McClelland
b0068a333b disable unnecessary services 2022-06-14 12:43:27 -06:00
Aiden McClelland
d947c2db13 fixes #1169 (#1533)
* fixes #1169

* consolidate trim

Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>

Co-authored-by: J M <2364004+Blu-J@users.noreply.github.com>
2022-06-14 11:47:04 -06:00
Aiden McClelland
90e09c8c25 add "error_for_status" to static file downloads 2022-06-14 11:42:31 -06:00
J M
dbf59a7853 fix: restart/ uninstall sometimes didn't work (#1527)
* fix: restart/ uninstall sometimes didn't work

* Fix: Match the original lock types
2022-06-13 14:18:41 -06:00
Aiden McClelland
4d89e3beba fixes a bug where nginx will crash if eos goes into diagnostic mode a… (#1506)
fixes a bug where nginx will crash if eos goes into diagnostic mode after service init has completed
2022-06-13 12:43:12 -06:00
J M
5a88f41718 Feat/js known errors (#1514)
* feat: known errors for js

* chore: add expected exports

* Update js_scripts.rs

* chore: Use agreed upon shape

* chore: add updates to d.ts

* feat: error case

* chore: Add expectedExports as a NameSpace`

* chore: add more documentation to the types.d.ts
2022-06-10 13:04:52 -06:00
Aiden McClelland
435956a272 fix "missing proxy" error in embassy-cli (#1516)
* fix "missing proxy" error in embassy-cli

* fix: Add test and other fix for SetResult

Co-authored-by: J M <mogulslayer@gmail.com>
2022-06-10 12:58:58 -06:00
Aiden McClelland
7854885465 allow interactive TTY if available 2022-06-08 09:29:24 -06:00
Keagan McClelland
901ea6203e fixes serialization of regex pattern + description 2022-06-07 17:32:47 -06:00
J M
9217d00528 Fix/memory leak docker (#1505)
* fix: potential fix for the docker leaking the errors and such

* chore: Make sure that the buffer during reading the output will not exceed 10mb ish

* Chore: Add testing

* fix: Docker buffer reading to lines now works

* chore: fixing the broken responses
2022-06-07 12:58:12 -06:00
J M
f234f894af fix: potential fix for the docker leaking the errors and such (#1496)
* fix: potential fix for the docker leaking the errors and such

* chore: Make sure that the buffer during reading the output will not exceed 10mb ish

* Chore: Add testing
2022-06-07 11:11:43 -06:00
Aiden McClelland
4286edd78f allow embassy-cli not as root (#1501)
* allow embassy-cli not as root
* clean up merge
2022-06-07 11:11:01 -06:00
Keagan McClelland
334437f677 generate unique ca names based off of server id 2022-06-06 18:56:27 -06:00
Keagan McClelland
183c5cda14 refactors error handling for less redundancy 2022-06-06 18:43:32 -06:00
Keagan McClelland
45265453cb control experiment for correct configs 2022-06-06 18:43:32 -06:00
Keagan McClelland
80a06272cc fixes regex black hole 2022-06-06 18:23:28 -06:00
J M
473213d14b chore: fix the master (#1495)
* chore: fix the master

* chore: commit all the things swc
2022-06-06 15:02:44 -06:00
Matt Hill
d53e295569 UI cosmetic improvements (#1486)
* resize alerts and modals

* fix log color

* closes #1404

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
2022-06-06 11:31:45 -06:00
Thomas Moerkerken
18e2c610bc add quotes to handles spaces in working dir 2022-06-06 10:10:51 -06:00
J M
e0c68c1911 Fix/patch db unwrap remove (#1481)
* fix: Change the git to always give a maybe, then create the error in the failure cases

* fix: No wifi last

* chore: Revert to older api

* fix: build for sdk

* fix: build for sdk

* chore: update patch db

* chore: use the master patch db
2022-06-06 09:52:19 -06:00
Mariusz Kogen
34729c4509 Enable Control Groups for Docker containers (#1468)
Enabling Control Groups give Docker containers the ability to track and expose missing memory metrics. Try `docker stats`
2022-06-06 08:32:33 -06:00
Matt Hill
ca778b327b Clean up config (#1484)
* better formatting for union list

* cleaner config

Co-authored-by: Matt Hill <matthill@Matt-M1.local>
2022-06-03 12:35:56 -06:00
Benjamin B
bde6169746 Update contribution and frontend readme (#1467)
* docs: small updates to contributing and frontend readme

* chore: change build:deps script to use npm ci
2022-06-03 12:26:45 -06:00
Lucy C
3dfbf2fffd UI version updates and welcome message for 0.3.1 (#1479) 2022-06-03 12:23:32 -06:00
Benjamin B
34068ef633 Link to tor address on LAN setup page (#1277) (#1466)
* style: format lan page component

* Link to tor address on LAN setup page (#1277)
2022-06-01 15:43:57 -06:00
Benjamin B
e11729013f Disable view in marketplace button when side-loaded (#1471)
Disble view in marketplace button when side-loaded
2022-06-01 15:20:45 -06:00
Thomas Moerkerken
cceef054ac remove interactive TTY requirement from cmds 2022-06-01 14:37:12 -06:00
J M
b8751e7add Chore/version 0 3 1 0 (#1475)
* feat: move over to workspaces

* chore: Move to libs

* chore:fix(build): Compat

* chore: fixing pr
2022-06-01 10:22:00 -06:00
Keagan McClelland
37344f99a7 cleanup after rebase 2022-05-27 13:20:33 -06:00
Keagan McClelland
61bcd8720d warn if script is present but manifest does not require one 2022-05-27 13:20:33 -06:00
Keagan McClelland
6801ff996e require script is present during pack step iff any pkg procs are type script 2022-05-27 13:20:33 -06:00
J M
c8fc9a98bf fix: Change the source + add input 2022-05-27 13:20:33 -06:00
J M
52de5426ad Feat: js action
wip: Getting async js

feat: Have execute get action config

feat: Read + Write

chore: Add typing for globals

chore: Change the default path, include error on missing function, and add json File Read Write

chore: Change the default path, include error on missing function, and add json File Read Write

wip: Fix the unit test

wip: Fix the unit test

feat: module loading
2022-05-27 13:20:33 -06:00
Benjamin B
e7d0a81bfe Fix links in CONTRIBUTING.md, update ToC 2022-05-27 11:45:57 -06:00
Alex Inkin
4f3223d3ad refactor: isolate network toast and login redirect to separate services (#1412)
* refactor: isolate network toast and login redirect to separate services

* chore: remove accidentally committed sketch of a service

* chore: tidying things up

* feat: add `GlobalModule` encapsulating all global subscription services

* remove angular build cache when building deps

* chore: fix more issues found while testing

* chore: fix issues reported by testing

* chore: fix template error

* chore: fix server-info

* chore: fix server-info

* fix: switch to Observable to fix race conditions

* fix embassy name display on load

* update patchdb

* clean up patch data watch

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-05-26 16:56:47 -06:00
J M
4829637b46 fix: Dependency vs dependents (#1462)
* fix: Dependency vs dependents

* chore: Remove the debugging
2022-05-26 15:39:46 -06:00
J M
7f2494a26b Fix/making js work (#1456)
* Feat: js action

wip: Getting async js

feat: Have execute get action config

feat: Read + Write

chore: Add typing for globals

chore: Change the default path, include error on missing function, and add json File Read Write

chore: Change the default path, include error on missing function, and add json File Read Write

wip: Fix the unit test

wip: Fix the unit test

feat: module loading

* fix: Change the source + add input

* fix: Change the source + add input

wip: Fix missing js files during running

fix: Change the source + add input

wip: Fix missing js files during running

* fix: other paths

* feat: Build the arm js snapshot

* fix: test with more

* chore: Make the is_subset a result
2022-05-25 12:19:40 -06:00
J M
f7b5fb55d7 Feat/js action (#1437)
* Feat: js action

wip: Getting async js

feat: Have execute get action config

feat: Read + Write

chore: Add typing for globals

chore: Change the default path, include error on missing function, and add json File Read Write

chore: Change the default path, include error on missing function, and add json File Read Write

wip: Fix the unit test

wip: Fix the unit test

feat: module loading

* fix: Change the source + add input

* fix: single thread runtime

* fix: Smaller fixes

* Apply suggestions from code review

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>

* fix: pr

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-05-19 18:02:50 -06:00
Lucy C
2b6e54da1e Proxy local frontend to remote backend (#1452)
* add server proxy configurations

* change address to host due to compliation warning

* adjust config sample to more accurately reflect production version
2022-05-19 15:58:32 -06:00
Jonathan Zernik
1023916390 Add nginx config for proxy redirect (#1421)
* Add nginx config for proxy redirect protocol prefix

* Update proxy_redirect config to use scheme variable

* Only include proxy redirect directive when ssl is true
2022-05-19 14:56:53 -06:00
Keagan McClelland
6a0e9d5c0a refactor packer to async 2022-05-19 11:08:22 -06:00
Aiden McClelland
7b4d657a2d actually address warning instead of muting it like a sociopath 2022-05-16 16:46:59 -06:00
Keagan McClelland
b7e86bf556 cleanse warnings 2022-05-16 16:46:59 -06:00
Aiden McClelland
fa777bbd63 fix remaining rename 2022-05-16 16:23:46 -06:00
Aiden McClelland
2e7b2c15bc rename ActionImplementation to PackageProcedure 2022-05-16 16:23:46 -06:00
Keagan McClelland
9bc0fc8f05 formatting 2022-05-16 16:11:45 -06:00
Keagan McClelland
b354d30fe9 Update backend/src/s9pk/header.rs
Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
2022-05-16 16:11:45 -06:00
Keagan McClelland
a253e95b5a make scripts optional 2022-05-16 16:11:45 -06:00
Keagan McClelland
7e4c0d660a fix paths 2022-05-16 16:11:45 -06:00
Keagan McClelland
6a8bf2b074 s/open/create 2022-05-16 16:11:45 -06:00
Keagan McClelland
16729ebffc change script path 2022-05-16 16:11:45 -06:00
Keagan McClelland
f44d432b6a no tar for scripts 2022-05-16 16:11:45 -06:00
Keagan McClelland
93ee418f65 redundant imports 2022-05-16 16:11:45 -06:00
Keagan McClelland
cd6bda2113 optional script unpacking 2022-05-16 16:11:45 -06:00
Keagan McClelland
4a007cea78 cleanup assets and scripts on uninstall 2022-05-16 16:11:45 -06:00
Keagan McClelland
ab532b4432 fix script name 2022-05-16 16:11:45 -06:00
Keagan McClelland
ee98b91a29 remove scripts volume 2022-05-16 16:11:45 -06:00
Keagan McClelland
0294143b22 create script dirs on install 2022-05-16 16:11:45 -06:00
Keagan McClelland
2890798342 pack scripts into s9pk 2022-05-16 16:11:45 -06:00
Keagan McClelland
2d44852ec4 iterators can be played now 2022-05-16 11:24:14 -06:00
Keagan McClelland
b9de5755d1 fix error with circle of fifths type 2022-05-16 11:24:14 -06:00
Mariusz Kogen
84463673e2 ☯️ For the peace of mind ☯️ (#1444)
Simplifying and clarifying for first time builders
2022-05-16 11:09:11 -06:00
Dread
56efe9811d Update README.md to include yq (#1385)
Update README.md to include yq install instructions for Linux
2022-05-11 16:23:10 -06:00
Keagan McClelland
a6234e4507 adds product key to error message in setup flow when there is mismatch 2022-05-11 16:19:24 -06:00
Keagan McClelland
e41b2f6ca9 make nicer update sound 2022-05-11 16:15:56 -06:00
Lucy C
8cf000198f Fix/id params (#1414)
* watch config.json for changes when just building frontend

* fix version for data consistency

* clone param ids so not recursively stringified; add global type for stringified instances

* ensure only most recent data source grabbed to fix issue with service auto update on marketplace switch

* use take instead of shallow cloning data
2022-05-10 12:20:32 -06:00
J M
cc6cbbfb07 chore: Convert from ajv to ts-matches (#1415) 2022-05-10 11:00:56 -06:00
Mariusz Kogen
10d7a3d585 Switching SSH keys to start9 user (#1321)
* Update ssh.rs for start9 user

* .ssh directory for uid 1000 user

* Update init.rs for start9 user

* “His name is Robert Paulson”

* typo

* just cleaning up ...
2022-05-09 15:16:24 -06:00
J M
864555bcf0 Feat bulk locking (#1422)
* Feat: Multi-lock capabilities add to config

* wip: RPC.rs fixes, new combinatoric

* wip: changes

* chore: More things that are bulk

* fix: Saving

* chore: Remove a dyn object

* chore: Add tests + remove unused

* Fix/feat  bulk locking (#1427)

* fix: health check

* fix: start/stop service

* fix: install/uninstall services

* chore: Fix the notifications

* fix: Version

* fix: Version as serde

* chore: Update to latest patch db

* chore: Change the htLock to something that makes more sense

* chore: Fix the rest of the ht

* "chore: More ht_lock":
2022-05-09 14:53:39 -06:00
Mirko Rainer
5d3bc8cfa5 Update index.html (#1419)
* Update index.html

Increase proposed time to wait.

* Update index.html

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>

Co-authored-by: Lucy C <12953208+elvece@users.noreply.github.com>
2022-05-05 15:41:28 -06:00
dependabot[bot]
b130608a78 Bump async from 2.6.3 to 2.6.4 in /frontend (#1426)
* Bump async from 2.6.3 to 2.6.4 in /frontend

Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix eos version

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-05-04 16:51:25 -06:00
Chris Guida
6fa0a9762f Update server-show.page.ts
kernel logs are not just for device drivers
2022-05-04 18:38:05 -04:00
Aiden McClelland
17270e41fd version bump (#1423)
* version bump

* set `Current`

* update welcome message and adjust styling

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
2022-05-04 16:36:23 -06:00
Aiden McClelland
4ac03293ed attempt to heal when health check passes 2022-05-02 15:36:26 -04:00
Aiden McClelland
7c17e26480 prevent the kernel from OOMKilling embassyd (#1402)
* prevent the kernel from OOMKilling embassyd

* privilege embassyd with respect to cpu usage

* add a docker slice
2022-04-20 11:26:41 -04:00
Mariusz Kogen
1ac711c864 smarter wget
If for some reason make will be interrupted, wget will try to download .zip file and cause the name is taken it will download it to .zip1 which wont be recognized. This fixes it.
2022-04-15 15:26:00 -04:00
kn0wmad
82c2adbc7b Update Makefile (#1400)
Remove FE config file during a `make clean`
2022-04-15 10:57:25 -06:00
Lucy Cifferello
1dcf390ee9 make montserrat important to override, mainly for menu 2022-04-14 12:44:08 -04:00
waterplea
a143e2581e chore(snek): remove keyboard activation 2022-04-14 12:44:08 -04:00
waterplea
d7bdc15e49 refactor: decompose app component 2022-04-14 12:44:08 -04:00
Aiden McClelland
50f14fe040 fixes login locking up after refresh 2022-04-11 21:58:38 -04:00
Lucy Cifferello
0d96007c2f fix arch config for build 2022-04-11 16:10:03 -04:00
Lucy Cifferello
3eef671163 change welcome message 2022-04-11 16:09:25 -04:00
Aiden McClelland
2015770768 chore: bump version 2022-04-11 16:09:25 -04:00
Aiden McClelland
b686fc6794 commit compat after update 2022-04-11 15:10:18 -04:00
1936 changed files with 192742 additions and 86960 deletions

View File

@@ -1,36 +1,34 @@
name: 🐛 Bug Report
description: Create a report to help us improve EmbassyOS
title: '[bug]: '
description: Create a report to help us improve StartOS
title: "[bug]: "
labels: [Bug, Needs Triage]
assignees:
- dr-bonez
- MattDHill
body:
- type: checkboxes
attributes:
label: Prerequisites
description: Please confirm you have completed the following.
options:
- label: I have searched for [existing issues](https://github.com/start9labs/embassy-os/issues) that already report this problem, without success.
- label: I have searched for [existing issues](https://github.com/start9labs/start-os/issues) that already report this problem.
required: true
- type: input
attributes:
label: EmbassyOS Version
description: What version of EmbassyOS are you running?
placeholder: e.g. 0.3.0
label: Server Hardware
description: On what hardware are you running StartOS? Please be as detailed as possible!
placeholder: Pi (8GB) w/ 32GB microSD & Samsung T7 SSD
validations:
required: true
- type: input
attributes:
label: StartOS Version
description: What version of StartOS are you running?
placeholder: e.g. 0.3.4.3
validations:
required: true
- type: dropdown
attributes:
label: Device
description: What device are you using to connect to Embassy?
options:
- Phone/tablet
- Laptop/Desktop
validations:
required: true
- type: dropdown
attributes:
label: Device OS
label: Client OS
description: What operating system is your device running?
options:
- MacOS
@@ -45,14 +43,14 @@ body:
required: true
- type: input
attributes:
label: Device OS Version
label: Client OS Version
description: What version is your device OS?
validations:
required: true
- type: dropdown
attributes:
label: Browser
description: What browser are you using to connect to Embassy?
description: What browser are you using to connect to your server?
options:
- Firefox
- Brave

View File

@@ -1,16 +1,16 @@
name: 💡 Feature Request
description: Suggest an idea for EmbassyOS
title: '[feat]: '
description: Suggest an idea for StartOS
title: "[feat]: "
labels: [Enhancement]
assignees:
- dr-bonez
- MattDHill
body:
- type: checkboxes
attributes:
label: Prerequisites
description: Please confirm you have completed the following.
options:
- label: I have searched for [existing issues](https://github.com/start9labs/embassy-os/issues) that already suggest this feature, without success.
- label: I have searched for [existing issues](https://github.com/start9labs/start-os/issues) that already suggest this feature.
required: true
- type: textarea
attributes:
@@ -27,7 +27,7 @@ body:
- type: textarea
attributes:
label: Describe Preferred Solution
description: How you want this feature added to EmbassyOS?
description: How you want this feature added to StartOS?
- type: textarea
attributes:
label: Describe Alternatives

281
.github/workflows/startos-iso.yaml vendored Normal file
View File

@@ -0,0 +1,281 @@
name: Debian-based ISO and SquashFS
on:
workflow_call:
workflow_dispatch:
inputs:
environment:
type: choice
description: Environment
options:
- NONE
- dev
- unstable
- dev-unstable
runner:
type: choice
description: Runner
options:
- standard
- fast
platform:
type: choice
description: Platform
options:
- ALL
- x86_64
- x86_64-nonfree
- aarch64
- aarch64-nonfree
- raspberrypi
deploy:
type: choice
description: Deploy
options:
- NONE
- alpha
- beta
push:
branches:
- master
- next/*
pull_request:
branches:
- master
- next/*
env:
NODEJS_VERSION: "22.17.1"
ENVIRONMENT: '${{ fromJson(format(''["{0}", ""]'', github.event.inputs.environment || ''dev''))[github.event.inputs.environment == ''NONE''] }}'
jobs:
compile:
name: Compile Base Binaries
strategy:
fail-fast: true
matrix:
arch: >-
${{
fromJson('{
"x86_64": ["x86_64"],
"x86_64-nonfree": ["x86_64"],
"aarch64": ["aarch64"],
"aarch64-nonfree": ["aarch64"],
"raspberrypi": ["aarch64"],
"ALL": ["x86_64", "aarch64"]
}')[github.event.inputs.platform || 'ALL']
}}
runs-on: ${{ fromJson('["ubuntu-22.04", "buildjet-32vcpu-ubuntu-2204"]')[github.event.inputs.runner == 'fast'] }}
steps:
- run: |
sudo mount -t tmpfs tmpfs .
if: ${{ github.event.inputs.runner == 'fast' }}
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODEJS_VERSION }}
- name: Set up docker QEMU
uses: docker/setup-qemu-action@v3
- name: Set up system dependencies
run: sudo apt-get update && sudo apt-get install -y qemu-user-static systemd-container squashfuse
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure sccache
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_RESULTS_URL', process.env.ACTIONS_RESULTS_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Make
run: make ARCH=${{ matrix.arch }} compiled-${{ matrix.arch }}.tar
env:
SCCACHE_GHA_ENABLED: on
SCCACHE_GHA_VERSION: 0
- uses: actions/upload-artifact@v4
with:
name: compiled-${{ matrix.arch }}.tar
path: compiled-${{ matrix.arch }}.tar
image:
name: Build Image
needs: [compile]
strategy:
fail-fast: false
matrix:
platform: >-
${{
fromJson(
format(
'[
["{0}"],
["x86_64", "x86_64-nonfree", "aarch64", "aarch64-nonfree", "raspberrypi"]
]',
github.event.inputs.platform || 'ALL'
)
)[(github.event.inputs.platform || 'ALL') == 'ALL']
}}
runs-on: >-
${{
fromJson(
format(
'["ubuntu-22.04", "{0}"]',
fromJson('{
"x86_64": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204",
"aarch64": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64-nonfree": "buildjet-8vcpu-ubuntu-2204-arm",
"raspberrypi": "buildjet-8vcpu-ubuntu-2204-arm",
}')[matrix.platform]
)
)[github.event.inputs.runner == 'fast']
}}
env:
ARCH: >-
${{
fromJson('{
"x86_64": "x86_64",
"x86_64-nonfree": "x86_64",
"aarch64": "aarch64",
"aarch64-nonfree": "aarch64",
"raspberrypi": "aarch64",
}')[matrix.platform]
}}
steps:
- name: Free space
run: rm -rf /opt/hostedtoolcache*
if: ${{ github.event.inputs.runner != 'fast' }}
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static
wget https://deb.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.2-1_all.deb
sha256sum ./debspawn_0.6.2-1_all.deb | grep 37ef27458cb1e35e8bce4d4f639b06b4b3866fc0b9191ec6b9bd157afd06a817
sudo apt-get install -y ./debspawn_0.6.2-1_all.deb
- name: Configure debspawn
run: |
sudo mkdir -p /etc/debspawn/
echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml
sudo mkdir -p /var/tmp/debspawn
- run: sudo mount -t tmpfs tmpfs /var/tmp/debspawn
if: ${{ github.event.inputs.runner == 'fast' && (matrix.platform == 'x86_64' || matrix.platform == 'x86_64-nonfree') }}
- name: Download compiled artifacts
uses: actions/download-artifact@v4
with:
name: compiled-${{ env.ARCH }}.tar
- name: Extract compiled artifacts
run: tar -xvf compiled-${{ env.ARCH }}.tar
- name: Prevent rebuild of compiled artifacts
run: |
mkdir -p web/node_modules
mkdir -p web/dist/raw
mkdir -p core/startos/bindings
mkdir -p sdk/base/lib/osBindings
mkdir -p container-runtime/node_modules
mkdir -p container-runtime/dist
mkdir -p container-runtime/dist/node_modules
mkdir -p core/startos/bindings
mkdir -p sdk/dist
mkdir -p sdk/baseDist
mkdir -p patch-db/client/node_modules
mkdir -p patch-db/client/dist
mkdir -p web/.angular
mkdir -p web/dist/raw/ui
mkdir -p web/dist/raw/install-wizard
mkdir -p web/dist/raw/setup-wizard
mkdir -p web/dist/static/ui
mkdir -p web/dist/static/install-wizard
mkdir -p web/dist/static/setup-wizard
PLATFORM=${{ matrix.platform }} make -t compiled-${{ env.ARCH }}.tar
- run: git status
- name: Run iso build
run: PLATFORM=${{ matrix.platform }} make iso
if: ${{ matrix.platform != 'raspberrypi' }}
- name: Run img build
run: PLATFORM=${{ matrix.platform }} make img
if: ${{ matrix.platform == 'raspberrypi' }}
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.platform }}.squashfs
path: results/*.squashfs
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.platform }}.iso
path: results/*.iso
if: ${{ matrix.platform != 'raspberrypi' }}
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.platform }}.img
path: results/*.img
if: ${{ matrix.platform == 'raspberrypi' }}
- name: Upload OTA to registry
run: >-
PLATFORM=${{ matrix.platform }} make upload-ota TARGET="${{
fromJson('{
"alpha": "alpha-registry-x.start9.com",
"beta": "beta-registry.start9.com",
}')[github.event.inputs.deploy]
}}" KEY="${{
fromJson(
format('{{
"alpha": "{0}",
"beta": "{1}",
}}', secrets.ALPHA_INDEX_KEY, secrets.BETA_INDEX_KEY)
)[github.event.inputs.deploy]
}}"
if: ${{ github.event.inputs.deploy != '' && github.event.inputs.deploy != 'NONE' }}
index:
if: ${{ github.event.inputs.deploy != '' && github.event.inputs.deploy != 'NONE' }}
needs: [image]
runs-on: ubuntu-22.04
steps:
- run: >-
curl "https://${{
fromJson('{
"alpha": "alpha-registry-x.start9.com",
"beta": "beta-registry.start9.com",
}')[github.event.inputs.deploy]
}}:8443/resync.cgi?key=${{
fromJson(
format('{{
"alpha": "{0}",
"beta": "{1}",
}}', secrets.ALPHA_INDEX_KEY, secrets.BETA_INDEX_KEY)
)[github.event.inputs.deploy]
}}"

31
.github/workflows/test.yaml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Automated Tests
on:
push:
branches:
- master
- next/*
pull_request:
branches:
- master
- next/*
env:
NODEJS_VERSION: "22.17.1"
ENVIRONMENT: dev-unstable
jobs:
test:
name: Run Automated Tests
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODEJS_VERSION }}
- name: Build And Run Tests
run: make test

18
.gitignore vendored
View File

@@ -8,3 +8,21 @@
/product_key.txt
/*_product_key.txt
.vscode/settings.json
deploy_web.sh
deploy_web.sh
secrets.db
.vscode/
/cargo-deps/**/*
/PLATFORM.txt
/ENVIRONMENT.txt
/GIT_HASH.txt
/VERSION.txt
/*.deb
/target
/*.squashfs
/results
/dpkg-workdir
/compiled.tar
/compiled-*.tar
/firmware
/tmp

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "rpc-toolkit"]
path = rpc-toolkit
url = https://github.com/Start9Labs/rpc-toolkit.git
[submodule "patch-db"]
path = patch-db
url = https://github.com/Start9Labs/patch-db.git

View File

@@ -1,205 +1,133 @@
<!-- omit in toc -->
# Contributing to Embassy OS
# Contributing to StartOS
First off, thanks for taking the time to contribute! ❤️
This guide is for contributing to the StartOS. If you are interested in packaging a service for StartOS, visit the [service packaging guide](https://docs.start9.com/latest/packaging-guide/). If you are interested in promoting, providing technical support, creating tutorials, or helping in other ways, please visit the [Start9 website](https://start9.com/contribute).
All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
## Collaboration
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues
> - Buy an [Embassy](https://start9labs.com)
- [Matrix](https://matrix.to/#/#community-dev:matrix.start9labs.com)
- [Telegram](https://t.me/start9_labs/47471)
<!-- omit in toc -->
## Table of Contents
## Project Structure
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Setting Up Your Development Environment](#setting-up-your-development-environment)
- [Building The Image](#building-the-image)
- [Improving The Documentation](#improving-the-documentation)
- [Styleguides](#styleguides)
- [Formatting](#formatting)
- [Atomic Commits](#atomic-commits)
- [Commit Messages](#commit-messages)
- [Pull Requests](#pull-requests)
- [Rebasing Changes](#rebasing-changes)
- [Join The Discussion](#join-the-discussion)
- [Join The Project Team](#join-the-project-team)
## I Have a Question
> If you want to ask a question, we assume that you have read the available [Documentation](https://docs.start9labs.com).
Before you ask a question, it is best to search for existing [Issues](https://github.com/Start9Labs/embassy-os/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an [Issue](https://github.com/Start9Labs/embassy-os/issues/new).
- Provide as much context as you can about what you're running into.
- Provide project and platform versions, depending on what seems relevant.
We will then take care of the issue as soon as possible.
<!--
You might want to create a separate issue tag for questions and include it in this description. People should then tag their issues accordingly.
Depending on how large the project is, you may want to outsource the questioning, e.g. to Stack Overflow or Gitter. You may add additional contact and information possibilities:
- IRC
- Slack
- Gitter
- Stack Overflow tag
- Blog
- FAQ
- Roadmap
- E-Mail List
- Forum
-->
## I Want To Contribute
> ### Legal Notice <!-- omit in toc -->
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
### Reporting Bugs
<!-- omit in toc -->
#### Before Submitting a Bug Report
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://start9.com/latest/user-manual). If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/Start9Labs/embassy-os/issues?q=label%3Abug).
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- Client OS, Platform and Version (Windows/Linux/macOS/iOS/Android, Firefox/Tor Browser/Consulate)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Possibly your input and the output
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
<!-- omit in toc -->
#### How Do I Submit a Good Bug Report?
> You must never report security related issues, vulnerabilities or bugs to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <security@start9labs.com>.
<!-- You may add a PGP key to allow the messages to be sent encrypted as well. -->
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
- Open an [Issue](https://github.com/Start9Labs/embassy-os/issues/new/choose) selecting the appropriate type.
- Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section.
Once it's filed:
- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `Question`. Bugs with the `Question` tag will not be addressed until they are answered.
- If the team is able to reproduce the issue, it will be marked a scoping level tag, as well as possibly other tags (such as `Security`), and the issue will be left to be [implemented by someone](#your-first-code-contribution).
<!-- You might want to create an issue template for bugs and errors that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Suggesting Enhancements
This section guides you through submitting an enhancement suggestion for Embassy OS, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
<!-- omit in toc -->
#### Before Submitting an Enhancement
- Make sure that you are using the latest version.
- Read the [documentation](https://start9.com/latest/user-manual) carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/Start9Labs/embassy-os/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
<!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion?
Enhancement suggestions are tracked as [GitHub issues](https://github.com/Start9Labs/embassy-os/issues).
- Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. <!-- this should only be included if the project has a GUI -->
- **Explain why this enhancement would be useful** to most Embassy OS users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
<!-- You might want to create an issue template for enhancement suggestions that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Project Structure
EmbassyOS is composed of the following components. Please visit the README for each component to understand the dependency requirements and installation instructions.
- [`ui`](ui/README.md) (Typescript Ionic Angular) is the code that is deployed to the browser to provide the user interface for EmbassyOS.
- [`backend`] (backend/README.md) (Rust) is a command line utility, daemon, and software development kit that sets up and manages services and their environments, provides the interface for the ui, manages system state, and provides utilities for packaging services for EmbassyOS.
- `patch-db` - A diff based data store that is used to synchronize data between the front and backend.
- Notably, `patch-db` has a [client](patch-db/client/README.md) with its own dependency and installation requirements.
- `rpc-toolkit` - A library for generating an rpc server with cli bindings from Rust functions.
- `system-images` - (Docker, Rust) A suite of utility Docker images that are preloaded with EmbassyOS to assist with functions relating to services (eg. configuration, backups, health checks).
- [`setup-wizard`] (ui/README.md)- Code for the user interface that is displayed during the setup and recovery process for EmbassyOS.
- [`diagnostic-ui`] (diagnostic-ui/README.md) - Code for the user interface that is displayed when something has gone wrong with starting up EmbassyOS, which provides helpful debugging tools.
### Your First Code Contribution
#### Setting up your development environment
First, clone the EmbassyOS repository and from the project root, pull in the submodules for dependent libraries.
```
git clone https://github.com/Start9Labs/embassy-os.git
git submodule update --init --recursive
```bash
/
├── assets/
├── container-runtime/
├── core/
├── build/
├── debian/
├── web/
├── image-recipe/
├── patch-db
└── sdk/
```
Depending on which component of the ecosystem you are interested in contributing to, follow the installation requirements listed in that component's README (linked [above](#project-structure))
#### assets
#### Building The Image
This step is for setting up an environment in which to test your code changes if you do not yet have a EmbassyOS.
screenshots for the StartOS README
- Requirements
- `ext4fs` (available if running on the Linux kernel)
- [Docker](https://docs.docker.com/get-docker/)
- GNU Make
- Building
- see setup instructions [here](build/README.md)
- run `make` from the project root
#### container-runtime
### Improving The Documentation
You can find the repository for Start9's documentation [here](https://github.com/Start9Labs/documentation). If there is something you would like to see added, let us know, or create an issue yourself. Welcome are contributions for lacking or incorrect information, broken links, requested additions, or general style improvements.
A NodeJS program that dynamically loads maintainer scripts and communicates with the OS to manage packages
Contributions in the form of setup guides for integrations with external applications are highly encouraged. If you struggled through a process and would like to share your steps with others, check out the docs for each [service](https://github.com/Start9Labs/documentation/blob/master/source/user-manuals/available-services/index.rst) we support. The wrapper repos contain sections for adding integration guides, such as this [one](https://github.com/Start9Labs/bitcoind-wrapper/tree/master/docs). These not only help out others in the community, but inform how we can create a more seamless and intuitive experience.
#### core
## Styleguides
### Formatting
Each component of EmbassyOS contains its own style guide. Code must be formatted with the formatter designated for each component. These are outlined within each component folder's README.
An API, daemon (startd), and CLI (start-cli) that together provide the core functionality of StartOS.
### Atomic Commits
Commits [should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) and diffs should be easy to read.
Do not mix any formatting fixes or code moves with actual code changes.
#### build
### Commit Messages
If a commit touches only 1 component, prefix the message with the affected component. i.e. `backend: update to tokio v0.3`.
Auxiliary files and scripts to include in deployed StartOS images
### Pull Requests
The body of a pull request should contain sufficient description of what the changes do, as well as a justification.
You should include references to any relevant [issues](https://github.com/Start9Labs/embassy-os/issues).
#### debian
### Rebasing Changes
When a pull request conflicts with the target branch, you may be asked to rebase it on top of the current target branch. The git rebase command will take care of rebuilding your commits on top of the new base.
Maintainer scripts for the StartOS Debian package
This project aims to have a clean git history, where code changes are only made in non-merge commits. This simplifies auditability because merge commits can be assumed to not contain arbitrary code changes.
#### web
## Join The Discussion
Current or aspiring contributors? Join our community developer [Matrix channel](https://matrix.to/#/#community-dev:matrix.start9labs.com).
Web UIs served under various conditions and used to interact with StartOS APIs.
Just interested in or using the project? Join our community [Telegram](https://t.me/start9_labs) or [Matrix](https://matrix.to/#/#community:matrix.start9labs.com).
#### image-recipe
## Join The Project Team
Interested in becoming a part of the Start9 Labs team? Send an email to <jobs@start9labs.com>
Scripts for building StartOS images
<!-- omit in toc -->
## Attribution
This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!
#### patch-db (submodule)
A diff based data store used to synchronize data between the web interfaces and server.
#### sdk
A typescript sdk for building start-os packages
## Environment Setup
#### Clone the StartOS repository
```sh
git clone https://github.com/Start9Labs/start-os.git --recurse-submodules
cd start-os
```
#### Continue to your project of interest for additional instructions:
- [`core`](core/README.md)
- [`web-interfaces`](web-interfaces/README.md)
- [`build`](build/README.md)
- [`patch-db`](https://github.com/Start9Labs/patch-db)
## Building
This project uses [GNU Make](https://www.gnu.org/software/make/) to build its components. To build any specific component, simply run `make <TARGET>` replacing `<TARGET>` with the name of the target you'd like to build
### Requirements
- [GNU Make](https://www.gnu.org/software/make/)
- [Docker](https://docs.docker.com/get-docker/)
- [NodeJS v20.16.0](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
- [sed](https://www.gnu.org/software/sed/)
- [grep](https://www.gnu.org/software/grep/)
- [awk](https://www.gnu.org/software/gawk/)
- [jq](https://jqlang.github.io/jq/)
- [gzip](https://www.gnu.org/software/gzip/)
- [brotli](https://github.com/google/brotli)
### Environment variables
- `PLATFORM`: which platform you would like to build for. Must be one of `x86_64`, `x86_64-nonfree`, `aarch64`, `aarch64-nonfree`, `raspberrypi`
- NOTE: `nonfree` images are for including `nonfree` firmware packages in the built ISO
- `ENVIRONMENT`: a hyphen separated set of feature flags to enable
- `dev`: enables password ssh (INSECURE!) and does not compress frontends
- `unstable`: enables assertions that will cause errors on unexpected inconsistencies that are undesirable in production use either for performance or reliability reasons
- `docker`: use `docker` instead of `podman`
- `GIT_BRANCH_AS_HASH`: set to `1` to use the current git branch name as the git hash so that the project does not need to be rebuilt on each commit
### Useful Make Targets
- `iso`: Create a full `.iso` image
- Only possible from Debian
- Not available for `PLATFORM=raspberrypi`
- Additional Requirements:
- [debspawn](https://github.com/lkhq/debspawn)
- `img`: Create a full `.img` image
- Only possible from Debian
- Only available for `PLATFORM=raspberrypi`
- Additional Requirements:
- [debspawn](https://github.com/lkhq/debspawn)
- `format`: Run automatic code formatting for the project
- Additional Requirements:
- [rust](https://rustup.rs/)
- `test`: Run automated tests for the project
- Additional Requirements:
- [rust](https://rustup.rs/)
- `update`: Deploy the current working project to a device over ssh as if through an over-the-air update
- Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2`
- `reflash`: Deploy the current working project to a device over ssh as if using a live `iso` image to reflash it
- Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2`
- `update-overlay`: Deploy the current working project to a device over ssh to the in-memory overlay without restarting it
- WARNING: changes will be reverted after the device is rebooted
- WARNING: changes to `init` will not take effect as the device is already initialized
- Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2`
- `wormhole`: Deploy the `startbox` to a device using [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole)
- When the build it complete will emit a command to paste into the shell of the device to upgrade it
- Additional Requirements:
- [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole)
- `clean`: Delete all compiled artifacts

134
DEVELOPMENT.md Normal file
View File

@@ -0,0 +1,134 @@
# Setting up your development environment on Debian/Ubuntu
A step-by-step guide
> This is the only officially supported build environment.
> MacOS has limited build capabilities and Windows requires [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install)
## Installing dependencies
Run the following commands one at a time
```sh
sudo apt update
sudo apt install -y ca-certificates curl gpg build-essential
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg-architecture -q DEB_HOST_ARCH) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bookworm stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y sed grep gawk jq gzip brotli containerd.io docker-ce docker-ce-cli docker-compose-plugin qemu-user-static binfmt-support squashfs-tools git debspawn rsync b3sum
sudo mkdir -p /etc/debspawn/
echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml
sudo usermod -aG docker $USER
sudo su $USER
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create --use
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # proceed with default installation
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
nvm alias default 22 # this prevents your machine from reverting back to another version
```
## Cloning the repository
```sh
git clone --recursive https://github.com/Start9Labs/start-os.git --branch next/major
cd start-os
```
## Building an ISO
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make iso
```
This will build an ISO for your current architecture. If you are building to run on an architecture other than the one you are currently on, replace `$(uname -m)` with the correct platform for the device (one of `aarch64`, `aarch64-nonfree`, `x86_64`, `x86_64-nonfree`, `raspberrypi`)
## Creating a VM
### Install virt-manager
```sh
sudo apt update
sudo apt install -y virt-manager
sudo usermod -aG libvirt $USER
sudo su $USER
```
### Launch virt-manager
```sh
virt-manager
```
### Create new virtual machine
![Select "Create a new virtual machine"](assets/create-vm/step-1.png)
![Click "Forward"](assets/create-vm/step-2.png)
![Click "Browse"](assets/create-vm/step-3.png)
![Click "+"](assets/create-vm/step-4.png)
#### make sure to set "Target Path" to the path to your results directory in start-os
![Create storage pool](assets/create-vm/step-5.png)
![Select storage pool](assets/create-vm/step-6.png)
![Select ISO](assets/create-vm/step-7.png)
![Select "Generic or unknown OS" and click "Forward"](assets/create-vm/step-8.png)
![Set Memory and CPUs](assets/create-vm/step-9.png)
![Create disk](assets/create-vm/step-10.png)
![Name VM](assets/create-vm/step-11.png)
![Create network](assets/create-vm/step-12.png)
## Updating a VM
The fastest way to update a VM to your latest code depends on what you changed:
### UI or startd:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make update-startbox REMOTE=start9@<VM IP>
```
### Container runtime or debian dependencies:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make update-deb REMOTE=start9@<VM IP>
```
### Image recipe:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make update-squashfs REMOTE=start9@<VM IP>
```
---
If the device you are building for is not available via ssh, it is also possible to use `magic-wormhole` to send the relevant files.
### Prerequisites:
```sh
sudo apt update
sudo apt install -y magic-wormhole
```
As before, the fastest way to update a VM to your latest code depends on what you changed. Each of the following commands will return a command to paste into the shell of the device you would like to upgrade.
### UI or startd:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole
```
### Container runtime or debian dependencies:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole-deb
```
### Image recipe:
```sh
PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole-squashfs
```

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Start9 Labs, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,25 +0,0 @@
# START9 PERSONAL USE LICENSE v1.0
This license governs the use of the accompanying Software. If you use the Software, you accept this license. If you do not accept the license, do not use the Software.
1. **Definitions.**
1. “Licensor” means the copyright owner, Start9 Labs, Inc, or its successor(s) in interest, or a future assignee of the copyright.
2. “Source Code” means the preferred form of the Software for making modifications to it.
3. “Object Code” means any non-source form of the Software, including the machine-language output by a compiler or assembler.
4. “Distribute” means to convey or to publish and generally has the same meaning here as under U.S. Copyright law.
5. “Sell” means practicing any or all of the rights granted to you under the License to provide to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/support services related to the Software), a product or service whose value derives, entirely or substantially, from the functionality of the Software.
2. **Grant of Rights.** Subject to the terms of this license, the Licensor grants you, the licensee, a non-exclusive, worldwide, royalty-free copyright license to:
1. Access, audit, copy, modify, compile, or distribute the Source Code or modifications to the Source Code.
2. Run, test, or otherwise use the Object Code.
3. **Limitations.**
1. The grant of rights under the License will NOT include, and the License does NOT grant you the right to:
1. Sell the Software or any derivative works based thereon.
2. Distribute the Object Code.
2. If you Distribute the Source Code, or if permission is separately granted to Distribute the Object Code, you expressly undertake not to remove, or modify, in any manner, the copyright notices attached to the Source Code, and displayed in any output of the Object Code when run, and to reproduce these notices, in an identical manner, in any distributed copies of the Software together with a copy of this license. If you Distribute a modified copy of the Software, or a derivative work based thereon, the work must carry prominent notices stating that you modified it, and giving a relevant date.
3. The terms of this license will apply to anyone who comes into possession of a copy of the Software, and any modifications or derivative works based thereon, made by anyone.
4. **Contributions.** You hereby grant to Licensor a perpetual, irrevocable, worldwide, non-exclusive, royalty-free license to use and exploit any modifications or derivative works based on the Source Code of which you are the author.
5. **Disclaimer.** THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. LICENSOR HAS NO OBLIGATION TO SUPPORT RECIPIENTS OF THE SOFTWARE.

376
Makefile
View File

@@ -1,73 +1,345 @@
EMBASSY_BINS := backend/target/aarch64-unknown-linux-gnu/release/embassyd backend/target/aarch64-unknown-linux-gnu/release/embassy-init backend/target/aarch64-unknown-linux-gnu/release/embassy-cli backend/target/aarch64-unknown-linux-gnu/release/embassy-sdk
EMBASSY_UIS := frontend/dist/ui frontend/dist/setup-wizard frontend/dist/diagnostic-ui
EMBASSY_SRC := raspios.img product_key.txt $(EMBASSY_BINS) backend/embassyd.service backend/embassy-init.service $(EMBASSY_UIS) $(shell find build)
COMPAT_SRC := $(shell find system-images/compat/src)
UTILS_SRC := $(shell find system-images/utils/Dockerfile)
BACKEND_SRC := $(shell find backend/src) $(shell find patch-db/*/src) $(shell find rpc-toolkit/*/src) backend/Cargo.toml backend/Cargo.lock
FRONTEND_SRC := $(shell find frontend/projects) $(shell find frontend/assets)
PATCH_DB_CLIENT_SRC = $(shell find patch-db/client -not -path patch-db/client/dist)
GIT_REFS := $(shell find .git/refs/heads)
TMP_FILE := $(shell mktemp)
ls-files = $(shell git ls-files --cached --others --exclude-standard $1)
PROFILE = release
PLATFORM_FILE := $(shell ./check-platform.sh)
ENVIRONMENT_FILE := $(shell ./check-environment.sh)
GIT_HASH_FILE := $(shell ./check-git-hash.sh)
VERSION_FILE := $(shell ./check-version.sh)
BASENAME := $(shell ./basename.sh)
PLATFORM := $(shell if [ -f ./PLATFORM.txt ]; then cat ./PLATFORM.txt; else echo unknown; fi)
ARCH := $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo aarch64; else echo $(PLATFORM) | sed 's/-nonfree$$//g'; fi)
IMAGE_TYPE=$(shell if [ "$(PLATFORM)" = raspberrypi ]; then echo img; else echo iso; fi)
WEB_UIS := web/dist/raw/ui/index.html web/dist/raw/setup-wizard/index.html web/dist/raw/install-wizard/index.html
COMPRESSED_WEB_UIS := web/dist/static/ui/index.html web/dist/static/setup-wizard/index.html web/dist/static/install-wizard/index.html
FIRMWARE_ROMS := ./firmware/$(PLATFORM) $(shell jq --raw-output '.[] | select(.platform[] | contains("$(PLATFORM)")) | "./firmware/$(PLATFORM)/" + .id + ".rom.gz"' build/lib/firmware.json)
BUILD_SRC := $(call ls-files, build) build/lib/depends build/lib/conflicts $(FIRMWARE_ROMS)
DEBIAN_SRC := $(call ls-files, debian/)
IMAGE_RECIPE_SRC := $(call ls-files, image-recipe/)
STARTD_SRC := core/startos/startd.service $(BUILD_SRC)
CORE_SRC := $(call ls-files, core) $(shell git ls-files --recurse-submodules patch-db) $(GIT_HASH_FILE)
WEB_SHARED_SRC := $(call ls-files, web/projects/shared) $(call ls-files, web/projects/marketplace) $(shell ls -p web/ | grep -v / | sed 's/^/web\//g') web/node_modules/.package-lock.json web/config.json patch-db/client/dist/index.js sdk/baseDist/package.json web/patchdb-ui-seed.json sdk/dist/package.json
WEB_UI_SRC := $(call ls-files, web/projects/ui)
WEB_SETUP_WIZARD_SRC := $(call ls-files, web/projects/setup-wizard)
WEB_INSTALL_WIZARD_SRC := $(call ls-files, web/projects/install-wizard)
PATCH_DB_CLIENT_SRC := $(shell git ls-files --recurse-submodules patch-db/client)
GZIP_BIN := $(shell which pigz || which gzip)
TAR_BIN := $(shell which gtar || which tar)
COMPILED_TARGETS := core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox core/target/$(ARCH)-unknown-linux-musl/release/containerbox container-runtime/rootfs.$(ARCH).squashfs
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(PLATFORM_FILE) \
$(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then \
echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; \
fi) \
$(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then \
echo cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph; \
fi') \
$(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)console($$|-) ]]; then \
echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; \
fi')
REBUILD_TYPES = 1
ifeq ($(REMOTE),)
mkdir = mkdir -p $1
rm = rm -rf $1
cp = cp -r $1 $2
ln = ln -sf $1 $2
else
ifeq ($(SSHPASS),)
ssh = ssh $(REMOTE) $1
else
ssh = sshpass -p $(SSHPASS) ssh $(REMOTE) $1
endif
mkdir = $(call ssh,'sudo mkdir -p $1')
rm = $(call ssh,'sudo rm -rf $1')
ln = $(call ssh,'sudo ln -sf $1 $2')
define cp
$(TAR_BIN) --transform "s|^$1|x|" -czv -f- $1 | $(call ssh,"sudo tar --transform 's|^x|$2|' -xzv -f- -C /")
endef
endif
.DELETE_ON_ERROR:
all: eos.img
.PHONY: all metadata install clean format cli uis ui reflash deb $(IMAGE_TYPE) squashfs wormhole wormhole-deb test test-core test-sdk test-container-runtime registry
gzip: eos.img
gzip -k eos.img
all: $(ALL_TARGETS)
touch:
touch $(ALL_TARGETS)
metadata: $(VERSION_FILE) $(PLATFORM_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE)
clean:
rm -f eos.img
rm -f ubuntu.img
rm -f product_key.txt
rm -f system-images/**/*.tar
sudo rm -f $(EMBASSY_BINS)
rm -rf frontend/node_modules
rm -rf frontend/dist
rm -rf core/target
rm -rf core/startos/bindings
rm -rf web/.angular
rm -f web/config.json
rm -rf web/node_modules
rm -rf web/dist
rm -rf patch-db/client/node_modules
rm -rf patch-db/client/dist
rm -rf patch-db/target
rm -rf cargo-deps
rm -rf dpkg-workdir
rm -rf image-recipe/deb
rm -rf results
rm -rf build/lib/firmware
rm -rf container-runtime/dist
rm -rf container-runtime/node_modules
rm -f container-runtime/*.squashfs
if [ -d container-runtime/tmp/combined ] && mountpoint container-runtime/tmp/combined; then sudo umount container-runtime/tmp/combined; fi
if [ -d container-runtime/tmp/lower ] && mountpoint container-runtime/tmp/lower; then sudo umount container-runtime/tmp/lower; fi
rm -rf container-runtime/tmp
(cd sdk && make clean)
rm -f ENVIRONMENT.txt
rm -f PLATFORM.txt
rm -f GIT_HASH.txt
rm -f VERSION.txt
eos.img: $(EMBASSY_SRC) system-images/compat/compat.tar system-images/utils/utils.tar
! test -f eos.img || rm eos.img
if [ "$(NO_KEY)" = "1" ]; then NO_KEY=1 ./build/make-image.sh; else ./build/make-image.sh; fi
format:
cd core && cargo +nightly fmt
system-images/compat/compat.tar: $(COMPAT_SRC)
cd system-images/compat && ./build.sh
cd system-images/compat && DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --tag start9/x_system/compat --platform=linux/arm64 -o type=docker,dest=compat.tar .
test: | test-core test-sdk test-container-runtime
system-images/utils/utils.tar: $(UTILS_SRC)
cd system-images/utils && DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --tag start9/x_system/utils --platform=linux/arm64 -o type=docker,dest=utils.tar .
test-core: $(CORE_SRC) $(ENVIRONMENT_FILE)
./core/run-tests.sh
raspios.img:
wget https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2022-01-28/2022-01-28-raspios-bullseye-arm64-lite.zip
unzip 2022-01-28-raspios-bullseye-arm64-lite.zip
mv 2022-01-28-raspios-bullseye-arm64-lite.img raspios.img
test-sdk: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts
cd sdk && make test
product_key.txt:
$(shell which echo) -n "X" > product_key.txt
cat /dev/urandom | base32 | head -c11 | tr '[:upper:]' '[:lower:]' >> product_key.txt
if [ "$(KEY)" != "" ]; then $(shell which echo) -n "$(KEY)" > product_key.txt; fi
echo >> product_key.txt
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
$(EMBASSY_BINS): $(BACKEND_SRC)
cd backend && ./build-prod.sh
cli:
./core/install-cli.sh
frontend/node_modules: frontend/package.json
npm --prefix frontend ci
registry:
./core/build-registrybox.sh
$(EMBASSY_UIS): $(FRONTEND_SRC) frontend/node_modules patch-db/client patch-db/client/dist frontend/config.json
npm --prefix frontend run build:all
tunnel:
./core/build-tunnelbox.sh
frontend/config.json: .git/HEAD $(GIT_REFS)
jq '.useMocks = false' frontend/config-sample.json > frontend/config.json
npm --prefix frontend run-script build-config
deb: results/$(BASENAME).deb
patch-db/client/node_modules: patch-db/client/package.json
npm --prefix patch-db/client install
debian/control: build/lib/depends build/lib/conflicts
./debuild/control.sh
patch-db/client/dist: $(PATCH_DB_CLIENT_SRC) patch-db/client/node_modules
! test -d patch-db/client/dist || rm -rf patch-db/client/dist
results/$(BASENAME).deb: dpkg-build.sh $(DEBIAN_SRC) $(ALL_TARGETS)
PLATFORM=$(PLATFORM) REQUIRES=debian ./build/os-compat/run-compat.sh ./dpkg-build.sh
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)
squashfs: results/$(BASENAME).squashfs
results/$(BASENAME).$(IMAGE_TYPE) results/$(BASENAME).squashfs: $(IMAGE_RECIPE_SRC) results/$(BASENAME).deb
REQUIRES=debian ./build/os-compat/run-compat.sh ./image-recipe/run-local-build.sh "results/$(BASENAME).deb"
# For creating os images. DO NOT USE
install: $(ALL_TARGETS)
$(call mkdir,$(DESTDIR)/usr/bin)
$(call mkdir,$(DESTDIR)/usr/sbin)
$(call cp,core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox,$(DESTDIR)/usr/bin/startbox)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/startd)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/start-cli)
if [ "$(PLATFORM)" = "raspberrypi" ]; then $(call cp,cargo-deps/aarch64-unknown-linux-musl/release/pi-beep,$(DESTDIR)/usr/bin/pi-beep); fi
if /bin/bash -c '[[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]'; then \
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph,$(DESTDIR)/usr/bin/flamegraph); \
fi
if /bin/bash -c '[[ "${ENVIRONMENT}" =~ (^|-)console($$|-) ]]'; then \
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console,$(DESTDIR)/usr/bin/tokio-console); \
fi
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs,$(DESTDIR)/usr/bin/startos-backup-fs)
$(call ln,/usr/bin/startos-backup-fs,$(DESTDIR)/usr/sbin/mount.backup-fs)
$(call mkdir,$(DESTDIR)/lib/systemd/system)
$(call cp,core/startos/startd.service,$(DESTDIR)/lib/systemd/system/startd.service)
$(call mkdir,$(DESTDIR)/usr/lib)
$(call rm,$(DESTDIR)/usr/lib/startos)
$(call cp,build/lib,$(DESTDIR)/usr/lib/startos)
$(call mkdir,$(DESTDIR)/usr/lib/startos/container-runtime)
$(call cp,container-runtime/rootfs.$(ARCH).squashfs,$(DESTDIR)/usr/lib/startos/container-runtime/rootfs.squashfs)
$(call cp,PLATFORM.txt,$(DESTDIR)/usr/lib/startos/PLATFORM.txt)
$(call cp,ENVIRONMENT.txt,$(DESTDIR)/usr/lib/startos/ENVIRONMENT.txt)
$(call cp,GIT_HASH.txt,$(DESTDIR)/usr/lib/startos/GIT_HASH.txt)
$(call cp,VERSION.txt,$(DESTDIR)/usr/lib/startos/VERSION.txt)
$(call cp,firmware/$(PLATFORM),$(DESTDIR)/usr/lib/startos/firmware)
update-overlay: $(ALL_TARGETS)
@echo "\033[33m!!! THIS WILL ONLY REFLASH YOUR DEVICE IN MEMORY !!!\033[0m"
@echo "\033[33mALL CHANGES WILL BE REVERTED IF YOU RESTART THE DEVICE\033[0m"
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
@if [ "`ssh $(REMOTE) 'cat /usr/lib/startos/VERSION.txt'`" != "`cat ./VERSION.txt`" ]; then >&2 echo "StartOS requires migrations: update-overlay is unavailable." && false; fi
$(call ssh,"sudo systemctl stop startd")
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) PLATFORM=$(PLATFORM)
$(call ssh,"sudo systemctl start startd")
wormhole: core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox
@echo "Paste the following command into the shell of your StartOS server:"
@echo
@wormhole send core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade \"cd /usr/bin && rm startbox && wormhole receive --accept-file %s && chmod +x startbox\"\n", $$3 }'
wormhole-deb: results/$(BASENAME).deb
@echo "Paste the following command into the shell of your StartOS server:"
@echo
@wormhole send results/$(BASENAME).deb 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade '"'"'cd $$(mktemp -d) && wormhole receive --accept-file %s && apt-get install -y --reinstall ./$(BASENAME).deb'"'"'\n", $$3 }'
wormhole-squashfs: results/$(BASENAME).squashfs
$(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs | head -c 32))
$(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}'))
@echo "Paste the following command into the shell of your StartOS server:"
@echo
@wormhole send results/$(BASENAME).squashfs 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo sh -c '"'"'/usr/lib/startos/scripts/prune-images $(SQFS_SIZE) && /usr/lib/startos/scripts/prune-boot && cd /media/startos/images && wormhole receive --accept-file %s && CHECKSUM=$(SQFS_SUM) /usr/lib/startos/scripts/use-img ./$(BASENAME).squashfs'"'"'\n", $$3 }'
update: $(ALL_TARGETS)
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM)
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"')
update-startbox: core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox # only update binary (faster than full update)
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
$(call cp,core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox,/media/startos/next/usr/bin/startbox)
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync true')
update-deb: results/$(BASENAME).deb # better than update, but only available from debian
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
$(call mkdir,/media/startos/next/tmp/startos-deb)
$(call cp,results/$(BASENAME).deb,/media/startos/next/tmp/startos-deb/$(BASENAME).deb)
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y --reinstall /tmp/startos-deb/$(BASENAME).deb"')
update-squashfs: results/$(BASENAME).squashfs
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs))
$(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}'))
$(call ssh,'/usr/lib/startos/scripts/prune-images $(SQFS_SIZE)')
$(call ssh,'/usr/lib/startos/scripts/prune-boot')
$(call cp,results/$(BASENAME).squashfs,/media/startos/images/next.rootfs)
$(call ssh,'sudo CHECKSUM=$(SQFS_SUM) /usr/lib/startos/scripts/use-img /media/startos/images/next.rootfs')
emulate-reflash: $(ALL_TARGETS)
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM)
$(call ssh,'sudo rm -f /media/startos/config/disk.guid /media/startos/config/overlay/etc/hostname')
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"')
upload-ota: results/$(BASENAME).squashfs
TARGET=$(TARGET) KEY=$(KEY) ./upload-ota.sh
container-runtime/debian.$(ARCH).squashfs: ./container-runtime/download-base-image.sh
ARCH=$(ARCH) ./container-runtime/download-base-image.sh
container-runtime/package-lock.json: sdk/dist/package.json
npm --prefix container-runtime i
touch container-runtime/package-lock.json
container-runtime/node_modules/.package-lock.json: container-runtime/package-lock.json
npm --prefix container-runtime ci
touch container-runtime/node_modules/.package-lock.json
sdk/base/lib/osBindings/index.ts: $(shell if [ "$(REBUILD_TYPES)" -ne 0 ]; then echo core/startos/bindings/index.ts; fi)
mkdir -p sdk/base/lib/osBindings
rsync -ac --delete core/startos/bindings/ sdk/base/lib/osBindings/
touch sdk/base/lib/osBindings/index.ts
core/startos/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
rm -rf core/startos/bindings
./core/build-ts.sh
ls core/startos/bindings/*.ts | sed 's/core\/startos\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/startos/bindings/index.ts
npm --prefix sdk exec -- prettier --config ./sdk/base/package.json -w ./core/startos/bindings/*.ts
touch core/startos/bindings/index.ts
sdk/dist/package.json sdk/baseDist/package.json: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts
(cd sdk && make bundle)
touch sdk/dist/package.json
touch sdk/baseDist/package.json
# TODO: make container-runtime its own makefile?
container-runtime/dist/index.js: container-runtime/node_modules/.package-lock.json $(call ls-files, container-runtime/src) container-runtime/package.json container-runtime/tsconfig.json
npm --prefix container-runtime run build
container-runtime/dist/node_modules/.package-lock.json container-runtime/dist/package.json container-runtime/dist/package-lock.json: container-runtime/package.json container-runtime/package-lock.json sdk/dist/package.json container-runtime/install-dist-deps.sh
./container-runtime/install-dist-deps.sh
touch container-runtime/dist/node_modules/.package-lock.json
container-runtime/rootfs.$(ARCH).squashfs: container-runtime/debian.$(ARCH).squashfs container-runtime/container-runtime.service container-runtime/update-image.sh container-runtime/deb-install.sh container-runtime/dist/index.js container-runtime/dist/node_modules/.package-lock.json core/target/$(ARCH)-unknown-linux-musl/release/containerbox
ARCH=$(ARCH) REQUIRES=linux ./build/os-compat/run-compat.sh ./container-runtime/update-image.sh
build/lib/depends build/lib/conflicts: $(ENVIRONMENT_FILE) build/dpkg-deps/*
build/dpkg-deps/generate.sh
$(FIRMWARE_ROMS): build/lib/firmware.json download-firmware.sh $(PLATFORM_FILE)
./download-firmware.sh $(PLATFORM)
core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox: $(CORE_SRC) $(COMPRESSED_WEB_UIS) web/patchdb-ui-seed.json $(ENVIRONMENT_FILE)
ARCH=$(ARCH) PROFILE=$(PROFILE) ./core/build-startbox.sh
touch core/target/$(ARCH)-unknown-linux-musl/$(PROFILE)/startbox
core/target/$(ARCH)-unknown-linux-musl/release/containerbox: $(CORE_SRC) $(ENVIRONMENT_FILE)
ARCH=$(ARCH) ./core/build-containerbox.sh
touch core/target/$(ARCH)-unknown-linux-musl/release/containerbox
web/package-lock.json: web/package.json sdk/baseDist/package.json
npm --prefix web i
touch web/package-lock.json
web/node_modules/.package-lock.json: web/package-lock.json
npm --prefix web ci
touch web/node_modules/.package-lock.json
web/.angular/.updated: patch-db/client/dist/index.js sdk/baseDist/package.json web/node_modules/.package-lock.json
rm -rf web/.angular
mkdir -p web/.angular
touch web/.angular/.updated
web/dist/raw/ui/index.html: $(WEB_UI_SRC) $(WEB_SHARED_SRC) web/.angular/.updated
npm --prefix web run build:ui
touch web/dist/raw/ui/index.html
web/dist/raw/setup-wizard/index.html: $(WEB_SETUP_WIZARD_SRC) $(WEB_SHARED_SRC) web/.angular/.updated
npm --prefix web run build:setup
touch web/dist/raw/setup-wizard/index.html
web/dist/raw/install-wizard/index.html: $(WEB_INSTALL_WIZARD_SRC) $(WEB_SHARED_SRC) web/.angular/.updated
npm --prefix web run build:install
touch web/dist/raw/install-wizard/index.html
$(COMPRESSED_WEB_UIS): $(WEB_UIS) $(ENVIRONMENT_FILE)
./compress-uis.sh
web/config.json: $(GIT_HASH_FILE) web/config-sample.json
jq '.useMocks = false' web/config-sample.json | jq '.gitHash = "$(shell cat GIT_HASH.txt)"' > web/config.json
patch-db/client/node_modules/.package-lock.json: patch-db/client/package.json
npm --prefix patch-db/client ci
touch patch-db/client/node_modules/.package-lock.json
patch-db/client/dist/index.js: $(PATCH_DB_CLIENT_SRC) patch-db/client/node_modules/.package-lock.json
rm -rf patch-db/client/dist
npm --prefix patch-db/client run build
touch patch-db/client/dist/index.js
# this is a convenience step to build all frontends - it is not referenced elsewhere in this file
frontend: frontend/node_modules $(EMBASSY_UIS)
# used by github actions
compiled-$(ARCH).tar: $(COMPILED_TARGETS) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE)
tar -cvf $@ $^
# this is a convenience step to build all web uis - it is not referenced elsewhere in this file
uis: $(WEB_UIS)
# this is a convenience step to build the UI
ui: web/dist/raw/ui
cargo-deps/aarch64-unknown-linux-musl/release/pi-beep:
ARCH=aarch64 ./build-cargo-dep.sh pi-beep
cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console:
ARCH=$(ARCH) PREINSTALL="apk add musl-dev pkgconfig" ./build-cargo-dep.sh tokio-console
cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs:
ARCH=$(ARCH) PREINSTALL="apk add fuse3 fuse3-dev fuse3-static musl-dev pkgconfig" ./build-cargo-dep.sh --git https://github.com/Start9Labs/start-fs.git startos-backup-fs
cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph:
ARCH=$(ARCH) PREINSTALL="apk add musl-dev pkgconfig" ./build-cargo-dep.sh flamegraph

123
README.md
View File

@@ -1,49 +1,82 @@
# EmbassyOS
[![Version](https://img.shields.io/github/v/tag/Start9Labs/embassy-os?color=success)](https://github.com/Start9Labs/embassy-os/releases)
[![community](https://img.shields.io/badge/community-matrix-yellow)](https://matrix.to/#/#community:matrix.start9labs.com)
[![community](https://img.shields.io/badge/community-telegram-informational)](https://t.me/start9_labs)
[![support](https://img.shields.io/badge/support-docs-important)](https://docs.start9labs.com)
[![developer](https://img.shields.io/badge/developer-matrix-blueviolet)](https://matrix.to/#/#community-dev:matrix.start9labs.com)
[![website](https://img.shields.io/website?down_color=lightgrey&down_message=offline&up_color=green&up_message=online&url=https%3A%2F%2Fstart9labs.com)](https://start9labs.com)
[![mastodon](https://img.shields.io/mastodon/follow/000000001?domain=https%3A%2F%2Fmastodon.start9labs.com&label=Follow&style=social)](http://mastodon.start9labs.com)
[![twitter](https://img.shields.io/twitter/follow/start9labs?label=Follow)](https://twitter.com/start9labs)
### _Welcome to the era of Sovereign Computing_ ###
EmbassyOS is a browser-based, graphical operating system for a personal server. EmbassyOS facilitates the discovery, installation, network configuration, service configuration, data backup, dependency management, and health monitoring of self-hosted software services. It is the most advanced, secure, reliable, and user friendly personal server OS in the world.
## Running EmbassyOS
There are multiple ways to get your hands on EmbassyOS.
### :moneybag: Buy an Embassy
This is the most convenient option. Simply [buy an Embassy](https://start9.com) from Start9 and plug it in. Depending on where you live, shipping costs and import duties will vary.
### :construction_worker: Build your own Embassy
While not as convenient as buying an Embassy, this option is easier than you might imagine, and there are 4 reasons why you might prefer it:
1. You already have a Raspberry Pi and would like to re-purpose it.
1. You want to save on shipping costs.
1. You prefer not to divulge your physical address.
1. You just like building things.
To pursue this option, follow this [guide](https://start9.com/latest/diy).
### :hammer_and_wrench: Build EmbassyOS from Source
EmbassyOS can be built from source, for personal use, for free.
A detailed guide for doing so can be found [here](https://github.com/Start9Labs/embassy-os/blob/master/build/README.md).
## :heart: Contributing
There are multiple ways to contribute: work directly on EmbassyOS, package a service for the marketplace, or help with documentation and guides. To learn more about contributing, see [here](https://github.com/Start9Labs/embassy-os/blob/master/CONTRIBUTING.md).
## UI Screenshots
<div align="center">
<img src="web/projects/shared/assets/img/icon.png" alt="StartOS Logo" width="16%" />
<h1 style="margin-top: 0;">StartOS</h1>
<a href="https://github.com/Start9Labs/start-os/releases">
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/start9labs/start-os?logo=github">
</a>
<a href="https://github.com/Start9Labs/start-os/actions/workflows/startos-iso.yaml">
<img src="https://github.com/Start9Labs/start-os/actions/workflows/startos-iso.yaml/badge.svg">
</a>
<a href="https://heyapollo.com/product/startos">
<img alt="Static Badge" src="https://img.shields.io/badge/apollo-review%20%E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90%20-slateblue">
</a>
<a href="https://twitter.com/start9labs">
<img alt="X (formerly Twitter) Follow" src="https://img.shields.io/twitter/follow/start9labs">
</a>
<a href="https://matrix.to/#/#community:matrix.start9labs.com">
<img alt="Static Badge" src="https://img.shields.io/badge/community-matrix-yellow?logo=matrix">
</a>
<a href="https://t.me/start9_labs">
<img alt="Static Badge" src="https://img.shields.io/badge/community-telegram-blue?logo=telegram">
</a>
<a href="https://docs.start9.com">
<img alt="Static Badge" src="https://img.shields.io/badge/docs-orange?label=%F0%9F%91%A4%20support">
</a>
<a href="https://matrix.to/#/#community-dev:matrix.start9labs.com">
<img alt="Static Badge" src="https://img.shields.io/badge/developer-matrix-darkcyan?logo=matrix">
</a>
<a href="https://start9.com">
<img alt="Website" src="https://img.shields.io/website?up_message=online&down_message=offline&url=https%3A%2F%2Fstart9.com&logo=website&label=%F0%9F%8C%90%20website">
</a>
</div>
<br />
<div align="center">
<h3>
Welcome to the era of Sovereign Computing
</h3>
<p>
StartOS is an open source Linux distribution optimized for running a personal server. It facilitates the discovery, installation, network configuration, service configuration, data backup, dependency management, and health monitoring of self-hosted software services.
</p>
</div>
<br />
<p align="center">
<img src="assets/EmbassyOS.png" alt="EmbassyOS" width="65%">
<img src="assets/StartOS.png" alt="StartOS" width="85%">
</p>
<br />
## Running StartOS
> [!WARNING]
> StartOS is in beta. It lacks features. It doesn't always work perfectly. Start9 servers are not plug and play. Using them properly requires some effort and patience. Please do not use StartOS or purchase a server if you are unable or unwilling to follow instructions and learn new concepts.
### 💰 Buy a Start9 server
This is the most convenient option. Simply [buy a server](https://store.start9.com) from Start9 and plug it in.
### 👷 Build your own server
This option is easier than you might imagine, and there are 4 reasons why you might prefer it:
1. You already have hardware
1. You want to save on shipping costs
1. You prefer not to divulge your physical address
1. You just like building things
To pursue this option, follow one of our [DIY guides](https://start9.com/latest/diy).
## ❤️ Contributing
There are multiple ways to contribute: work directly on StartOS, package a service for the marketplace, or help with documentation and guides. To learn more about contributing, see [here](https://start9.com/contribute/).
To report security issues, please email our security team - security@start9.com.
## 🌎 Marketplace
There are dozens of services available for StartOS, and new ones are being added all the time. Check out the full list of available services [here](https://marketplace.start9.com/marketplace). To read more about the Marketplace ecosystem, check out this [blog post](https://blog.start9.com/start9-marketplace-strategy/)
## 🖥️ User Interface Screenshots
<p align="center">
<img src="assets/eos-services.png" alt="Embassy Services" width="45%">
<img src="assets/eos-preferences.png" alt="Embassy Preferences" width="45%">
</p>
<p align="center">
<img src="assets/eos-bitcoind-health-check.png" alt="Embassy Bitcoin Health Checks" width="45%"> <img src="assets/eos-logs.png" alt="Embassy Logs" width="45%">
<img src="assets/registry.png" alt="StartOS Marketplace" width="49%">
<img src="assets/community.png" alt="StartOS Community Registry" width="49%">
<img src="assets/c-lightning.png" alt="StartOS NextCloud Service" width="49%">
<img src="assets/btcpay.png" alt="StartOS BTCPay Service" width="49%">
<img src="assets/nextcloud.png" alt="StartOS System Settings" width="49%">
<img src="assets/system.png" alt="StartOS System Settings" width="49%">
<img src="assets/welcome.png" alt="StartOS System Settings" width="49%">
<img src="assets/logs.png" alt="StartOS System Settings" width="49%">
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 KiB

BIN
assets/StartOS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
assets/btcpay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

BIN
assets/c-lightning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

BIN
assets/community.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

BIN
assets/create-vm/step-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/create-vm/step-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/create-vm/step-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/create-vm/step-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
assets/create-vm/step-5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
assets/create-vm/step-6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
assets/create-vm/step-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
assets/create-vm/step-8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
assets/create-vm/step-9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 KiB

BIN
assets/logs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
assets/nextcloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

BIN
assets/registry.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 KiB

BIN
assets/system.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

BIN
assets/welcome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

View File

@@ -1,139 +0,0 @@
[package]
authors = ["Aiden McClelland <me@drbonez.dev>"]
description = "The core of the Start9 Embassy Operating System"
documentation = "https://docs.rs/embassy-os"
edition = "2018"
keywords = [
"self-hosted",
"raspberry-pi",
"privacy",
"bitcoin",
"full-node",
"lightning",
]
name = "embassy-os"
readme = "README.md"
repository = "https://github.com/Start9Labs/embassy-os"
version = "0.3.0-rev.1"
[lib]
name = "embassy"
path = "src/lib.rs"
[[bin]]
name = "embassyd"
path = "src/bin/embassyd.rs"
[[bin]]
name = "embassy-init"
path = "src/bin/embassy-init.rs"
[[bin]]
name = "embassy-sdk"
path = "src/bin/embassy-sdk.rs"
[[bin]]
name = "embassy-cli"
path = "src/bin/embassy-cli.rs"
[features]
avahi = ["avahi-sys"]
beta = []
default = ["avahi", "sound", "metal"]
metal = []
sound = []
unstable = ["patch-db/unstable"]
[dependencies]
aes = { version = "0.7.5", features = ["ctr"] }
async-trait = "0.1.51"
avahi-sys = { git = "https://github.com/Start9Labs/avahi-sys", version = "0.10.0", branch = "feature/dynamic-linking", features = [
"dynamic",
], optional = true }
base32 = "0.4.0"
base64 = "0.13.0"
basic-cookies = "0.1.4"
bollard = "0.11.0"
chrono = { version = "0.4.19", features = ["serde"] }
clap = "2.33"
color-eyre = "0.5"
cookie_store = "0.15.0"
digest = "0.9.0"
divrem = "1.0.0"
ed25519-dalek = { version = "1.0.1", features = ["serde"] }
emver = { version = "0.1.6", features = ["serde"] }
fd-lock-rs = "0.1.3"
futures = "0.3.17"
git-version = "0.3.5"
hex = "0.4.3"
hmac = "0.11.0"
http = "0.2.5"
hyper = "0.14.13"
hyper-ws-listener = { git = "https://github.com/Start9Labs/hyper-ws-listener.git", branch = "main" }
imbl = "1.0.1"
indexmap = { version = "1.7.0", features = ["serde"] }
isocountry = "0.3.2"
itertools = "0.10.1"
jsonpath_lib = "0.3.0"
lazy_static = "1.4"
libc = "0.2.103"
log = "0.4.14"
nix = "0.23.0"
nom = "7.0.0"
num = "0.4.0"
num_enum = "0.5.4"
openssh-keys = "0.5.0"
openssl = { version = "0.10.36", features = ["vendored"] }
patch-db = { version = "*", path = "../patch-db/patch-db", features = [
"trace",
] }
pbkdf2 = "0.9.0"
pin-project = "1.0.8"
platforms = "1.1.0"
prettytable-rs = "0.8.0"
proptest = "1.0.0"
proptest-derive = "0.3.0"
rand = "0.7.3"
regex = "1.5.4"
reqwest = { version = "0.11.4", features = ["stream", "json", "socks"] }
reqwest_cookie_store = "0.2.0"
rpassword = "5.0.1"
rpc-toolkit = { version = "*", path = "../rpc-toolkit/rpc-toolkit" }
rust-argon2 = "0.8.3"
scopeguard = "1.1" # because avahi-sys fucks your shit up
serde = { version = "1.0.130", features = ["derive", "rc"] }
serde_cbor = { package = "ciborium", version = "0.2.0" }
serde_json = "1.0.68"
serde_toml = { package = "toml", version = "0.5.8" }
serde_yaml = "0.8.21"
sha2 = "0.9.8"
simple-logging = "2.0"
sqlx = { version = "0.5.11", features = [
"chrono",
"offline",
"runtime-tokio-rustls",
"sqlite",
] }
stderrlog = "0.5.1"
tar = "0.4.37"
thiserror = "1.0.29"
tokio = { version = "1.15.0", features = ["full"] }
tokio-compat-02 = "0.2.0"
tokio-stream = { version = "0.1.7", features = ["io-util", "sync"] }
tokio-tar = { git = "https://github.com/dr-bonez/tokio-tar.git" }
tokio-tungstenite = "0.14.0"
tokio-util = { version = "0.6.8", features = ["io"] }
torut = "0.2.0"
tracing = "0.1"
tracing-error = "0.1"
tracing-futures = "0.2"
tracing-subscriber = "0.2"
typed-builder = "0.9.1"
url = { version = "2.2.2", features = ["serde"] }
[dependencies.serde_with]
features = ["macros", "json"]
version = "1.10.0"
[profile.dev.package.backtrace]
opt-level = 3

View File

@@ -1,35 +0,0 @@
# EmbassyOS Backend
- Requirements:
- [Install Rust](https://rustup.rs)
- Recommended: [rust-analyzer](https://rust-analyzer.github.io/)
- [Docker](https://docs.docker.com/get-docker/)
- [Rust ARM64 Build Container](https://github.com/Start9Labs/rust-arm-builder)
- Scripts (run withing the `./backend` directory)
- `build-prod.sh` - compiles a release build of the artifacts for running on ARM64
- `build-dev.sh` - compiles a development build of the artifacts for running on ARM64
- A Linux computer or VM
## Structure
The EmbassyOS backend is broken up into 4 different binaries:
- embassyd: This is the main workhorse of EmbassyOS - any new functionality you want will likely go here
- embassy-init: This is the component responsible for allowing you to set up your device, and handles system initialization on startup
- embassy-cli: This is a CLI tool that will allow you to issue commands to embassyd and control it similarly to the UI
- embassy-sdk: This is a CLI tool that aids in building and packaging services you wish to deploy to the Embassy
Finally there is a library `embassy` that supports all four of these tools.
See [here](/backend/Cargo.toml) for details.
## Building
You can build the entire operating system image using `make` from the root of the EmbassyOS project. This will subsequently invoke the build scripts above to actually create the requisite binaries and put them onto the final operating system image.
## Questions
If you have questions about how various pieces of the backend system work. Open an issue and tag the following people
- dr-bonez
- ProofOfKeags

View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -e
shopt -s expand_aliases
if [ "$0" != "./build-dev.sh" ]; then
>&2 echo "Must be run from backend directory"
exit 1
fi
alias 'rust-arm64-builder'='docker run --rm -it -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src start9/rust-arm-cross:aarch64'
cd ..
rust-arm64-builder sh -c "(cd backend && cargo build)"
cd backend
#rust-arm64-builder aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/embassyd

View File

@@ -1,15 +0,0 @@
#!/bin/bash
set -e
shopt -s expand_aliases
if [ "$0" != "./build-portable-dev.sh" ]; then
>&2 echo "Must be run from backend directory"
exit 1
fi
alias 'rust-musl-builder'='docker run --rm -it -v "$HOME"/.cargo/registry:/root/.cargo/registry -v "$(pwd)":/home/rust/src start9/rust-musl-cross:x86_64-musl'
cd ..
rust-musl-builder sh -c "(cd backend && cargo +beta build --target=x86_64-unknown-linux-musl --no-default-features)"
cd backend

View File

@@ -1,15 +0,0 @@
#!/bin/bash
set -e
shopt -s expand_aliases
if [ "$0" != "./build-portable.sh" ]; then
>&2 echo "Must be run from backend directory"
exit 1
fi
alias 'rust-musl-builder'='docker run --rm -it -v "$HOME"/.cargo/registry:/root/.cargo/registry -v "$(pwd)":/home/rust/src start9/rust-musl-cross:x86_64-musl'
cd ..
rust-musl-builder sh -c "(cd backend && cargo +beta build --release --target=x86_64-unknown-linux-musl --no-default-features)"
cd backend

View File

@@ -1,28 +0,0 @@
#!/bin/bash
set -e
shopt -s expand_aliases
if [ "$0" != "./build-prod.sh" ]; then
>&2 echo "Must be run from backend directory"
exit 1
fi
alias 'rust-arm64-builder'='docker run --rm -it -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src start9/rust-arm-cross:aarch64'
cd ..
if [[ "$ENVIRONMENT" =~ (^|-)unstable($|-) ]]; then
if [[ "$ENVIRONMENT" =~ (^|-)beta($|-) ]]; then
rust-arm64-builder sh -c "(cd backend && cargo build --release --features beta,unstable)"
else
rust-arm64-builder sh -c "(cd backend && cargo build --release --features unstable)"
fi
else
if [[ "$ENVIRONMENT" =~ (^|-)beta($|-) ]]; then
rust-arm64-builder sh -c "(cd backend && cargo build --release --features beta)"
else
rust-arm64-builder sh -c "(cd backend && cargo build --release)"
fi
fi
cd backend
#rust-arm64-builder aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/embassyd

View File

@@ -1,12 +0,0 @@
#!/bin/bash
# Enter the backend directory, copy over the built EmbassyOS binaries and systemd services, edit the nginx config, then create the .ssh directory
cp target/aarch64-unknown-linux-gnu/release/embassy-init /mnt/usr/local/bin
cp target/aarch64-unknown-linux-gnu/release/embassyd /mnt/usr/local/bin
cp target/aarch64-unknown-linux-gnu/release/embassy-cli /mnt/usr/local/bin
cp *.service /mnt/etc/systemd/system/
echo "application/wasm wasm;" | sudo tee -a "/mnt/etc/nginx/mime.types"
mkdir -p /mnt/root/.ssh

View File

@@ -1,14 +0,0 @@
[Unit]
Description=Embassy Init
After=network.target
Requires=network.target
Wants=avahi-daemon.service nginx.service tor.service
[Service]
Type=oneshot
Environment=RUST_LOG=embassy_init=debug,embassy=debug
ExecStart=/usr/local/bin/embassy-init
RemainAfterExit=true
[Install]
WantedBy=embassyd.service

View File

@@ -1,14 +0,0 @@
[Unit]
Description=Embassy Daemon
After=embassy-init.service
Requires=embassy-init.service
[Service]
Type=simple
Environment=RUST_LOG=embassyd=debug,embassy=debug
ExecStart=/usr/local/bin/embassyd
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

View File

@@ -1,11 +0,0 @@
#!/bin/bash
set -e
shopt -s expand_aliases
if [ "$0" != "./install-sdk.sh" ]; then
>&2 echo "Must be run from backend directory"
exit 1
fi
cargo install --bin=embassy-sdk --path=. --no-default-features

View File

@@ -1,58 +0,0 @@
-- Add migration script here
CREATE TABLE IF NOT EXISTS tor
(
package TEXT NOT NULL,
interface TEXT NOT NULL,
key BLOB NOT NULL CHECK (length(key) = 64),
PRIMARY KEY (package, interface)
);
CREATE TABLE IF NOT EXISTS session
(
id TEXT NOT NULL PRIMARY KEY,
logged_in TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
logged_out TIMESTAMP,
last_active TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_agent TEXT,
metadata TEXT NOT NULL DEFAULT 'null'
);
CREATE TABLE IF NOT EXISTS account
(
id INTEGER PRIMARY KEY CHECK (id = 0),
password TEXT NOT NULL,
tor_key BLOB NOT NULL CHECK (length(tor_key) = 64)
);
CREATE TABLE IF NOT EXISTS ssh_keys
(
fingerprint TEXT NOT NULL,
openssh_pubkey TEXT NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY (fingerprint)
);
CREATE TABLE IF NOT EXISTS certificates
(
id INTEGER PRIMARY KEY, -- Root = 0, Int = 1, Other = 2..
priv_key_pem TEXT NOT NULL,
certificate_pem TEXT NOT NULL,
lookup_string TEXT UNIQUE,
created_at TEXT,
updated_at TEXT
);
CREATE TABLE IF NOT EXISTS notifications
(
id INTEGER PRIMARY KEY,
package_id TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
code INTEGER NOT NULL,
level TEXT NOT NULL,
title TEXT NOT NULL,
message TEXT NOT NULL,
data TEXT
);
CREATE TABLE IF NOT EXISTS cifs_shares
(
id INTEGER PRIMARY KEY,
hostname TEXT NOT NULL,
path TEXT NOT NULL,
username TEXT NOT NULL,
password TEXT
);

View File

@@ -1,695 +0,0 @@
{
"db": "SQLite",
"10350f5a16f1b2a6ce91672ae5dc6acc46691bd8f901861545ec83c326a8ccef": {
"query": "INSERT INTO ssh_keys (fingerprint, openssh_pubkey, created_at) VALUES (?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"118d59de5cf930d5a3b5667b2220e9a3d593bd84276beb2b76c93b2694b0fd72": {
"query": "INSERT INTO session (id, user_agent, metadata) VALUES (?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"165daa7d6a60cb42122373b2c5ac7d39399bcc99992f0002ee7bfef50a8daceb": {
"query": "DELETE FROM certificates WHERE id = 0 OR id = 1;",
"describe": {
"columns": [],
"parameters": {
"Right": 0
},
"nullable": []
}
},
"177c4b9cc7901a3b906e5969b86b1c11e6acbfb8e86e98f197d7333030b17964": {
"query": "DELETE FROM notifications WHERE id = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"1b2242afa55e730b37b00929b656d80940b457ec86c234ddd0de917bd8872611": {
"query": "INSERT INTO cifs_shares (hostname, path, username, password) VALUES (?, ?, ?, ?) RETURNING id AS \"id: u32\"",
"describe": {
"columns": [
{
"name": "id: u32",
"ordinal": 0,
"type_info": "Null"
}
],
"parameters": {
"Right": 4
},
"nullable": [
false
]
}
},
"1eee1fdc793919c391008854407143d7a11b4668486c11a760b49af49992f9f8": {
"query": "REPLACE INTO tor (package, interface, key) VALUES (?, 'main', ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
}
},
"3502e58f2ab48fb4566d21c920c096f81acfa3ff0d02f970626a4dcd67bac71d": {
"query": "SELECT tor_key FROM account",
"describe": {
"columns": [
{
"name": "tor_key",
"ordinal": 0,
"type_info": "Blob"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false
]
}
},
"3e57a0e52b69f33e9411c13b03a5d82c5856d63f0375eb4c23b255a09c54f8b1": {
"query": "SELECT key FROM tor WHERE package = ? AND interface = ?",
"describe": {
"columns": [
{
"name": "key",
"ordinal": 0,
"type_info": "Blob"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false
]
}
},
"4691e3a2ce80b59009ac17124f54f925f61dc5ea371903e62cdffa5d7b67ca96": {
"query": "SELECT * FROM session WHERE logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "logged_in",
"ordinal": 1,
"type_info": "Datetime"
},
{
"name": "logged_out",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "last_active",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "user_agent",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "metadata",
"ordinal": 5,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
true,
false,
true,
false
]
}
},
"530192a2a530ee6b92e5b98e1eb1bf6d1426c7b0cb2578593a367cb0bf2c3ca8": {
"query": "UPDATE certificates SET priv_key_pem = ?, certificate_pem = ?, updated_at = datetime('now') WHERE lookup_string = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"56b986f2a2b7091d9c3acdd78f75d9842242de1f4da8f3672f2793d9fb256928": {
"query": "DELETE FROM tor WHERE package = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"5b114c450073f77f466c980a2541293f30087b57301c379630326e5e5c2fb792": {
"query": "REPLACE INTO tor (package, interface, key) VALUES (?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"5c47da44b9c84468e95a13fc47301989900f130b3b5899d1ee6664df3ed812ac": {
"query": "INSERT INTO certificates (id, priv_key_pem, certificate_pem, lookup_string, created_at, updated_at) VALUES (0, ?, ?, NULL, datetime('now'), datetime('now'))",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
}
},
"629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a": {
"query": "SELECT password FROM account",
"describe": {
"columns": [
{
"name": "password",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false
]
}
},
"63785dc5f193ea31e6f641a910c75857ccd288a3f6e9c4f704331531e4f0689f": {
"query": "UPDATE session SET last_active = CURRENT_TIMESTAMP WHERE id = ? AND logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"6440354d73a67c041ea29508b43b5f309d45837a44f1a562051ad540d894c7d6": {
"query": "DELETE FROM ssh_keys WHERE fingerprint = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"65e6c3fbb138da5cf385af096fdd3c062b6e826e12a8a4b23e16fcc773004c29": {
"query": "SELECT id, package_id, created_at, code, level, title, message, data FROM notifications WHERE id < ? ORDER BY id DESC LIMIT ?",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "package_id",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "code",
"ordinal": 3,
"type_info": "Int64"
},
{
"name": "level",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "title",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "message",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "data",
"ordinal": 7,
"type_info": "Text"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
true,
false,
false,
false,
false,
false,
true
]
}
},
"668f39c868f90cdbcc635858bac9e55ed73192ed2aec5c52dcfba9800a7a4a41": {
"query": "SELECT id AS \"id: u32\", hostname, path, username, password FROM cifs_shares",
"describe": {
"columns": [
{
"name": "id: u32",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "hostname",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "path",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "username",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "password",
"ordinal": 4,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
true
]
}
},
"6b9abc9e079cff975f8a7f07ff70548c7877ecae3be0d0f2d3f439a6713326c0": {
"query": "DELETE FROM notifications WHERE id < ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
},
"6c96d76bffcc5f03290d8d8544a58521345ed2a843a509b17bbcd6257bb81821": {
"query": "SELECT priv_key_pem, certificate_pem FROM certificates WHERE id = 1;",
"describe": {
"columns": [
{
"name": "priv_key_pem",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "certificate_pem",
"ordinal": 1,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false
]
}
},
"7d548d2472fa3707bd17364b4800e229b9c2b1c0a22e245bf4e635b9b16b8c24": {
"query": "INSERT INTO certificates (priv_key_pem, certificate_pem, lookup_string, created_at, updated_at) VALUES (?, ?, ?, datetime('now'), datetime('now'))",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"8595651866e7db772260bd79e19d55b7271fd795b82a99821c935a9237c1aa16": {
"query": "SELECT interface, key FROM tor WHERE package = ?",
"describe": {
"columns": [
{
"name": "interface",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "key",
"ordinal": 1,
"type_info": "Blob"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false
]
}
},
"9496e17a73672ac3675e02efa7c4bf8bd479b866c0d31fa1e3a85ef159310a57": {
"query": "SELECT priv_key_pem, certificate_pem FROM certificates WHERE lookup_string = ?",
"describe": {
"columns": [
{
"name": "priv_key_pem",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "certificate_pem",
"ordinal": 1,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false
]
}
},
"9fcedab1ba34daa2c6ae97c5953c09821b35b55be75b0c66045ab31a2cf4553e": {
"query": "REPLACE INTO account (id, password, tor_key) VALUES (?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"a1cbaac36d8e14c8c3e7276237c4824bff18861f91b0b08aa5791704c492acb7": {
"query": "INSERT INTO certificates (id, priv_key_pem, certificate_pem, lookup_string, created_at, updated_at) VALUES (1, ?, ?, NULL, datetime('now'), datetime('now'))",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
}
},
"a4e7162322b28508310b9de7ebc891e619b881ff6d3ea09eba13da39626ab12f": {
"query": "UPDATE cifs_shares SET hostname = ?, path = ?, username = ?, password = ? WHERE id = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
}
},
"a6b0c8909a3a5d6d9156aebfb359424e6b5a1d1402e028219e21726f1ebd282e": {
"query": "SELECT fingerprint, openssh_pubkey, created_at FROM ssh_keys",
"describe": {
"columns": [
{
"name": "fingerprint",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "openssh_pubkey",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false
]
}
},
"abfdeea8cd10343b85f647d7abc5dc3bd0b5891101b143485938192ee3b8c907": {
"query": "SELECT id, package_id, created_at, code, level, title, message, data FROM notifications ORDER BY id DESC LIMIT ?",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
},
{
"name": "package_id",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "code",
"ordinal": 3,
"type_info": "Int64"
},
{
"name": "level",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "title",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "message",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "data",
"ordinal": 7,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
true,
false,
false,
false,
false,
false,
true
]
}
},
"b376d9e77e0861a9af2d1081ca48d14e83abc5a1546213d15bb570972c403beb": {
"query": "-- Add migration script here\nCREATE TABLE IF NOT EXISTS tor\n(\n package TEXT NOT NULL,\n interface TEXT NOT NULL,\n key BLOB NOT NULL CHECK (length(key) = 64),\n PRIMARY KEY (package, interface)\n);\nCREATE TABLE IF NOT EXISTS session\n(\n id TEXT NOT NULL PRIMARY KEY,\n logged_in TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n logged_out TIMESTAMP,\n last_active TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n user_agent TEXT,\n metadata TEXT NOT NULL DEFAULT 'null'\n);\nCREATE TABLE IF NOT EXISTS account\n(\n id INTEGER PRIMARY KEY CHECK (id = 0),\n password TEXT NOT NULL,\n tor_key BLOB NOT NULL CHECK (length(tor_key) = 64)\n);\nCREATE TABLE IF NOT EXISTS ssh_keys\n(\n fingerprint TEXT NOT NULL,\n openssh_pubkey TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY (fingerprint)\n);\nCREATE TABLE IF NOT EXISTS certificates\n(\n id INTEGER PRIMARY KEY, -- Root = 0, Int = 1, Other = 2..\n priv_key_pem TEXT NOT NULL,\n certificate_pem TEXT NOT NULL,\n lookup_string TEXT UNIQUE,\n created_at TEXT,\n updated_at TEXT\n);\nCREATE TABLE IF NOT EXISTS notifications\n(\n id INTEGER PRIMARY KEY,\n package_id TEXT,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n code INTEGER NOT NULL,\n level TEXT NOT NULL,\n title TEXT NOT NULL,\n message TEXT NOT NULL,\n data TEXT\n);\nCREATE TABLE IF NOT EXISTS cifs_shares\n(\n id INTEGER PRIMARY KEY,\n hostname TEXT NOT NULL,\n path TEXT NOT NULL,\n username TEXT NOT NULL,\n password TEXT\n);",
"describe": {
"columns": [],
"parameters": {
"Right": 0
},
"nullable": []
}
},
"cc33fe2958fe7caeac6999a217f918a68b45ad596664170b4d07671c6ea49566": {
"query": "SELECT hostname, path, username, password FROM cifs_shares WHERE id = ?",
"describe": {
"columns": [
{
"name": "hostname",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "path",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "username",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "password",
"ordinal": 3,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true
]
}
},
"d5117054072476377f3c4f040ea429d4c9b2cf534e76f35c80a2bf60e8599cca": {
"query": "SELECT openssh_pubkey FROM ssh_keys",
"describe": {
"columns": [
{
"name": "openssh_pubkey",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false
]
}
},
"d54bd5b53f8c760e1f8cde604aa8b1bdc66e4e025a636bc44ffbcd788b5168fd": {
"query": "INSERT INTO notifications (package_id, code, level, title, message, data) VALUES (?, ?, ?, ?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 6
},
"nullable": []
}
},
"d79d608ceb862c15b741a6040044c6dd54a837a3a0c5594d15a6041c7bc68ea8": {
"query": "INSERT OR IGNORE INTO tor (package, interface, key) VALUES (?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
}
},
"de2a5e90798d606047ab8180c044baac05469c0cdf151316bd58ee8c7196fdef": {
"query": "SELECT * FROM ssh_keys WHERE fingerprint = ?",
"describe": {
"columns": [
{
"name": "fingerprint",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "openssh_pubkey",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false
]
}
},
"ed848affa5bf92997cd441e3a50b3616b6724df3884bd9d199b3225e0bea8a54": {
"query": "SELECT priv_key_pem, certificate_pem FROM certificates WHERE id = 0;",
"describe": {
"columns": [
{
"name": "priv_key_pem",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "certificate_pem",
"ordinal": 1,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false
]
}
},
"f63c8c5a8754b34a49ef5d67802fa2b72aa409bbec92ecc6901492092974b71a": {
"query": "DELETE FROM cifs_shares WHERE id = ?",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
}
}
}

View File

@@ -1,354 +0,0 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::{OsStr, OsString};
use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::time::Duration;
use bollard::container::RemoveContainerOptions;
use futures::future::Either as EitherFuture;
use nix::sys::signal;
use nix::unistd::Pid;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tracing::instrument;
use crate::context::RpcContext;
use crate::id::{Id, ImageId};
use crate::s9pk::manifest::{PackageId, SYSTEM_PACKAGE_ID};
use crate::util::serde::{Duration as SerdeDuration, IoFormat};
use crate::util::Version;
use crate::volume::{VolumeId, Volumes};
use crate::{Error, ResultExt, HOST_IP};
pub const NET_TLD: &str = "embassy";
lazy_static::lazy_static! {
pub static ref SYSTEM_IMAGES: BTreeSet<ImageId> = {
let mut set = BTreeSet::new();
set.insert("compat".parse().unwrap());
set.insert("utils".parse().unwrap());
set
};
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct DockerAction {
pub image: ImageId,
#[serde(default)]
pub system: bool,
pub entrypoint: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub mounts: BTreeMap<VolumeId, PathBuf>,
#[serde(default)]
pub io_format: Option<IoFormat>,
#[serde(default)]
pub inject: bool,
#[serde(default)]
pub shm_size_mb: Option<usize>, // TODO: use postfix sizing? like 1k vs 1m vs 1g
#[serde(default)]
pub sigterm_timeout: Option<SerdeDuration>,
}
impl DockerAction {
pub fn validate(
&self,
volumes: &Volumes,
image_ids: &BTreeSet<ImageId>,
expected_io: bool,
) -> Result<(), color_eyre::eyre::Report> {
for (volume, _) in &self.mounts {
if !volumes.contains_key(volume) && !matches!(&volume, &VolumeId::Backup) {
color_eyre::eyre::bail!("unknown volume: {}", volume);
}
}
if self.system {
if !SYSTEM_IMAGES.contains(&self.image) {
color_eyre::eyre::bail!("unknown system image: {}", self.image);
}
} else {
if !image_ids.contains(&self.image) {
color_eyre::eyre::bail!("image for {} not contained in package", self.image);
}
}
if expected_io && self.io_format.is_none() {
color_eyre::eyre::bail!("expected io-format");
}
Ok(())
}
#[instrument(skip(ctx, input))]
pub async fn execute<I: Serialize, O: for<'de> Deserialize<'de>>(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
name: Option<&str>,
volumes: &Volumes,
input: Option<I>,
allow_inject: bool,
timeout: Option<Duration>,
) -> Result<Result<O, (i32, String)>, Error> {
let mut cmd = tokio::process::Command::new("docker");
if self.inject && allow_inject {
cmd.arg("exec");
} else {
let container_name = Self::container_name(pkg_id, name);
cmd.arg("run")
.arg("--rm")
.arg("--network=start9")
.arg(format!("--add-host=embassy:{}", Ipv4Addr::from(HOST_IP)))
.arg("--name")
.arg(&container_name)
.arg(format!("--hostname={}", &container_name))
.arg("--no-healthcheck");
match ctx
.docker
.remove_container(
&container_name,
Some(RemoveContainerOptions {
v: false,
force: true,
link: false,
}),
)
.await
{
Ok(()) | Err(bollard::errors::Error::DockerResponseNotFoundError { .. }) => Ok(()),
Err(e) => Err(e),
}?;
}
cmd.args(
self.docker_args(ctx, pkg_id, pkg_version, volumes, allow_inject)
.await,
);
let input_buf = if let (Some(input), Some(format)) = (&input, &self.io_format) {
cmd.stdin(std::process::Stdio::piped());
Some(format.to_vec(input)?)
} else {
None
};
cmd.stdout(std::process::Stdio::piped());
cmd.stderr(std::process::Stdio::piped());
tracing::trace!(
"{}",
format!("{:?}", cmd)
.split(r#"" ""#)
.collect::<Vec<&str>>()
.join(" ")
);
let mut handle = cmd.spawn().with_kind(crate::ErrorKind::Docker)?;
let id = handle.id();
let timeout_fut = if let Some(timeout) = timeout {
EitherFuture::Right(async move {
tokio::time::sleep(timeout).await;
Ok(())
})
} else {
EitherFuture::Left(futures::future::pending::<Result<_, Error>>())
};
if let (Some(input), Some(mut stdin)) = (&input_buf, handle.stdin.take()) {
use tokio::io::AsyncWriteExt;
stdin
.write_all(input)
.await
.with_kind(crate::ErrorKind::Docker)?;
stdin.flush().await?;
stdin.shutdown().await?;
drop(stdin);
}
enum Race<T> {
Done(T),
TimedOut,
}
let res = tokio::select! {
res = handle.wait_with_output() => Race::Done(res.with_kind(crate::ErrorKind::Docker)?),
res = timeout_fut => {
res?;
Race::TimedOut
},
};
let res = match res {
Race::Done(x) => x,
Race::TimedOut => {
if let Some(id) = id {
signal::kill(Pid::from_raw(id as i32), signal::SIGKILL)
.with_kind(crate::ErrorKind::Docker)?;
}
return Ok(Err((143, "Timed out. Retrying soon...".to_owned())));
}
};
Ok(if res.status.success() || res.status.code() == Some(143) {
Ok(if let Some(format) = self.io_format {
match format.from_slice(&res.stdout) {
Ok(a) => a,
Err(e) => {
tracing::warn!(
"Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.",
format,
e
);
serde_json::from_value(String::from_utf8(res.stdout)?.into())
.with_kind(crate::ErrorKind::Deserialization)?
}
}
} else if res.stdout.is_empty() {
serde_json::from_value(Value::Null).with_kind(crate::ErrorKind::Deserialization)?
} else {
serde_json::from_value(String::from_utf8(res.stdout)?.into())
.with_kind(crate::ErrorKind::Deserialization)?
})
} else {
Err((
res.status.code().unwrap_or_default(),
String::from_utf8(res.stderr)?,
))
})
}
#[instrument(skip(ctx, input))]
pub async fn sandboxed<I: Serialize, O: for<'de> Deserialize<'de>>(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
volumes: &Volumes,
input: Option<I>,
timeout: Option<Duration>,
) -> Result<Result<O, (i32, String)>, Error> {
let mut cmd = tokio::process::Command::new("docker");
cmd.arg("run").arg("--rm").arg("--network=none");
cmd.args(
self.docker_args(ctx, pkg_id, pkg_version, &volumes.to_readonly(), false)
.await,
);
let input_buf = if let (Some(input), Some(format)) = (&input, &self.io_format) {
cmd.stdin(std::process::Stdio::piped());
Some(format.to_vec(input)?)
} else {
None
};
cmd.stdout(std::process::Stdio::piped());
cmd.stderr(std::process::Stdio::piped());
let mut handle = cmd.spawn().with_kind(crate::ErrorKind::Docker)?;
if let (Some(input), Some(stdin)) = (&input_buf, &mut handle.stdin) {
use tokio::io::AsyncWriteExt;
stdin
.write_all(input)
.await
.with_kind(crate::ErrorKind::Docker)?;
}
let res = handle
.wait_with_output()
.await
.with_kind(crate::ErrorKind::Docker)?;
Ok(if res.status.success() || res.status.code() == Some(143) {
Ok(if let Some(format) = &self.io_format {
match format.from_slice(&res.stdout) {
Ok(a) => a,
Err(e) => {
tracing::warn!(
"Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.",
format,
e
);
serde_json::from_value(String::from_utf8(res.stdout)?.into())
.with_kind(crate::ErrorKind::Deserialization)?
}
}
} else if res.stdout.is_empty() {
serde_json::from_value(Value::Null).with_kind(crate::ErrorKind::Deserialization)?
} else {
serde_json::from_value(String::from_utf8(res.stdout)?.into())
.with_kind(crate::ErrorKind::Deserialization)?
})
} else {
Err((
res.status.code().unwrap_or_default(),
String::from_utf8(res.stderr)?,
))
})
}
pub fn container_name(pkg_id: &PackageId, name: Option<&str>) -> String {
if let Some(name) = name {
format!("{}_{}.{}", pkg_id, name, NET_TLD)
} else {
format!("{}.{}", pkg_id, NET_TLD)
}
}
pub fn uncontainer_name(name: &str) -> Option<(PackageId<&str>, Option<&str>)> {
let (pre_tld, _) = name.split_once(".")?;
if pre_tld.contains('_') {
let (pkg, name) = name.split_once("_")?;
Some((Id::try_from(pkg).ok()?.into(), Some(name)))
} else {
Some((Id::try_from(pre_tld).ok()?.into(), None))
}
}
async fn docker_args(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
volumes: &Volumes,
allow_inject: bool,
) -> Vec<Cow<'_, OsStr>> {
let mut res = Vec::with_capacity(
(2 * self.mounts.len()) // --mount <MOUNT_ARG>
+ (2 * self.shm_size_mb.is_some() as usize) // --shm-size <SHM_SIZE>
+ 5 // --interactive --log-driver=journald --entrypoint <ENTRYPOINT> <IMAGE>
+ self.args.len(), // [ARG...]
);
for (volume_id, dst) in &self.mounts {
let volume = if let Some(v) = volumes.get(volume_id) {
v
} else {
continue;
};
let src = volume.path_for(ctx, pkg_id, pkg_version, volume_id);
if let Err(e) = tokio::fs::metadata(&src).await {
tracing::warn!("{} not mounted to container: {}", src.display(), e);
continue;
}
res.push(OsStr::new("--mount").into());
res.push(
OsString::from(format!(
"type=bind,src={},dst={}{}",
src.display(),
dst.display(),
if volume.readonly() { ",readonly" } else { "" }
))
.into(),
);
}
if let Some(shm_size_mb) = self.shm_size_mb {
res.push(OsStr::new("--shm-size").into());
res.push(OsString::from(format!("{}m", shm_size_mb)).into());
}
res.push(OsStr::new("--interactive").into());
if self.inject && allow_inject {
res.push(OsString::from(Self::container_name(pkg_id, None)).into());
res.push(OsStr::new(&self.entrypoint).into());
} else {
res.push(OsStr::new("--log-driver=journald").into());
res.push(OsStr::new("--entrypoint").into());
res.push(OsStr::new(&self.entrypoint).into());
if self.system {
res.push(OsString::from(self.image.for_package(SYSTEM_PACKAGE_ID, None)).into());
} else {
res.push(OsString::from(self.image.for_package(pkg_id, Some(pkg_version))).into());
}
}
res.extend(self.args.iter().map(|s| OsStr::new(s).into()));
res
}
}

View File

@@ -1,290 +0,0 @@
use std::collections::{BTreeMap, BTreeSet};
use std::path::Path;
use std::str::FromStr;
use std::time::Duration;
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use indexmap::IndexSet;
use patch_db::HasModel;
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use self::docker::DockerAction;
use crate::config::{Config, ConfigSpec};
use crate::context::RpcContext;
use crate::id::{Id, ImageId, InvalidId};
use crate::s9pk::manifest::PackageId;
use crate::util::serde::{display_serializable, parse_stdin_deserializable, IoFormat};
use crate::util::Version;
use crate::volume::Volumes;
use crate::{Error, ResultExt};
pub mod docker;
// TODO: create RPC endpoint that looks up the appropriate action and calls `execute`
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct ActionId<S: AsRef<str> = String>(Id<S>);
impl FromStr for ActionId {
type Err = InvalidId;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(ActionId(Id::try_from(s.to_owned())?))
}
}
impl From<ActionId> for String {
fn from(value: ActionId) -> Self {
value.0.into()
}
}
impl<S: AsRef<str>> AsRef<ActionId<S>> for ActionId<S> {
fn as_ref(&self) -> &ActionId<S> {
self
}
}
impl<S: AsRef<str>> std::fmt::Display for ActionId<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.0)
}
}
impl<S: AsRef<str>> AsRef<str> for ActionId<S> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<S: AsRef<str>> AsRef<Path> for ActionId<S> {
fn as_ref(&self) -> &Path {
self.0.as_ref().as_ref()
}
}
impl<'de, S> Deserialize<'de> for ActionId<S>
where
S: AsRef<str>,
Id<S>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(ActionId(Deserialize::deserialize(deserializer)?))
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Actions(pub BTreeMap<ActionId, Action>);
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "version")]
pub enum ActionResult {
#[serde(rename = "0")]
V0(ActionResultV0),
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ActionResultV0 {
pub message: String,
pub value: Option<String>,
pub copyable: bool,
pub qr: bool,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum DockerStatus {
Running,
Stopped,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Action {
pub name: String,
pub description: String,
#[serde(default)]
pub warning: Option<String>,
pub implementation: ActionImplementation,
pub allowed_statuses: IndexSet<DockerStatus>,
#[serde(default)]
pub input_spec: ConfigSpec,
}
impl Action {
#[instrument]
pub fn validate(&self, volumes: &Volumes, image_ids: &BTreeSet<ImageId>) -> Result<(), Error> {
self.implementation
.validate(volumes, image_ids, true)
.with_ctx(|_| {
(
crate::ErrorKind::ValidateS9pk,
format!("Action {}", self.name),
)
})
}
#[instrument(skip(ctx))]
pub async fn execute(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
action_id: &ActionId,
volumes: &Volumes,
input: Option<Config>,
) -> Result<ActionResult, Error> {
if let Some(ref input) = input {
self.input_spec
.matches(&input)
.with_kind(crate::ErrorKind::ConfigSpecViolation)?;
}
self.implementation
.execute(
ctx,
pkg_id,
pkg_version,
Some(&format!("{}Action", action_id)),
volumes,
input,
true,
None,
)
.await?
.map_err(|e| Error::new(eyre!("{}", e.1), crate::ErrorKind::Action))
}
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
#[serde(tag = "type")]
pub enum ActionImplementation {
Docker(DockerAction),
}
impl ActionImplementation {
#[instrument]
pub fn validate(
&self,
volumes: &Volumes,
image_ids: &BTreeSet<ImageId>,
expected_io: bool,
) -> Result<(), color_eyre::eyre::Report> {
match self {
ActionImplementation::Docker(action) => {
action.validate(volumes, image_ids, expected_io)
}
}
}
#[instrument(skip(ctx, input))]
pub async fn execute<I: Serialize, O: for<'de> Deserialize<'de>>(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
name: Option<&str>,
volumes: &Volumes,
input: Option<I>,
allow_inject: bool,
timeout: Option<Duration>,
) -> Result<Result<O, (i32, String)>, Error> {
match self {
ActionImplementation::Docker(action) => {
action
.execute(
ctx,
pkg_id,
pkg_version,
name,
volumes,
input,
allow_inject,
timeout,
)
.await
}
}
}
#[instrument(skip(ctx, input))]
pub async fn sandboxed<I: Serialize, O: for<'de> Deserialize<'de>>(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
volumes: &Volumes,
input: Option<I>,
timeout: Option<Duration>,
) -> Result<Result<O, (i32, String)>, Error> {
match self {
ActionImplementation::Docker(action) => {
action
.sandboxed(ctx, pkg_id, pkg_version, volumes, input, timeout)
.await
}
}
}
}
fn display_action_result(action_result: ActionResult, matches: &ArgMatches<'_>) {
if matches.is_present("format") {
return display_serializable(action_result, matches);
}
match action_result {
ActionResult::V0(ar) => {
println!(
"{}: {}",
ar.message,
serde_json::to_string(&ar.value).unwrap()
);
}
}
}
#[command(about = "Executes an action", display(display_action_result))]
#[instrument(skip(ctx))]
pub async fn action(
#[context] ctx: RpcContext,
#[arg(rename = "id")] pkg_id: PackageId,
#[arg(rename = "action-id")] action_id: ActionId,
#[arg(stdin, parse(parse_stdin_deserializable))] input: Option<Config>,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<ActionResult, Error> {
let mut db = ctx.db.handle();
let manifest = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&pkg_id)
.and_then(|p| p.installed())
.expect(&mut db)
.await
.with_kind(crate::ErrorKind::NotFound)?
.manifest()
.get(&mut db, true)
.await?
.to_owned();
if let Some(action) = manifest.actions.0.get(&action_id) {
action
.execute(
&ctx,
&manifest.id,
&manifest.version,
&action_id,
&manifest.volumes,
input,
)
.await
} else {
Err(Error::new(
eyre!("Action not found in manifest"),
crate::ErrorKind::NotFound,
))
}
}
pub struct NoOutput;
impl<'de> Deserialize<'de> for NoOutput {
fn deserialize<D>(_: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(NoOutput)
}
}

View File

@@ -1,258 +0,0 @@
use std::collections::BTreeMap;
use std::marker::PhantomData;
use chrono::{DateTime, Utc};
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use rpc_toolkit::command;
use rpc_toolkit::command_helpers::prelude::{RequestParts, ResponseParts};
use rpc_toolkit::yajrc::RpcError;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sqlx::{Executor, Sqlite};
use tracing::instrument;
use crate::context::{CliContext, RpcContext};
use crate::middleware::auth::{AsLogoutSessionId, HasLoggedOutSessions, HashSessionToken};
use crate::util::display_none;
use crate::util::serde::{display_serializable, IoFormat};
use crate::{ensure_code, Error, ResultExt};
#[command(subcommands(login, logout, session))]
pub fn auth() -> Result<(), Error> {
Ok(())
}
pub fn parse_metadata(_: &str, _: &ArgMatches<'_>) -> Result<Value, Error> {
Ok(serde_json::json!({
"platforms": ["cli"],
}))
}
#[test]
fn gen_pwd() {
println!(
"{:?}",
argon2::hash_encoded(
b"testing1234",
&rand::random::<[u8; 16]>()[..],
&argon2::Config::default()
)
.unwrap()
)
}
#[instrument(skip(ctx, password))]
async fn cli_login(
ctx: CliContext,
password: Option<String>,
metadata: Value,
) -> Result<(), RpcError> {
let password = if let Some(password) = password {
password
} else {
rpassword::prompt_password_stdout("Password: ")?
};
rpc_toolkit::command_helpers::call_remote(
ctx,
"auth.login",
serde_json::json!({ "password": password, "metadata": metadata }),
PhantomData::<()>,
)
.await?
.result?;
Ok(())
}
pub fn check_password(hash: &str, password: &str) -> Result<(), Error> {
ensure_code!(
argon2::verify_encoded(&hash, password.as_bytes()).map_err(|_| {
Error::new(
eyre!("Password Incorrect"),
crate::ErrorKind::IncorrectPassword,
)
})?,
crate::ErrorKind::IncorrectPassword,
"Password Incorrect"
);
Ok(())
}
pub async fn check_password_against_db<Ex>(secrets: &mut Ex, password: &str) -> Result<(), Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let pw_hash = sqlx::query!("SELECT password FROM account")
.fetch_one(secrets)
.await?
.password;
check_password(&pw_hash, password)?;
Ok(())
}
#[command(
custom_cli(cli_login(async, context(CliContext))),
display(display_none),
metadata(authenticated = false)
)]
#[instrument(skip(ctx, password))]
pub async fn login(
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
#[response] res: &mut ResponseParts,
#[arg] password: Option<String>,
#[arg(
parse(parse_metadata),
default = "",
help = "RPC Only: This value cannot be overidden from the cli"
)]
metadata: Value,
) -> Result<(), Error> {
let password = password.unwrap_or_default();
let mut handle = ctx.secret_store.acquire().await?;
check_password_against_db(&mut handle, &password).await?;
let hash_token = HashSessionToken::new();
let user_agent = req.headers.get("user-agent").and_then(|h| h.to_str().ok());
let metadata = serde_json::to_string(&metadata).with_kind(crate::ErrorKind::Database)?;
let hash_token_hashed = hash_token.hashed();
sqlx::query!(
"INSERT INTO session (id, user_agent, metadata) VALUES (?, ?, ?)",
hash_token_hashed,
user_agent,
metadata,
)
.execute(&mut handle)
.await?;
res.headers.insert(
"set-cookie",
hash_token.header_value()?, // Should be impossible, but don't want to panic
);
Ok(())
}
#[command(display(display_none), metadata(authenticated = false))]
#[instrument(skip(ctx))]
pub async fn logout(
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
) -> Result<Option<HasLoggedOutSessions>, Error> {
let auth = match HashSessionToken::from_request_parts(req) {
Err(_) => return Ok(None),
Ok(a) => a,
};
Ok(Some(HasLoggedOutSessions::new(vec![auth], &ctx).await?))
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Session {
logged_in: DateTime<Utc>,
last_active: DateTime<Utc>,
user_agent: Option<String>,
metadata: Value,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct SessionList {
current: String,
sessions: BTreeMap<String, Session>,
}
#[command(subcommands(list, kill))]
pub async fn session() -> Result<(), Error> {
Ok(())
}
fn display_sessions(arg: SessionList, matches: &ArgMatches<'_>) {
use prettytable::*;
if matches.is_present("format") {
return display_serializable(arg, matches);
}
let mut table = Table::new();
table.add_row(row![bc =>
"ID",
"LOGGED IN",
"LAST ACTIVE",
"USER AGENT",
"METADATA",
]);
for (id, session) in arg.sessions {
let mut row = row![
&id,
&format!("{}", session.logged_in),
&format!("{}", session.last_active),
session.user_agent.as_deref().unwrap_or("N/A"),
&format!("{}", session.metadata),
];
if id == arg.current {
row.iter_mut()
.map(|c| c.style(Attr::ForegroundColor(color::GREEN)))
.collect::<()>()
}
table.add_row(row);
}
table.print_tty(false);
}
#[command(display(display_sessions))]
#[instrument(skip(ctx))]
pub async fn list(
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<SessionList, Error> {
Ok(SessionList {
current: HashSessionToken::from_request_parts(req)?.as_hash(),
sessions: sqlx::query!(
"SELECT * FROM session WHERE logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP"
)
.fetch_all(&mut ctx.secret_store.acquire().await?)
.await?
.into_iter()
.map(|row| {
Ok((
row.id,
Session {
logged_in: DateTime::from_utc(row.logged_in, Utc),
last_active: DateTime::from_utc(row.last_active, Utc),
user_agent: row.user_agent,
metadata: serde_json::from_str(&row.metadata)
.with_kind(crate::ErrorKind::Database)?,
},
))
})
.collect::<Result<_, Error>>()?,
})
}
fn parse_comma_separated(arg: &str, _: &ArgMatches<'_>) -> Result<Vec<String>, RpcError> {
Ok(arg.split(",").map(|s| s.trim().to_owned()).collect())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct KillSessionId(String);
impl AsLogoutSessionId for KillSessionId {
fn as_logout_session_id(self) -> String {
self.0
}
}
#[command(display(display_none))]
#[instrument(skip(ctx))]
pub async fn kill(
#[context] ctx: RpcContext,
#[arg(parse(parse_comma_separated))] ids: Vec<String>,
) -> Result<(), Error> {
HasLoggedOutSessions::new(ids.into_iter().map(KillSessionId), &ctx).await?;
Ok(())
}

View File

@@ -1,397 +0,0 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use chrono::Utc;
use color_eyre::eyre::eyre;
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use patch_db::{DbHandle, LockType, PatchDbHandle, Revision};
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::io::AsyncWriteExt;
use torut::onion::TorSecretKeyV3;
use tracing::instrument;
use super::target::BackupTargetId;
use super::PackageBackupReport;
use crate::auth::check_password_against_db;
use crate::backup::{BackupReport, ServerBackupReport};
use crate::context::RpcContext;
use crate::db::util::WithRevision;
use crate::disk::mount::backup::BackupMountGuard;
use crate::disk::mount::filesystem::ReadWrite;
use crate::disk::mount::guard::TmpMountGuard;
use crate::notifications::NotificationLevel;
use crate::s9pk::manifest::PackageId;
use crate::status::MainStatus;
use crate::util::serde::IoFormat;
use crate::util::{display_none, AtomicFile};
use crate::version::VersionT;
use crate::Error;
#[derive(Debug)]
pub struct OsBackup {
pub tor_key: TorSecretKeyV3,
pub root_ca_key: PKey<Private>,
pub root_ca_cert: X509,
pub ui: Value,
}
impl<'de> Deserialize<'de> for OsBackup {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(rename = "kebab-case")]
struct OsBackupDe {
tor_key: String,
root_ca_key: String,
root_ca_cert: String,
ui: Value,
}
let int = OsBackupDe::deserialize(deserializer)?;
let key_vec = base32::decode(base32::Alphabet::RFC4648 { padding: true }, &int.tor_key)
.ok_or_else(|| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Str(&int.tor_key),
&"an RFC4648 encoded string",
)
})?;
if key_vec.len() != 64 {
return Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(&int.tor_key),
&"a 64 byte value encoded as an RFC4648 string",
));
}
let mut key_slice = [0; 64];
key_slice.clone_from_slice(&key_vec);
Ok(OsBackup {
tor_key: TorSecretKeyV3::from(key_slice),
root_ca_key: PKey::<Private>::private_key_from_pem(int.root_ca_key.as_bytes())
.map_err(serde::de::Error::custom)?,
root_ca_cert: X509::from_pem(int.root_ca_cert.as_bytes())
.map_err(serde::de::Error::custom)?,
ui: int.ui,
})
}
}
impl Serialize for OsBackup {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
#[serde(rename = "kebab-case")]
struct OsBackupSer<'a> {
tor_key: String,
root_ca_key: String,
root_ca_cert: String,
ui: &'a Value,
}
OsBackupSer {
tor_key: base32::encode(
base32::Alphabet::RFC4648 { padding: true },
&self.tor_key.as_bytes(),
),
root_ca_key: String::from_utf8(
self.root_ca_key
.private_key_to_pem_pkcs8()
.map_err(serde::ser::Error::custom)?,
)
.map_err(serde::ser::Error::custom)?,
root_ca_cert: String::from_utf8(
self.root_ca_cert
.to_pem()
.map_err(serde::ser::Error::custom)?,
)
.map_err(serde::ser::Error::custom)?,
ui: &self.ui,
}
.serialize(serializer)
}
}
#[command(rename = "create", display(display_none))]
#[instrument(skip(ctx, old_password, password))]
pub async fn backup_all(
#[context] ctx: RpcContext,
#[arg(rename = "target-id")] target_id: BackupTargetId,
#[arg(rename = "old-password", long = "old-password")] old_password: Option<String>,
#[arg] password: String,
) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
check_password_against_db(&mut ctx.secret_store.acquire().await?, &password).await?;
let fs = target_id
.load(&mut ctx.secret_store.acquire().await?)
.await?;
let mut backup_guard = BackupMountGuard::mount(
TmpMountGuard::mount(&fs, ReadWrite).await?,
old_password.as_ref().unwrap_or(&password),
)
.await?;
if old_password.is_some() {
backup_guard.change_password(&password)?;
}
let revision = assure_backing_up(&mut db).await?;
tokio::task::spawn(async move {
let backup_res = perform_backup(&ctx, &mut db, backup_guard).await;
let status_model = crate::db::DatabaseModel::new()
.server_info()
.status_info()
.backing_up();
status_model
.clone()
.lock(&mut db, LockType::Write)
.await
.expect("failed to lock server status");
match backup_res {
Ok(report) if report.iter().all(|(_, rep)| rep.error.is_none()) => ctx
.notification_manager
.notify(
&mut db,
None,
NotificationLevel::Success,
"Backup Complete".to_owned(),
"Your backup has completed".to_owned(),
BackupReport {
server: ServerBackupReport {
attempted: true,
error: None,
},
packages: report,
},
None,
)
.await
.expect("failed to send notification"),
Ok(report) => ctx
.notification_manager
.notify(
&mut db,
None,
NotificationLevel::Warning,
"Backup Complete".to_owned(),
"Your backup has completed, but some package(s) failed to backup".to_owned(),
BackupReport {
server: ServerBackupReport {
attempted: true,
error: None,
},
packages: report,
},
None,
)
.await
.expect("failed to send notification"),
Err(e) => {
tracing::error!("Backup Failed: {}", e);
tracing::debug!("{:?}", e);
ctx.notification_manager
.notify(
&mut db,
None,
NotificationLevel::Error,
"Backup Failed".to_owned(),
"Your backup failed to complete.".to_owned(),
BackupReport {
server: ServerBackupReport {
attempted: true,
error: Some(e.to_string()),
},
packages: BTreeMap::new(),
},
None,
)
.await
.expect("failed to send notification");
}
}
status_model
.put(&mut db, &false)
.await
.expect("failed to change server status");
});
Ok(WithRevision {
response: (),
revision,
})
}
#[instrument(skip(db))]
async fn assure_backing_up(db: &mut PatchDbHandle) -> Result<Option<Arc<Revision>>, Error> {
let mut tx = db.begin().await?;
let mut backing_up = crate::db::DatabaseModel::new()
.server_info()
.status_info()
.backing_up()
.get_mut(&mut tx)
.await?;
if *backing_up {
return Err(Error::new(
eyre!("Server is already backing up!"),
crate::ErrorKind::InvalidRequest,
));
}
*backing_up = true;
backing_up.save(&mut tx).await?;
Ok(tx.commit(None).await?)
}
#[instrument(skip(ctx, db, backup_guard))]
async fn perform_backup<Db: DbHandle>(
ctx: &RpcContext,
mut db: Db,
mut backup_guard: BackupMountGuard<TmpMountGuard>,
) -> Result<BTreeMap<PackageId, PackageBackupReport>, Error> {
let mut backup_report = BTreeMap::new();
for package_id in crate::db::DatabaseModel::new()
.package_data()
.keys(&mut db, false)
.await?
{
let mut tx = db.begin().await?; // for lock scope
let installed_model = if let Some(installed_model) = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&package_id)
.and_then(|m| m.installed())
.check(&mut tx)
.await?
{
installed_model
} else {
continue;
};
let main_status_model = installed_model.clone().status().main();
main_status_model.lock(&mut tx, LockType::Write).await?;
let (started, health) = match main_status_model.get(&mut tx, true).await?.into_owned() {
MainStatus::Starting => (Some(Utc::now()), Default::default()),
MainStatus::Running { started, health } => (Some(started), health.clone()),
MainStatus::Stopped | MainStatus::Stopping => (None, Default::default()),
MainStatus::BackingUp { .. } => {
backup_report.insert(
package_id,
PackageBackupReport {
error: Some(
"Can't do backup because service is in a backing up state".to_owned(),
),
},
);
continue;
}
};
main_status_model
.put(
&mut tx,
&MainStatus::BackingUp {
started,
health: health.clone(),
},
)
.await?;
tx.save().await?; // drop locks
let manifest = installed_model
.clone()
.manifest()
.get(&mut db, false)
.await?;
ctx.managers
.get(&(manifest.id.clone(), manifest.version.clone()))
.await
.ok_or_else(|| {
Error::new(eyre!("Manager not found"), crate::ErrorKind::InvalidRequest)
})?
.synchronize()
.await;
let mut tx = db.begin().await?;
installed_model.lock(&mut tx, LockType::Write).await?;
let guard = backup_guard.mount_package_backup(&package_id).await?;
let res = manifest
.backup
.create(
ctx,
&package_id,
&manifest.title,
&manifest.version,
&manifest.interfaces,
&manifest.volumes,
)
.await;
guard.unmount().await?;
backup_report.insert(
package_id.clone(),
PackageBackupReport {
error: res.as_ref().err().map(|e| e.to_string()),
},
);
if let Ok(pkg_meta) = res {
installed_model
.last_backup()
.put(&mut tx, &Some(pkg_meta.timestamp))
.await?;
backup_guard
.metadata
.package_backups
.insert(package_id, pkg_meta);
}
main_status_model
.put(
&mut tx,
&match started {
Some(started) => MainStatus::Running { started, health },
None => MainStatus::Stopped,
},
)
.await?;
tx.save().await?;
}
crate::db::DatabaseModel::new()
.lock(&mut db, LockType::Write)
.await?;
let (root_ca_key, root_ca_cert) = ctx.net_controller.ssl.export_root_ca().await?;
let mut os_backup_file = AtomicFile::new(backup_guard.as_ref().join("os-backup.cbor")).await?;
os_backup_file
.write_all(
&IoFormat::Cbor.to_vec(&OsBackup {
tor_key: ctx.net_controller.tor.embassyd_tor_key().await,
root_ca_key,
root_ca_cert,
ui: crate::db::DatabaseModel::new()
.ui()
.get(&mut db, true)
.await?
.into_owned(),
})?,
)
.await?;
os_backup_file.save().await?;
let timestamp = Some(Utc::now());
backup_guard.unencrypted_metadata.version = crate::version::Current::new().semver().into();
backup_guard.unencrypted_metadata.full = true;
backup_guard.metadata.version = crate::version::Current::new().semver().into();
backup_guard.metadata.timestamp = timestamp;
backup_guard.save_and_unmount().await?;
crate::db::DatabaseModel::new()
.server_info()
.last_backup()
.put(&mut db, &timestamp)
.await?;
Ok(backup_report)
}

View File

@@ -1,247 +0,0 @@
use std::collections::{BTreeMap, BTreeSet};
use std::path::Path;
use chrono::{DateTime, Utc};
use color_eyre::eyre::eyre;
use patch_db::{DbHandle, HasModel, LockType};
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use sqlx::{Executor, Sqlite};
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use tracing::instrument;
use self::target::PackageBackupInfo;
use crate::action::{ActionImplementation, NoOutput};
use crate::context::RpcContext;
use crate::dependencies::reconfigure_dependents_with_live_pointers;
use crate::id::ImageId;
use crate::install::PKG_ARCHIVE_DIR;
use crate::net::interface::{InterfaceId, Interfaces};
use crate::s9pk::manifest::PackageId;
use crate::util::serde::IoFormat;
use crate::util::{AtomicFile, Version};
use crate::version::{Current, VersionT};
use crate::volume::{backup_dir, Volume, VolumeId, Volumes, BACKUP_DIR};
use crate::{Error, ResultExt};
pub mod backup_bulk;
pub mod restore;
pub mod target;
#[derive(Debug, Deserialize, Serialize)]
pub struct BackupReport {
server: ServerBackupReport,
packages: BTreeMap<PackageId, PackageBackupReport>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ServerBackupReport {
attempted: bool,
error: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct PackageBackupReport {
error: Option<String>,
}
#[command(subcommands(backup_bulk::backup_all, target::target))]
pub fn backup() -> Result<(), Error> {
Ok(())
}
#[command(rename = "backup", subcommands(restore::restore_packages_rpc))]
pub fn package_backup() -> Result<(), Error> {
Ok(())
}
#[derive(Deserialize, Serialize)]
struct BackupMetadata {
pub timestamp: DateTime<Utc>,
pub tor_keys: BTreeMap<InterfaceId, String>,
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)]
pub struct BackupActions {
pub create: ActionImplementation,
pub restore: ActionImplementation,
}
impl BackupActions {
pub fn validate(&self, volumes: &Volumes, image_ids: &BTreeSet<ImageId>) -> Result<(), Error> {
self.create
.validate(volumes, image_ids, false)
.with_ctx(|_| (crate::ErrorKind::ValidateS9pk, "Backup Create"))?;
self.restore
.validate(volumes, image_ids, false)
.with_ctx(|_| (crate::ErrorKind::ValidateS9pk, "Backup Restore"))?;
Ok(())
}
#[instrument(skip(ctx))]
pub async fn create(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_title: &str,
pkg_version: &Version,
interfaces: &Interfaces,
volumes: &Volumes,
) -> Result<PackageBackupInfo, Error> {
let mut volumes = volumes.to_readonly();
volumes.insert(VolumeId::Backup, Volume::Backup { readonly: false });
let backup_dir = backup_dir(pkg_id);
if tokio::fs::metadata(&backup_dir).await.is_err() {
tokio::fs::create_dir_all(&backup_dir).await?
}
self.create
.execute::<(), NoOutput>(
ctx,
pkg_id,
pkg_version,
Some("CreateBackup"),
&volumes,
None,
false,
None,
)
.await?
.map_err(|e| eyre!("{}", e.1))
.with_kind(crate::ErrorKind::Backup)?;
let tor_keys = interfaces
.tor_keys(&mut ctx.secret_store.acquire().await?, pkg_id)
.await?
.into_iter()
.map(|(id, key)| {
(
id,
base32::encode(base32::Alphabet::RFC4648 { padding: true }, &key.as_bytes()),
)
})
.collect();
let tmp_path = Path::new(BACKUP_DIR)
.join(pkg_id)
.join(format!("{}.s9pk", pkg_id));
let s9pk_path = ctx
.datadir
.join(PKG_ARCHIVE_DIR)
.join(pkg_id)
.join(pkg_version.as_str())
.join(format!("{}.s9pk", pkg_id));
let mut infile = File::open(&s9pk_path).await?;
let mut outfile = AtomicFile::new(&tmp_path).await?;
tokio::io::copy(&mut infile, &mut *outfile)
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
format!("cp {} -> {}", s9pk_path.display(), tmp_path.display()),
)
})?;
outfile.save().await?;
let timestamp = Utc::now();
let metadata_path = Path::new(BACKUP_DIR).join(pkg_id).join("metadata.cbor");
let mut outfile = AtomicFile::new(&metadata_path).await?;
outfile
.write_all(&IoFormat::Cbor.to_vec(&BackupMetadata {
timestamp,
tor_keys,
})?)
.await?;
outfile.save().await?;
Ok(PackageBackupInfo {
os_version: Current::new().semver().into(),
title: pkg_title.to_owned(),
version: pkg_version.clone(),
timestamp,
})
}
#[instrument(skip(ctx, db, secrets))]
pub async fn restore<Ex, Db: DbHandle>(
&self,
ctx: &RpcContext,
db: &mut Db,
secrets: &mut Ex,
pkg_id: &PackageId,
pkg_version: &Version,
interfaces: &Interfaces,
volumes: &Volumes,
) -> Result<(), Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let mut volumes = volumes.clone();
volumes.insert(VolumeId::Backup, Volume::Backup { readonly: true });
self.restore
.execute::<(), NoOutput>(
ctx,
pkg_id,
pkg_version,
Some("RestoreBackup"),
&volumes,
None,
false,
None,
)
.await?
.map_err(|e| eyre!("{}", e.1))
.with_kind(crate::ErrorKind::Restore)?;
let metadata_path = Path::new(BACKUP_DIR).join(pkg_id).join("metadata.cbor");
let metadata: BackupMetadata = IoFormat::Cbor.from_slice(
&tokio::fs::read(&metadata_path).await.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
metadata_path.display().to_string(),
)
})?,
)?;
for (iface, key) in metadata.tor_keys {
let key_vec = base32::decode(base32::Alphabet::RFC4648 { padding: true }, &key)
.ok_or_else(|| {
Error::new(
eyre!("invalid base32 string"),
crate::ErrorKind::Deserialization,
)
})?;
sqlx::query!(
"REPLACE INTO tor (package, interface, key) VALUES (?, ?, ?)",
**pkg_id,
*iface,
key_vec,
)
.execute(&mut *secrets)
.await?;
}
crate::db::DatabaseModel::new()
.package_data()
.lock(db, LockType::Write)
.await?;
crate::db::DatabaseModel::new()
.package_data()
.idx_model(pkg_id)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.interface_addresses()
.put(db, &interfaces.install(&mut *secrets, pkg_id).await?)
.await?;
let entry = crate::db::DatabaseModel::new()
.package_data()
.idx_model(pkg_id)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.get(db, true)
.await?;
reconfigure_dependents_with_live_pointers(ctx, db, &entry).await?;
Ok(())
}
}

View File

@@ -1,425 +0,0 @@
use std::collections::BTreeMap;
use std::path::Path;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::time::Duration;
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use futures::future::BoxFuture;
use futures::FutureExt;
use openssl::x509::X509;
use patch_db::{DbHandle, PatchDbHandle, Revision};
use rpc_toolkit::command;
use tokio::fs::File;
use tokio::task::JoinHandle;
use torut::onion::OnionAddressV3;
use tracing::instrument;
use super::target::BackupTargetId;
use crate::backup::backup_bulk::OsBackup;
use crate::context::{RpcContext, SetupContext};
use crate::db::model::{PackageDataEntry, StaticFiles};
use crate::db::util::WithRevision;
use crate::disk::mount::backup::{BackupMountGuard, PackageBackupMountGuard};
use crate::disk::mount::filesystem::ReadOnly;
use crate::disk::mount::guard::TmpMountGuard;
use crate::install::progress::InstallProgress;
use crate::install::{download_install_s9pk, PKG_PUBLIC_DIR};
use crate::net::ssl::SslManager;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::s9pk::reader::S9pkReader;
use crate::setup::RecoveryStatus;
use crate::util::display_none;
use crate::util::io::dir_size;
use crate::util::serde::IoFormat;
use crate::volume::{backup_dir, BACKUP_DIR, PKG_VOLUME_DIR};
use crate::{auth::check_password_against_db, notifications::NotificationLevel};
use crate::{Error, ResultExt};
fn parse_comma_separated(arg: &str, _: &ArgMatches<'_>) -> Result<Vec<PackageId>, Error> {
arg.split(',')
.map(|s| s.trim().parse().map_err(Error::from))
.collect()
}
#[command(rename = "restore", display(display_none))]
#[instrument(skip(ctx, old_password, password))]
pub async fn restore_packages_rpc(
#[context] ctx: RpcContext,
#[arg(parse(parse_comma_separated))] ids: Vec<PackageId>,
#[arg(rename = "target-id")] target_id: BackupTargetId,
#[arg(rename = "old-password", long = "old-password")] old_password: Option<String>,
#[arg] password: String,
) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
check_password_against_db(&mut ctx.secret_store.acquire().await?, &password).await?;
let fs = target_id
.load(&mut ctx.secret_store.acquire().await?)
.await?;
let mut backup_guard = BackupMountGuard::mount(
TmpMountGuard::mount(&fs, ReadOnly).await?,
old_password.as_ref().unwrap_or(&password),
)
.await?;
if old_password.is_some() {
backup_guard.change_password(&password)?;
}
let (revision, backup_guard, tasks, _) =
restore_packages(&ctx, &mut db, backup_guard, ids).await?;
tokio::spawn(async {
futures::future::join_all(tasks).await;
if let Err(e) = backup_guard.unmount().await {
tracing::error!("Error unmounting backup drive: {}", e);
tracing::debug!("{:?}", e);
}
});
Ok(WithRevision {
response: (),
revision,
})
}
async fn approximate_progress(
rpc_ctx: &RpcContext,
progress: &mut ProgressInfo,
) -> Result<(), Error> {
for (id, size) in &mut progress.target_volume_size {
let dir = rpc_ctx.datadir.join(PKG_VOLUME_DIR).join(id).join("data");
if tokio::fs::metadata(&dir).await.is_err() {
*size = 0;
} else {
*size = dir_size(&dir).await?;
}
}
Ok(())
}
async fn approximate_progress_loop(
ctx: &SetupContext,
rpc_ctx: &RpcContext,
mut starting_info: ProgressInfo,
) {
loop {
if let Err(e) = approximate_progress(rpc_ctx, &mut starting_info).await {
tracing::error!("Failed to approximate restore progress: {}", e);
tracing::debug!("{:?}", e);
} else {
*ctx.recovery_status.write().await = Some(Ok(starting_info.flatten()));
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
#[derive(Debug, Default)]
struct ProgressInfo {
package_installs: BTreeMap<PackageId, Arc<InstallProgress>>,
src_volume_size: BTreeMap<PackageId, u64>,
target_volume_size: BTreeMap<PackageId, u64>,
}
impl ProgressInfo {
fn flatten(&self) -> RecoveryStatus {
let mut total_bytes = 0;
let mut bytes_transferred = 0;
for progress in self.package_installs.values() {
total_bytes += ((progress.size.unwrap_or(0) as f64) * 2.2) as u64;
bytes_transferred += progress.downloaded.load(Ordering::SeqCst);
bytes_transferred += ((progress.validated.load(Ordering::SeqCst) as f64) * 0.2) as u64;
bytes_transferred += progress.unpacked.load(Ordering::SeqCst);
}
for size in self.src_volume_size.values() {
total_bytes += *size;
}
for size in self.target_volume_size.values() {
bytes_transferred += *size;
}
if bytes_transferred > total_bytes {
bytes_transferred = total_bytes;
}
RecoveryStatus {
total_bytes,
bytes_transferred,
complete: false,
}
}
}
#[instrument(skip(ctx))]
pub async fn recover_full_embassy(
ctx: SetupContext,
disk_guid: Arc<String>,
embassy_password: String,
recovery_source: TmpMountGuard,
recovery_password: Option<String>,
) -> Result<(OnionAddressV3, X509, BoxFuture<'static, Result<(), Error>>), Error> {
let backup_guard = BackupMountGuard::mount(
recovery_source,
recovery_password.as_deref().unwrap_or_default(),
)
.await?;
let os_backup_path = backup_guard.as_ref().join("os-backup.cbor");
let os_backup: OsBackup =
IoFormat::Cbor.from_slice(&tokio::fs::read(&os_backup_path).await.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
os_backup_path.display().to_string(),
)
})?)?;
let password = argon2::hash_encoded(
embassy_password.as_bytes(),
&rand::random::<[u8; 16]>()[..],
&argon2::Config::default(),
)
.with_kind(crate::ErrorKind::PasswordHashGeneration)?;
let key_vec = os_backup.tor_key.as_bytes().to_vec();
let secret_store = ctx.secret_store().await?;
sqlx::query!(
"REPLACE INTO account (id, password, tor_key) VALUES (?, ?, ?)",
0,
password,
key_vec,
)
.execute(&mut secret_store.acquire().await?)
.await?;
SslManager::import_root_ca(
secret_store.clone(),
os_backup.root_ca_key,
os_backup.root_ca_cert.clone(),
)
.await?;
secret_store.close().await;
Ok((
os_backup.tor_key.public().get_onion_address(),
os_backup.root_ca_cert,
async move {
let rpc_ctx = RpcContext::init(ctx.config_path.as_ref(), disk_guid).await?;
let mut db = rpc_ctx.db.handle();
let ids = backup_guard
.metadata
.package_backups
.keys()
.cloned()
.collect();
let (_, backup_guard, tasks, progress_info) = restore_packages(
&rpc_ctx,
&mut db,
backup_guard,
ids,
)
.await?;
tokio::select! {
res = futures::future::join_all(tasks) => {
for res in res {
match res.with_kind(crate::ErrorKind::Unknown) {
Ok((Ok(_), _)) => (),
Ok((Err(err), package_id)) => {
if let Err(err) = rpc_ctx.notification_manager.notify(
&mut db,
Some(package_id.clone()),
NotificationLevel::Error,
"Restoration Failure".to_string(), format!("Error restoring package {}: {}", package_id,err), (), None).await{
tracing::error!("Failed to notify: {}", err);
tracing::debug!("{:?}", err);
};
tracing::error!("Error restoring package {}: {}", package_id, err);
tracing::debug!("{:?}", err);
},
Err(e) => {
if let Err(err) = rpc_ctx.notification_manager.notify(
&mut db,
None,
NotificationLevel::Error,
"Restoration Failure".to_string(), format!("Error restoring ?: {}", e), (), None).await {
tracing::error!("Failed to notify: {}", err);
tracing::debug!("{:?}", err);
}
tracing::error!("Error restoring packages: {}", e);
tracing::debug!("{:?}", e);
},
}
}
},
_ = approximate_progress_loop(&ctx, &rpc_ctx, progress_info) => unreachable!(concat!(module_path!(), "::approximate_progress_loop should not terminate")),
}
backup_guard.unmount().await?;
rpc_ctx.shutdown().await
}.boxed()
))
}
async fn restore_packages(
ctx: &RpcContext,
db: &mut PatchDbHandle,
backup_guard: BackupMountGuard<TmpMountGuard>,
ids: Vec<PackageId>,
) -> Result<
(
Option<Arc<Revision>>,
BackupMountGuard<TmpMountGuard>,
Vec<JoinHandle<(Result<(), Error>, PackageId)>>,
ProgressInfo,
),
Error,
> {
let (revision, guards) = assure_restoring(ctx, db, ids, &backup_guard).await?;
let mut progress_info = ProgressInfo::default();
let mut tasks = Vec::with_capacity(guards.len());
for (manifest, guard) in guards {
let id = manifest.id.clone();
let (progress, task) = restore_package(ctx.clone(), manifest, guard).await?;
progress_info.package_installs.insert(id.clone(), progress);
progress_info
.src_volume_size
.insert(id.clone(), dir_size(backup_dir(&id)).await?);
progress_info.target_volume_size.insert(id.clone(), 0);
let package_id = id.clone();
tasks.push(tokio::spawn(
async move {
if let Err(e) = task.await {
tracing::error!("Error restoring package {}: {}", id, e);
tracing::debug!("{:?}", e);
Err(e)
} else {
Ok(())
}
}
.map(|x| (x, package_id)),
));
}
Ok((revision, backup_guard, tasks, progress_info))
}
#[instrument(skip(ctx, db, backup_guard))]
async fn assure_restoring(
ctx: &RpcContext,
db: &mut PatchDbHandle,
ids: Vec<PackageId>,
backup_guard: &BackupMountGuard<TmpMountGuard>,
) -> Result<
(
Option<Arc<Revision>>,
Vec<(Manifest, PackageBackupMountGuard)>,
),
Error,
> {
let mut tx = db.begin().await?;
let mut guards = Vec::with_capacity(ids.len());
for id in ids {
let mut model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.get_mut(&mut tx)
.await?;
if !model.is_none() {
return Err(Error::new(
eyre!("Can't restore over existing package: {}", id),
crate::ErrorKind::InvalidRequest,
));
}
let guard = backup_guard.mount_package_backup(&id).await?;
let s9pk_path = Path::new(BACKUP_DIR).join(&id).join(format!("{}.s9pk", id));
let mut rdr = S9pkReader::open(&s9pk_path, false).await?;
let manifest = rdr.manifest().await?;
let version = manifest.version.clone();
let progress = InstallProgress::new(Some(tokio::fs::metadata(&s9pk_path).await?.len()));
let public_dir_path = ctx
.datadir
.join(PKG_PUBLIC_DIR)
.join(&id)
.join(version.as_str());
tokio::fs::create_dir_all(&public_dir_path).await?;
let license_path = public_dir_path.join("LICENSE.md");
let mut dst = File::create(&license_path).await?;
tokio::io::copy(&mut rdr.license().await?, &mut dst).await?;
dst.sync_all().await?;
let instructions_path = public_dir_path.join("INSTRUCTIONS.md");
let mut dst = File::create(&instructions_path).await?;
tokio::io::copy(&mut rdr.instructions().await?, &mut dst).await?;
dst.sync_all().await?;
let icon_path = Path::new("icon").with_extension(&manifest.assets.icon_type());
let icon_path = public_dir_path.join(&icon_path);
let mut dst = File::create(&icon_path).await?;
tokio::io::copy(&mut rdr.icon().await?, &mut dst).await?;
dst.sync_all().await?;
*model = Some(PackageDataEntry::Restoring {
install_progress: progress.clone(),
static_files: StaticFiles::local(&id, &version, manifest.assets.icon_type()),
manifest: manifest.clone(),
});
model.save(&mut tx).await?;
guards.push((manifest, guard));
}
Ok((tx.commit(None).await?, guards))
}
#[instrument(skip(ctx, guard))]
async fn restore_package<'a>(
ctx: RpcContext,
manifest: Manifest,
guard: PackageBackupMountGuard,
) -> Result<(Arc<InstallProgress>, BoxFuture<'static, Result<(), Error>>), Error> {
let s9pk_path = Path::new(BACKUP_DIR)
.join(&manifest.id)
.join(format!("{}.s9pk", manifest.id));
let len = tokio::fs::metadata(&s9pk_path)
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
s9pk_path.display().to_string(),
)
})?
.len();
let file = File::open(&s9pk_path).await.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
s9pk_path.display().to_string(),
)
})?;
let progress = InstallProgress::new(Some(len));
Ok((
progress.clone(),
async move {
download_install_s9pk(&ctx, &manifest, None, progress, file).await?;
guard.unmount().await?;
Ok(())
}
.boxed(),
))
}

View File

@@ -1,212 +0,0 @@
use std::path::{Path, PathBuf};
use color_eyre::eyre::eyre;
use futures::TryStreamExt;
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use sqlx::{Executor, Sqlite};
use super::{BackupTarget, BackupTargetId};
use crate::context::RpcContext;
use crate::disk::mount::filesystem::cifs::Cifs;
use crate::disk::mount::filesystem::ReadOnly;
use crate::disk::mount::guard::TmpMountGuard;
use crate::disk::util::{recovery_info, EmbassyOsRecoveryInfo};
use crate::util::display_none;
use crate::util::serde::KeyVal;
use crate::Error;
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct CifsBackupTarget {
hostname: String,
path: PathBuf,
username: String,
mountable: bool,
embassy_os: Option<EmbassyOsRecoveryInfo>,
}
#[command(subcommands(add, update, remove))]
pub fn cifs() -> Result<(), Error> {
Ok(())
}
#[command(display(display_none))]
pub async fn add(
#[context] ctx: RpcContext,
#[arg] hostname: String,
#[arg] path: PathBuf,
#[arg] username: String,
#[arg] password: Option<String>,
) -> Result<KeyVal<BackupTargetId, BackupTarget>, Error> {
let cifs = Cifs {
hostname,
path,
username,
password,
};
let guard = TmpMountGuard::mount(&cifs, ReadOnly).await?;
let embassy_os = recovery_info(&guard).await?;
guard.unmount().await?;
let path_string = Path::new("/").join(&cifs.path).display().to_string();
let id: u32 = sqlx::query!(
"INSERT INTO cifs_shares (hostname, path, username, password) VALUES (?, ?, ?, ?) RETURNING id AS \"id: u32\"",
cifs.hostname,
path_string,
cifs.username,
cifs.password,
)
.fetch_one(&ctx.secret_store)
.await?.id;
Ok(KeyVal {
key: BackupTargetId::Cifs { id },
value: BackupTarget::Cifs(CifsBackupTarget {
hostname: cifs.hostname,
path: cifs.path,
username: cifs.username,
mountable: true,
embassy_os,
}),
})
}
#[command(display(display_none))]
pub async fn update(
#[context] ctx: RpcContext,
#[arg] id: BackupTargetId,
#[arg] hostname: String,
#[arg] path: PathBuf,
#[arg] username: String,
#[arg] password: Option<String>,
) -> Result<KeyVal<BackupTargetId, BackupTarget>, Error> {
let id = if let BackupTargetId::Cifs { id } = id {
id
} else {
return Err(Error::new(
eyre!("Backup Target ID {} Not Found", id),
crate::ErrorKind::NotFound,
));
};
let cifs = Cifs {
hostname,
path,
username,
password,
};
let guard = TmpMountGuard::mount(&cifs, ReadOnly).await?;
let embassy_os = recovery_info(&guard).await?;
guard.unmount().await?;
let path_string = Path::new("/").join(&cifs.path).display().to_string();
if sqlx::query!(
"UPDATE cifs_shares SET hostname = ?, path = ?, username = ?, password = ? WHERE id = ?",
cifs.hostname,
path_string,
cifs.username,
cifs.password,
id,
)
.execute(&ctx.secret_store)
.await?
.rows_affected()
== 0
{
return Err(Error::new(
eyre!("Backup Target ID {} Not Found", BackupTargetId::Cifs { id }),
crate::ErrorKind::NotFound,
));
};
Ok(KeyVal {
key: BackupTargetId::Cifs { id },
value: BackupTarget::Cifs(CifsBackupTarget {
hostname: cifs.hostname,
path: cifs.path,
username: cifs.username,
mountable: true,
embassy_os,
}),
})
}
#[command(display(display_none))]
pub async fn remove(#[context] ctx: RpcContext, #[arg] id: BackupTargetId) -> Result<(), Error> {
let id = if let BackupTargetId::Cifs { id } = id {
id
} else {
return Err(Error::new(
eyre!("Backup Target ID {} Not Found", id),
crate::ErrorKind::NotFound,
));
};
if sqlx::query!("DELETE FROM cifs_shares WHERE id = ?", id)
.execute(&ctx.secret_store)
.await?
.rows_affected()
== 0
{
return Err(Error::new(
eyre!("Backup Target ID {} Not Found", BackupTargetId::Cifs { id }),
crate::ErrorKind::NotFound,
));
};
Ok(())
}
pub async fn load<Ex>(secrets: &mut Ex, id: u32) -> Result<Cifs, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let record = sqlx::query!(
"SELECT hostname, path, username, password FROM cifs_shares WHERE id = ?",
id
)
.fetch_one(secrets)
.await?;
Ok(Cifs {
hostname: record.hostname,
path: PathBuf::from(record.path),
username: record.username,
password: record.password,
})
}
pub async fn list<Ex>(secrets: &mut Ex) -> Result<Vec<(u32, CifsBackupTarget)>, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let mut records = sqlx::query!(
"SELECT id AS \"id: u32\", hostname, path, username, password FROM cifs_shares"
)
.fetch_many(secrets);
let mut cifs = Vec::new();
while let Some(query_result) = records.try_next().await? {
if let Some(record) = query_result.right() {
let mount_info = Cifs {
hostname: record.hostname,
path: PathBuf::from(record.path),
username: record.username,
password: record.password,
};
let embassy_os = async {
let guard = TmpMountGuard::mount(&mount_info, ReadOnly).await?;
let embassy_os = recovery_info(&guard).await?;
guard.unmount().await?;
Ok::<_, Error>(embassy_os)
}
.await;
cifs.push((
record.id,
CifsBackupTarget {
hostname: mount_info.hostname,
path: mount_info.path,
username: mount_info.username,
mountable: embassy_os.is_ok(),
embassy_os: embassy_os.ok().and_then(|a| a),
},
));
}
}
Ok(cifs)
}

View File

@@ -1,247 +0,0 @@
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use async_trait::async_trait;
use chrono::{DateTime, Utc};
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray;
use digest::Digest;
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use sqlx::{Executor, Sqlite};
use tracing::instrument;
use self::cifs::CifsBackupTarget;
use crate::context::RpcContext;
use crate::disk::mount::backup::BackupMountGuard;
use crate::disk::mount::filesystem::block_dev::BlockDev;
use crate::disk::mount::filesystem::cifs::Cifs;
use crate::disk::mount::filesystem::{FileSystem, MountType, ReadOnly};
use crate::disk::mount::guard::TmpMountGuard;
use crate::disk::util::PartitionInfo;
use crate::s9pk::manifest::PackageId;
use crate::util::serde::{deserialize_from_str, display_serializable, serialize_display};
use crate::util::Version;
use crate::Error;
pub mod cifs;
#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
#[serde(rename_all = "kebab-case")]
pub enum BackupTarget {
#[serde(rename_all = "kebab-case")]
Disk {
vendor: Option<String>,
model: Option<String>,
#[serde(flatten)]
partition_info: PartitionInfo,
},
Cifs(CifsBackupTarget),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum BackupTargetId {
Disk { logicalname: PathBuf },
Cifs { id: u32 },
}
impl BackupTargetId {
pub async fn load<Ex>(self, secrets: &mut Ex) -> Result<BackupTargetFS, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
Ok(match self {
BackupTargetId::Disk { logicalname } => {
BackupTargetFS::Disk(BlockDev::new(logicalname))
}
BackupTargetId::Cifs { id } => BackupTargetFS::Cifs(cifs::load(secrets, id).await?),
})
}
}
impl std::fmt::Display for BackupTargetId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BackupTargetId::Disk { logicalname } => write!(f, "disk-{}", logicalname.display()),
BackupTargetId::Cifs { id } => write!(f, "cifs-{}", id),
}
}
}
impl std::str::FromStr for BackupTargetId {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.split_once("-") {
Some(("disk", logicalname)) => Ok(BackupTargetId::Disk {
logicalname: Path::new(logicalname).to_owned(),
}),
Some(("cifs", id)) => Ok(BackupTargetId::Cifs { id: id.parse()? }),
_ => Err(Error::new(
eyre!("Invalid Backup Target ID"),
crate::ErrorKind::InvalidBackupTargetId,
)),
}
}
}
impl<'de> Deserialize<'de> for BackupTargetId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserialize_from_str(deserializer)
}
}
impl Serialize for BackupTargetId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serialize_display(self, serializer)
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
#[serde(rename_all = "kebab-case")]
pub enum BackupTargetFS {
Disk(BlockDev<PathBuf>),
Cifs(Cifs),
}
#[async_trait]
impl FileSystem for BackupTargetFS {
async fn mount<P: AsRef<Path> + Send + Sync>(
&self,
mountpoint: P,
mount_type: MountType,
) -> Result<(), Error> {
match self {
BackupTargetFS::Disk(a) => a.mount(mountpoint, mount_type).await,
BackupTargetFS::Cifs(a) => a.mount(mountpoint, mount_type).await,
}
}
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> {
match self {
BackupTargetFS::Disk(a) => a.source_hash().await,
BackupTargetFS::Cifs(a) => a.source_hash().await,
}
}
}
#[command(subcommands(cifs::cifs, list, info))]
pub fn target() -> Result<(), Error> {
Ok(())
}
// TODO: incorporate reconnect into this response as well
#[command(display(display_serializable))]
pub async fn list(
#[context] ctx: RpcContext,
) -> Result<BTreeMap<BackupTargetId, BackupTarget>, Error> {
let mut sql_handle = ctx.secret_store.acquire().await?;
let (disks_res, cifs) =
tokio::try_join!(crate::disk::util::list(), cifs::list(&mut sql_handle),)?;
Ok(disks_res
.disks
.into_iter()
.flat_map(|mut disk| {
std::mem::take(&mut disk.partitions)
.into_iter()
.map(|part| {
(
BackupTargetId::Disk {
logicalname: part.logicalname.clone(),
},
BackupTarget::Disk {
vendor: disk.vendor.clone(),
model: disk.model.clone(),
partition_info: part,
},
)
})
.collect::<Vec<_>>()
})
.chain(
cifs.into_iter()
.map(|(id, cifs)| (BackupTargetId::Cifs { id }, BackupTarget::Cifs(cifs))),
)
.collect())
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct BackupInfo {
pub version: Version,
pub timestamp: Option<DateTime<Utc>>,
pub package_backups: BTreeMap<PackageId, PackageBackupInfo>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct PackageBackupInfo {
pub title: String,
pub version: Version,
pub os_version: Version,
pub timestamp: DateTime<Utc>,
}
fn display_backup_info(info: BackupInfo, matches: &ArgMatches<'_>) {
use prettytable::*;
if matches.is_present("format") {
return display_serializable(info, matches);
}
let mut table = Table::new();
table.add_row(row![bc =>
"ID",
"VERSION",
"OS VERSION",
"TIMESTAMP",
]);
table.add_row(row![
"EMBASSY OS",
info.version.as_str(),
info.version.as_str(),
&if let Some(ts) = &info.timestamp {
ts.to_string()
} else {
"N/A".to_owned()
},
]);
for (id, info) in info.package_backups {
let row = row![
id.as_str(),
info.version.as_str(),
info.os_version.as_str(),
&info.timestamp.to_string(),
];
table.add_row(row);
}
table.print_tty(false);
}
#[command(display(display_backup_info))]
#[instrument(skip(ctx, password))]
pub async fn info(
#[context] ctx: RpcContext,
#[arg(rename = "target-id")] target_id: BackupTargetId,
#[arg] password: String,
) -> Result<BackupInfo, Error> {
let guard = BackupMountGuard::mount(
TmpMountGuard::mount(
&target_id
.load(&mut ctx.secret_store.acquire().await?)
.await?,
ReadOnly,
)
.await?,
&password,
)
.await?;
let res = guard.metadata.clone();
guard.unmount().await?;
Ok(res)
}

View File

@@ -1,57 +0,0 @@
use clap::Arg;
use embassy::context::CliContext;
use embassy::util::logger::EmbassyLogger;
use embassy::version::{Current, VersionT};
use embassy::Error;
use rpc_toolkit::run_cli;
use rpc_toolkit::yajrc::RpcError;
use serde_json::Value;
fn inner_main() -> Result<(), Error> {
run_cli!({
command: embassy::main_api,
app: app => app
.name("Embassy CLI")
.version(Current::new().semver().to_string().as_str())
.arg(
clap::Arg::with_name("config")
.short("c")
.long("config")
.takes_value(true),
)
.arg(Arg::with_name("host").long("host").short("h").takes_value(true))
.arg(Arg::with_name("proxy").long("proxy").short("p").takes_value(true)),
context: matches => {
EmbassyLogger::init();
CliContext::init(matches)?
},
exit: |e: RpcError| {
match e.data {
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
Some(Value::Object(o)) => if let Some(Value::String(s)) = o.get("details") {
eprintln!("{}: {}", e.message, s);
if let Some(Value::String(s)) = o.get("debug") {
tracing::debug!("{}", s)
}
}
Some(a) => eprintln!("{}: {}", e.message, a),
None => eprintln!("{}", e.message),
}
std::process::exit(e.code);
}
});
Ok(())
}
fn main() {
match inner_main() {
Ok(_) => (),
Err(e) => {
eprintln!("{}", e.source);
tracing::debug!("{:?}", e.source);
drop(e.source);
std::process::exit(e.kind as i32)
}
}
}

View File

@@ -1,240 +0,0 @@
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use embassy::context::rpc::RpcContextConfig;
use embassy::context::{DiagnosticContext, SetupContext};
use embassy::disk::fsck::RepairStrategy;
use embassy::disk::main::DEFAULT_PASSWORD;
use embassy::disk::REPAIR_DISK_PATH;
use embassy::hostname::get_product_key;
use embassy::middleware::cors::cors;
use embassy::middleware::diagnostic::diagnostic;
use embassy::middleware::encrypt::encrypt;
#[cfg(feature = "avahi")]
use embassy::net::mdns::MdnsController;
use embassy::shutdown::Shutdown;
use embassy::sound::CHIME;
use embassy::util::logger::EmbassyLogger;
use embassy::util::Invoke;
use embassy::{Error, ResultExt};
use http::StatusCode;
use rpc_toolkit::rpc_server;
use tokio::process::Command;
use tracing::instrument;
fn status_fn(_: i32) -> StatusCode {
StatusCode::OK
}
#[instrument]
async fn setup_or_init(cfg_path: Option<&str>) -> Result<(), Error> {
if tokio::fs::metadata("/embassy-os/disk.guid").await.is_err() {
#[cfg(feature = "avahi")]
let _mdns = MdnsController::init();
tokio::fs::write(
"/etc/nginx/sites-available/default",
include_str!("../nginx/setup-wizard.conf"),
)
.await
.with_ctx(|_| {
(
embassy::ErrorKind::Filesystem,
"/etc/nginx/sites-available/default",
)
})?;
Command::new("systemctl")
.arg("reload")
.arg("nginx")
.invoke(embassy::ErrorKind::Nginx)
.await?;
let ctx = SetupContext::init(cfg_path).await?;
let keysource_ctx = ctx.clone();
let keysource = move || {
let ctx = keysource_ctx.clone();
async move { ctx.product_key().await }
};
let encrypt = encrypt(keysource);
tokio::time::sleep(Duration::from_secs(1)).await; // let the record state that I hate this
CHIME.play().await?;
rpc_server!({
command: embassy::setup_api,
context: ctx.clone(),
status: status_fn,
middleware: [
cors,
encrypt,
]
})
.with_graceful_shutdown({
let mut shutdown = ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
})
.await
.with_kind(embassy::ErrorKind::Network)?;
} else {
let cfg = RpcContextConfig::load(cfg_path).await?;
let guid_string = tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
.await?;
let guid = guid_string.trim();
let reboot = embassy::disk::main::import(
guid,
cfg.datadir(),
if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() {
RepairStrategy::Aggressive
} else {
RepairStrategy::Preen
},
DEFAULT_PASSWORD,
)
.await?;
if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() {
tokio::fs::remove_file(REPAIR_DISK_PATH)
.await
.with_ctx(|_| (embassy::ErrorKind::Filesystem, REPAIR_DISK_PATH))?;
}
if reboot.0 {
embassy::disk::main::export(guid, cfg.datadir()).await?;
Command::new("reboot")
.invoke(embassy::ErrorKind::Unknown)
.await?;
}
tracing::info!("Loaded Disk");
embassy::init::init(&cfg, &get_product_key().await?).await?;
}
Ok(())
}
async fn run_script_if_exists<P: AsRef<Path>>(path: P) {
let script = path.as_ref();
if script.exists() {
match Command::new("/bin/bash").arg(script).spawn() {
Ok(mut c) => {
if let Err(e) = c.wait().await {
tracing::error!("Error Running {}: {}", script.display(), e);
tracing::debug!("{:?}", e);
}
}
Err(e) => {
tracing::error!("Error Running {}: {}", script.display(), e);
tracing::debug!("{:?}", e);
}
}
}
}
#[instrument]
async fn inner_main(cfg_path: Option<&str>) -> Result<Option<Shutdown>, Error> {
embassy::sound::BEP.play().await?;
run_script_if_exists("/embassy-os/preinit.sh").await;
let res = if let Err(e) = setup_or_init(cfg_path).await {
async {
tracing::error!("{}", e.source);
tracing::debug!("{}", e.source);
embassy::sound::BEETHOVEN.play().await?;
#[cfg(feature = "avahi")]
let _mdns = MdnsController::init();
tokio::fs::write(
"/etc/nginx/sites-available/default",
include_str!("../nginx/diagnostic-ui.conf"),
)
.await
.with_ctx(|_| {
(
embassy::ErrorKind::Filesystem,
"/etc/nginx/sites-available/default",
)
})?;
Command::new("systemctl")
.arg("reload")
.arg("nginx")
.invoke(embassy::ErrorKind::Nginx)
.await?;
let ctx = DiagnosticContext::init(
cfg_path,
if tokio::fs::metadata("/embassy-os/disk.guid").await.is_ok() {
Some(Arc::new(
tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
.await?
.trim()
.to_owned(),
))
} else {
None
},
e,
)
.await?;
let mut shutdown_recv = ctx.shutdown.subscribe();
rpc_server!({
command: embassy::diagnostic_api,
context: ctx.clone(),
status: status_fn,
middleware: [
cors,
diagnostic,
]
})
.with_graceful_shutdown({
let mut shutdown = ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
})
.await
.with_kind(embassy::ErrorKind::Network)?;
Ok::<_, Error>(
shutdown_recv
.recv()
.await
.with_kind(embassy::ErrorKind::Network)?,
)
}
.await
} else {
Ok(None)
};
run_script_if_exists("/embassy-os/postinit.sh").await;
res
}
fn main() {
let matches = clap::App::new("embassyd")
.arg(
clap::Arg::with_name("config")
.short("c")
.long("config")
.takes_value(true),
)
.get_matches();
EmbassyLogger::init();
let cfg_path = matches.value_of("config");
let res = {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("failed to initialize runtime");
rt.block_on(inner_main(cfg_path))
};
match res {
Ok(Some(shutdown)) => shutdown.execute(),
Ok(None) => (),
Err(e) => {
eprintln!("{}", e.source);
tracing::debug!("{:?}", e.source);
drop(e.source);
std::process::exit(e.kind as i32)
}
}
}

View File

@@ -1,56 +0,0 @@
use embassy::context::SdkContext;
use embassy::util::logger::EmbassyLogger;
use embassy::version::{Current, VersionT};
use embassy::Error;
use rpc_toolkit::run_cli;
use rpc_toolkit::yajrc::RpcError;
use serde_json::Value;
fn inner_main() -> Result<(), Error> {
run_cli!({
command: embassy::portable_api,
app: app => app
.name("Embassy SDK")
.version(Current::new().semver().to_string().as_str())
.arg(
clap::Arg::with_name("config")
.short("c")
.long("config")
.takes_value(true),
),
context: matches => {
if let Err(_) = std::env::var("RUST_LOG") {
std::env::set_var("RUST_LOG", "embassy=warn");
}
EmbassyLogger::init();
SdkContext::init(matches)?
},
exit: |e: RpcError| {
match e.data {
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
Some(Value::Object(o)) => if let Some(Value::String(s)) = o.get("details") {
eprintln!("{}: {}", e.message, s);
if let Some(Value::String(s)) = o.get("debug") {
tracing::debug!("{}", s)
}
}
Some(a) => eprintln!("{}: {}", e.message, a),
None => eprintln!("{}", e.message),
}
std::process::exit(e.code);
}
});
Ok(())
}
fn main() {
match inner_main() {
Ok(_) => (),
Err(e) => {
eprintln!("{}", e.source);
tracing::debug!("{:?}", e.source);
drop(e.source);
std::process::exit(e.kind as i32)
}
}
}

View File

@@ -1,377 +0,0 @@
use std::sync::Arc;
use std::time::Duration;
use color_eyre::eyre::eyre;
use embassy::context::{DiagnosticContext, RpcContext};
use embassy::core::rpc_continuations::RequestGuid;
use embassy::db::subscribe;
use embassy::middleware::auth::auth;
use embassy::middleware::cors::cors;
use embassy::middleware::diagnostic::diagnostic;
#[cfg(feature = "avahi")]
use embassy::net::mdns::MdnsController;
use embassy::net::tor::tor_health_check;
use embassy::shutdown::Shutdown;
use embassy::system::launch_metrics_task;
use embassy::util::logger::EmbassyLogger;
use embassy::util::{daemon, Invoke};
use embassy::{static_server, Error, ErrorKind, ResultExt};
use futures::{FutureExt, TryFutureExt};
use reqwest::{Client, Proxy};
use rpc_toolkit::hyper::{Body, Response, Server, StatusCode};
use rpc_toolkit::rpc_server;
use tokio::process::Command;
use tokio::signal::unix::signal;
use tracing::instrument;
fn status_fn(_: i32) -> StatusCode {
StatusCode::OK
}
fn err_to_500(e: Error) -> Response<Body> {
tracing::error!("{}", e);
tracing::debug!("{:?}", e);
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap()
}
#[instrument]
async fn inner_main(cfg_path: Option<&str>) -> Result<Option<Shutdown>, Error> {
let (rpc_ctx, shutdown) = {
embassy::hostname::sync_hostname().await?;
let rpc_ctx = RpcContext::init(
cfg_path,
Arc::new(
tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
.await?
.trim()
.to_owned(),
),
)
.await?;
let mut shutdown_recv = rpc_ctx.shutdown.subscribe();
let sig_handler_ctx = rpc_ctx.clone();
let sig_handler = tokio::spawn(async move {
use tokio::signal::unix::SignalKind;
futures::future::select_all(
[
SignalKind::interrupt(),
SignalKind::quit(),
SignalKind::terminate(),
]
.iter()
.map(|s| {
async move {
signal(*s)
.expect(&format!("register {:?} handler", s))
.recv()
.await
}
.boxed()
}),
)
.await;
sig_handler_ctx
.shutdown
.send(None)
.map_err(|_| ())
.expect("send shutdown signal");
});
rpc_ctx.set_nginx_conf(&mut rpc_ctx.db.handle()).await?;
let auth = auth(rpc_ctx.clone());
let ctx = rpc_ctx.clone();
let server = rpc_server!({
command: embassy::main_api,
context: ctx,
status: status_fn,
middleware: [
cors,
auth,
]
})
.with_graceful_shutdown({
let mut shutdown = rpc_ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
});
let metrics_ctx = rpc_ctx.clone();
let metrics_task = tokio::spawn(async move {
launch_metrics_task(&metrics_ctx.metrics_cache, || {
metrics_ctx.shutdown.subscribe()
})
.await
});
let rev_cache_ctx = rpc_ctx.clone();
let revision_cache_task = tokio::spawn(async move {
let mut sub = rev_cache_ctx.db.subscribe();
let mut shutdown = rev_cache_ctx.shutdown.subscribe();
loop {
let rev = match tokio::select! {
a = sub.recv() => a,
_ = shutdown.recv() => break,
} {
Ok(a) => a,
Err(_) => {
rev_cache_ctx.revision_cache.write().await.truncate(0);
continue;
}
}; // TODO: handle falling behind
let mut cache = rev_cache_ctx.revision_cache.write().await;
cache.push_back(rev);
if cache.len() > rev_cache_ctx.revision_cache_size {
cache.pop_front();
}
}
});
let ws_ctx = rpc_ctx.clone();
let ws_server = {
let builder = Server::bind(&ws_ctx.bind_ws);
let make_svc = ::rpc_toolkit::hyper::service::make_service_fn(move |_| {
let ctx = ws_ctx.clone();
async move {
Ok::<_, ::rpc_toolkit::hyper::Error>(::rpc_toolkit::hyper::service::service_fn(
move |req| {
let ctx = ctx.clone();
async move {
tracing::debug!("Request to {}", req.uri().path());
match req.uri().path() {
"/ws/db" => {
Ok(subscribe(ctx, req).await.unwrap_or_else(err_to_500))
}
path if path.starts_with("/rest/rpc/") => {
match RequestGuid::from(
path.strip_prefix("/rest/rpc/").unwrap(),
) {
None => {
tracing::debug!("No Guid Path");
Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::empty())
}
Some(guid) => {
match ctx
.rpc_stream_continuations
.lock()
.await
.remove(&guid)
{
None => Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::empty()),
Some(cont) => match (cont.handler)(req).await {
Ok(r) => Ok(r),
Err(e) => Response::builder()
.status(
StatusCode::INTERNAL_SERVER_ERROR,
)
.body(Body::from(format!("{}", e))),
},
}
}
}
}
_ => Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::empty()),
}
}
},
))
}
});
builder.serve(make_svc)
}
.with_graceful_shutdown({
let mut shutdown = rpc_ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
});
let file_server_ctx = rpc_ctx.clone();
let file_server = {
static_server::init(file_server_ctx, {
let mut shutdown = rpc_ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
})
};
let tor_health_ctx = rpc_ctx.clone();
let tor_client = Client::builder()
.proxy(
Proxy::http(format!(
"socks5h://{}:{}",
rpc_ctx.tor_socks.ip(),
rpc_ctx.tor_socks.port()
))
.with_kind(crate::ErrorKind::Network)?,
)
.build()
.with_kind(crate::ErrorKind::Network)?;
let tor_health_daemon = daemon(
move || {
let ctx = tor_health_ctx.clone();
let client = tor_client.clone();
async move { tor_health_check(&client, &ctx.net_controller.tor).await }
},
Duration::from_secs(300),
rpc_ctx.shutdown.subscribe(),
);
embassy::sound::CHIME.play().await?;
futures::try_join!(
server
.map_err(|e| Error::new(e, ErrorKind::Network))
.map_ok(|_| tracing::debug!("RPC Server Shutdown")),
metrics_task
.map_err(|e| Error::new(
eyre!("{}", e).wrap_err("Metrics daemon panicked!"),
ErrorKind::Unknown
))
.map_ok(|_| tracing::debug!("Metrics daemon Shutdown")),
revision_cache_task
.map_err(|e| Error::new(
eyre!("{}", e).wrap_err("Revision Cache daemon panicked!"),
ErrorKind::Unknown
))
.map_ok(|_| tracing::debug!("Revision Cache daemon Shutdown")),
ws_server
.map_err(|e| Error::new(e, ErrorKind::Network))
.map_ok(|_| tracing::debug!("WebSocket Server Shutdown")),
file_server
.map_err(|e| Error::new(e, ErrorKind::Network))
.map_ok(|_| tracing::debug!("Static File Server Shutdown")),
tor_health_daemon
.map_err(|e| Error::new(
e.wrap_err("Tor Health daemon panicked!"),
ErrorKind::Unknown
))
.map_ok(|_| tracing::debug!("Tor Health daemon Shutdown")),
)?;
let mut shutdown = shutdown_recv
.recv()
.await
.with_kind(crate::ErrorKind::Unknown)?;
sig_handler.abort();
if let Some(shutdown) = &mut shutdown {
drop(shutdown.db_handle.take());
}
(rpc_ctx, shutdown)
};
rpc_ctx.shutdown().await?;
Ok(shutdown)
}
fn main() {
let matches = clap::App::new("embassyd")
.arg(
clap::Arg::with_name("config")
.short("c")
.long("config")
.takes_value(true),
)
.get_matches();
EmbassyLogger::init();
let cfg_path = matches.value_of("config");
let res = {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("failed to initialize runtime");
rt.block_on(async {
match inner_main(cfg_path).await {
Ok(a) => Ok(a),
Err(e) => {
(|| async {
tracing::error!("{}", e.source);
tracing::debug!("{:?}", e.source);
embassy::sound::BEETHOVEN.play().await?;
#[cfg(feature = "avahi")]
let _mdns = MdnsController::init();
tokio::fs::write(
"/etc/nginx/sites-available/default",
include_str!("../nginx/diagnostic-ui.conf"),
)
.await
.with_ctx(|_| {
(
embassy::ErrorKind::Filesystem,
"/etc/nginx/sites-available/default",
)
})?;
Command::new("systemctl")
.arg("reload")
.arg("nginx")
.invoke(embassy::ErrorKind::Nginx)
.await?;
let ctx = DiagnosticContext::init(
cfg_path,
if tokio::fs::metadata("/embassy-os/disk.guid").await.is_ok() {
Some(Arc::new(
tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
.await?
.trim()
.to_owned(),
))
} else {
None
},
e,
)
.await?;
rpc_server!({
command: embassy::diagnostic_api,
context: ctx.clone(),
status: status_fn,
middleware: [
cors,
diagnostic,
]
})
.with_graceful_shutdown({
let mut shutdown = ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
})
.await
.with_kind(embassy::ErrorKind::Network)?;
Ok::<_, Error>(None)
})()
.await
}
}
})
};
match res {
Ok(None) => (),
Ok(Some(s)) => s.execute(),
Err(e) => {
eprintln!("{}", e.source);
tracing::debug!("{:?}", e.source);
drop(e.source);
std::process::exit(e.kind as i32)
}
}
}

View File

@@ -1,114 +0,0 @@
use std::collections::{BTreeMap, BTreeSet};
use color_eyre::eyre::eyre;
use nix::sys::signal::Signal;
use patch_db::HasModel;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use super::{Config, ConfigSpec};
use crate::action::ActionImplementation;
use crate::context::RpcContext;
use crate::dependencies::Dependencies;
use crate::id::ImageId;
use crate::s9pk::manifest::PackageId;
use crate::status::health_check::HealthCheckId;
use crate::util::Version;
use crate::volume::Volumes;
use crate::{Error, ResultExt};
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct ConfigRes {
pub config: Option<Config>,
pub spec: ConfigSpec,
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)]
pub struct ConfigActions {
pub get: ActionImplementation,
pub set: ActionImplementation,
}
impl ConfigActions {
#[instrument]
pub fn validate(&self, volumes: &Volumes, image_ids: &BTreeSet<ImageId>) -> Result<(), Error> {
self.get
.validate(volumes, image_ids, true)
.with_ctx(|_| (crate::ErrorKind::ValidateS9pk, "Config Get"))?;
self.set
.validate(volumes, image_ids, true)
.with_ctx(|_| (crate::ErrorKind::ValidateS9pk, "Config Set"))?;
Ok(())
}
#[instrument(skip(ctx))]
pub async fn get(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
volumes: &Volumes,
) -> Result<ConfigRes, Error> {
self.get
.execute(
ctx,
pkg_id,
pkg_version,
Some("GetConfig"),
volumes,
None::<()>,
false,
None,
)
.await
.and_then(|res| {
res.map_err(|e| Error::new(eyre!("{}", e.1), crate::ErrorKind::ConfigGen))
})
}
#[instrument(skip(ctx))]
pub async fn set(
&self,
ctx: &RpcContext,
pkg_id: &PackageId,
pkg_version: &Version,
dependencies: &Dependencies,
volumes: &Volumes,
input: &Config,
) -> Result<SetResult, Error> {
let res: SetResult = self
.set
.execute(
ctx,
pkg_id,
pkg_version,
Some("SetConfig"),
volumes,
Some(input),
false,
None,
)
.await
.and_then(|res| {
res.map_err(|e| {
Error::new(eyre!("{}", e.1), crate::ErrorKind::ConfigRulesViolation)
})
})?;
Ok(SetResult {
signal: res.signal,
depends_on: res
.depends_on
.into_iter()
.filter(|(pkg, _)| dependencies.0.contains_key(pkg))
.collect(),
})
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct SetResult {
#[serde(deserialize_with = "crate::util::serde::deserialize_from_str_opt")]
#[serde(serialize_with = "crate::util::serde::serialize_display_opt")]
pub signal: Option<Signal>,
pub depends_on: BTreeMap<PackageId, BTreeSet<HealthCheckId>>,
}

View File

@@ -1,570 +0,0 @@
use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use std::time::Duration;
use color_eyre::eyre::eyre;
use futures::future::{BoxFuture, FutureExt};
use indexmap::IndexSet;
use itertools::Itertools;
use patch_db::{DbHandle, LockType};
use rand::SeedableRng;
use regex::Regex;
use rpc_toolkit::command;
use serde_json::Value;
use tracing::instrument;
use crate::context::RpcContext;
use crate::db::model::CurrentDependencyInfo;
use crate::db::util::WithRevision;
use crate::dependencies::{
add_dependent_to_current_dependents_lists, break_transitive, heal_all_dependents_transitive,
BreakageRes, DependencyError, DependencyErrors, TaggedDependencyError,
};
use crate::install::cleanup::remove_from_current_dependents_lists;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::util::display_none;
use crate::util::serde::{display_serializable, parse_stdin_deserializable, IoFormat};
use crate::{Error, ResultExt as _};
pub mod action;
pub mod spec;
pub mod util;
pub use spec::{ConfigSpec, Defaultable};
use util::NumRange;
use self::action::ConfigRes;
use self::spec::{PackagePointerSpec, ValueSpecPointer};
pub type Config = serde_json::Map<String, Value>;
pub trait TypeOf {
fn type_of(&self) -> &'static str;
}
impl TypeOf for Value {
fn type_of(&self) -> &'static str {
match self {
Value::Array(_) => "list",
Value::Bool(_) => "boolean",
Value::Null => "null",
Value::Number(_) => "number",
Value::Object(_) => "object",
Value::String(_) => "string",
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ConfigurationError {
#[error("Timeout Error")]
TimeoutError(#[from] TimeoutError),
#[error("No Match: {0}")]
NoMatch(#[from] NoMatchWithPath),
#[error("System Error: {0}")]
SystemError(Error),
#[error("Permission Denied: {0}")]
PermissionDenied(ValueSpecPointer),
}
impl From<ConfigurationError> for Error {
fn from(err: ConfigurationError) -> Self {
let kind = match &err {
ConfigurationError::SystemError(e) => e.kind,
_ => crate::ErrorKind::ConfigGen,
};
crate::Error::new(err, kind)
}
}
#[derive(Clone, Copy, Debug, thiserror::Error)]
#[error("Timeout Error")]
pub struct TimeoutError;
#[derive(Clone, Debug, thiserror::Error)]
pub struct NoMatchWithPath {
pub path: Vec<String>,
pub error: MatchError,
}
impl NoMatchWithPath {
pub fn new(error: MatchError) -> Self {
NoMatchWithPath {
path: Vec::new(),
error,
}
}
pub fn prepend(mut self, seg: String) -> Self {
self.path.push(seg);
self
}
}
impl std::fmt::Display for NoMatchWithPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.path.iter().rev().join("."), self.error)
}
}
impl From<NoMatchWithPath> for Error {
fn from(e: NoMatchWithPath) -> Self {
ConfigurationError::from(e).into()
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MatchError {
#[error("String {0:?} Does Not Match Pattern {1}")]
Pattern(String, Regex),
#[error("String {0:?} Is Not In Enum {1:?}")]
Enum(String, IndexSet<String>),
#[error("Field Is Not Nullable")]
NotNullable,
#[error("Length Mismatch: expected {0}, actual: {1}")]
LengthMismatch(NumRange<usize>, usize),
#[error("Invalid Type: expected {0}, actual: {1}")]
InvalidType(&'static str, &'static str),
#[error("Number Out Of Range: expected {0}, actual: {1}")]
OutOfRange(NumRange<f64>, f64),
#[error("Number Is Not Integral: {0}")]
NonIntegral(f64),
#[error("Variant {0:?} Is Not In Union {1:?}")]
Union(String, IndexSet<String>),
#[error("Variant Is Missing Tag {0:?}")]
MissingTag(String),
#[error("Property {0:?} Of Variant {1:?} Conflicts With Union Tag")]
PropertyMatchesUnionTag(String, String),
#[error("Name of Property {0:?} Conflicts With Map Tag Name")]
PropertyNameMatchesMapTag(String),
#[error("Pointer Is Invalid: {0}")]
InvalidPointer(spec::ValueSpecPointer),
#[error("Object Key Is Invalid: {0}")]
InvalidKey(String),
#[error("Value In List Is Not Unique")]
ListUniquenessViolation,
}
#[command(rename = "config-spec", cli_only, blocking, display(display_none))]
pub fn verify_spec(#[arg] path: PathBuf) -> Result<(), Error> {
let mut file = std::fs::File::open(&path)?;
let format = match path.extension().and_then(|s| s.to_str()) {
Some("yaml") | Some("yml") => IoFormat::Yaml,
Some("json") => IoFormat::Json,
Some("toml") => IoFormat::Toml,
Some("cbor") => IoFormat::Cbor,
_ => {
return Err(Error::new(
eyre!("Unknown file format. Expected one of yaml, json, toml, cbor."),
crate::ErrorKind::Deserialization,
));
}
};
let _: ConfigSpec = format.from_reader(&mut file)?;
Ok(())
}
#[command(subcommands(get, set))]
pub fn config(#[arg] id: PackageId) -> Result<PackageId, Error> {
Ok(id)
}
#[command(display(display_serializable))]
#[instrument(skip(ctx))]
pub async fn get(
#[context] ctx: RpcContext,
#[parent_data] id: PackageId,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<ConfigRes, Error> {
let mut db = ctx.db.handle();
let pkg_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|m| m.installed())
.expect(&mut db)
.await
.with_kind(crate::ErrorKind::NotFound)?;
let action = pkg_model
.clone()
.manifest()
.config()
.get(&mut db, true)
.await?
.to_owned()
.ok_or_else(|| Error::new(eyre!("{} has no config", id), crate::ErrorKind::NotFound))?;
let version = pkg_model
.clone()
.manifest()
.version()
.get(&mut db, true)
.await?;
let volumes = pkg_model.manifest().volumes().get(&mut db, true).await?;
action.get(&ctx, &id, &*version, &*volumes).await
}
#[command(
subcommands(self(set_impl(async, context(RpcContext))), set_dry),
display(display_none)
)]
#[instrument]
pub fn set(
#[parent_data] id: PackageId,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
#[arg(long = "timeout")] timeout: Option<crate::util::serde::Duration>,
#[arg(stdin, parse(parse_stdin_deserializable))] config: Option<Config>,
#[arg(rename = "expire-id", long = "expire-id")] expire_id: Option<String>,
) -> Result<(PackageId, Option<Config>, Option<Duration>, Option<String>), Error> {
Ok((id, config, timeout.map(|d| *d), expire_id))
}
#[command(rename = "dry", display(display_serializable))]
#[instrument(skip(ctx))]
pub async fn set_dry(
#[context] ctx: RpcContext,
#[parent_data] (id, config, timeout, _): (
PackageId,
Option<Config>,
Option<Duration>,
Option<String>,
),
) -> Result<BreakageRes, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
configure(
&ctx,
&mut tx,
&id,
config,
&timeout,
true,
&mut BTreeMap::new(),
&mut breakages,
)
.await?;
crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.expect(&mut tx)
.await?
.installed()
.expect(&mut tx)
.await?
.status()
.configured()
.put(&mut tx, &true)
.await?;
tx.abort().await?;
Ok(BreakageRes(breakages))
}
#[instrument(skip(ctx))]
pub async fn set_impl(
ctx: RpcContext,
(id, config, timeout, expire_id): (PackageId, Option<Config>, Option<Duration>, Option<String>),
) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
configure(
&ctx,
&mut tx,
&id,
config,
&timeout,
false,
&mut BTreeMap::new(),
&mut breakages,
)
.await?;
Ok(WithRevision {
response: (),
revision: tx.commit(expire_id).await?,
})
}
#[instrument(skip(ctx, db))]
pub async fn configure<Db: DbHandle>(
ctx: &RpcContext,
db: &mut Db,
id: &PackageId,
config: Option<Config>,
timeout: &Option<Duration>,
dry_run: bool,
overrides: &mut BTreeMap<PackageId, Config>,
breakages: &mut BTreeMap<PackageId, TaggedDependencyError>,
) -> Result<(), Error> {
configure_rec(ctx, db, id, config, timeout, dry_run, overrides, breakages).await?;
crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.status()
.configured()
.put(db, &true)
.await?;
Ok(())
}
#[instrument(skip(ctx, db))]
pub fn configure_rec<'a, Db: DbHandle>(
ctx: &'a RpcContext,
db: &'a mut Db,
id: &'a PackageId,
config: Option<Config>,
timeout: &'a Option<Duration>,
dry_run: bool,
overrides: &'a mut BTreeMap<PackageId, Config>,
breakages: &'a mut BTreeMap<PackageId, TaggedDependencyError>,
) -> BoxFuture<'a, Result<(), Error>> {
async move {
crate::db::DatabaseModel::new()
.package_data()
.lock(db, LockType::Write)
.await?;
// fetch data from db
let pkg_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.expect(db)
.await
.with_kind(crate::ErrorKind::NotFound)?;
let action = pkg_model
.clone()
.manifest()
.config()
.get(db, true)
.await?
.to_owned()
.ok_or_else(|| Error::new(eyre!("{} has no config", id), crate::ErrorKind::NotFound))?;
let version = pkg_model.clone().manifest().version().get(db, true).await?;
let dependencies = pkg_model
.clone()
.manifest()
.dependencies()
.get(db, true)
.await?;
let volumes = pkg_model.clone().manifest().volumes().get(db, true).await?;
let is_needs_config = !*pkg_model
.clone()
.status()
.configured()
.get(db, true)
.await?;
// get current config and current spec
let ConfigRes {
config: old_config,
spec,
} = action.get(ctx, id, &*version, &*volumes).await?;
// determine new config to use
let mut config = if let Some(config) = config.or_else(|| old_config.clone()) {
config
} else {
spec.gen(&mut rand::rngs::StdRng::from_entropy(), timeout)?
};
let manifest = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.map::<_, Manifest>(|i| i.manifest())
.expect(db)
.await?
.get(db, true)
.await
.with_kind(crate::ErrorKind::NotFound)?;
spec.validate(&*manifest)?;
spec.matches(&config)?; // check that new config matches spec
spec.update(ctx, db, &*manifest, &*overrides, &mut config)
.await?; // dereference pointers in the new config
// create backreferences to pointers
let mut sys = pkg_model.clone().system_pointers().get_mut(db).await?;
sys.truncate(0);
let mut current_dependencies: BTreeMap<PackageId, CurrentDependencyInfo> = dependencies
.0
.iter()
.filter_map(|(id, info)| {
if info.requirement.required() {
Some((id.clone(), CurrentDependencyInfo::default()))
} else {
None
}
})
.collect();
for ptr in spec.pointers(&config)? {
match ptr {
ValueSpecPointer::Package(pkg_ptr) => {
if let Some(current_dependency) =
current_dependencies.get_mut(pkg_ptr.package_id())
{
current_dependency.pointers.push(pkg_ptr);
} else {
current_dependencies.insert(
pkg_ptr.package_id().to_owned(),
CurrentDependencyInfo {
pointers: vec![pkg_ptr],
health_checks: BTreeSet::new(),
},
);
}
}
ValueSpecPointer::System(s) => sys.push(s),
}
}
sys.save(db).await?;
let signal = if !dry_run {
// run config action
let res = action
.set(ctx, id, &*version, &*dependencies, &*volumes, &config)
.await?;
// track dependencies with no pointers
for (package_id, health_checks) in res.depends_on.into_iter() {
if let Some(current_dependency) = current_dependencies.get_mut(&package_id) {
current_dependency.health_checks.extend(health_checks);
} else {
current_dependencies.insert(
package_id,
CurrentDependencyInfo {
pointers: Vec::new(),
health_checks,
},
);
}
}
// track dependency health checks
current_dependencies = current_dependencies
.into_iter()
.filter(|(dep_id, _)| {
if dep_id != id && !manifest.dependencies.0.contains_key(dep_id) {
tracing::warn!("Illegal dependency specified: {}", dep_id);
false
} else {
true
}
})
.collect();
res.signal
} else {
None
};
// update dependencies
let mut deps = pkg_model.clone().current_dependencies().get_mut(db).await?;
remove_from_current_dependents_lists(db, id, deps.keys()).await?; // remove previous
add_dependent_to_current_dependents_lists(db, id, &current_dependencies).await?; // add new
current_dependencies.remove(id);
*deps = current_dependencies.clone();
deps.save(db).await?;
let mut errs = pkg_model
.clone()
.status()
.dependency_errors()
.get_mut(db)
.await?;
*errs = DependencyErrors::init(ctx, db, &*manifest, &current_dependencies).await?;
errs.save(db).await?;
// cache current config for dependents
overrides.insert(id.clone(), config.clone());
// handle dependents
let dependents = pkg_model.clone().current_dependents().get(db, true).await?;
let prev = if is_needs_config { None } else { old_config }
.map(Value::Object)
.unwrap_or_default();
let next = Value::Object(config.clone());
for (dependent, dep_info) in dependents.iter().filter(|(dep_id, _)| dep_id != &id) {
// check if config passes dependent check
let dependent_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependent)
.and_then(|pkg| pkg.installed())
.expect(db)
.await?;
if let Some(cfg) = &*dependent_model
.clone()
.manifest()
.dependencies()
.idx_model(id)
.expect(db)
.await?
.config()
.get(db, true)
.await?
{
let manifest = dependent_model.clone().manifest().get(db, true).await?;
if let Err(error) = cfg
.check(
ctx,
dependent,
&manifest.version,
&manifest.volumes,
&config,
)
.await?
{
let dep_err = DependencyError::ConfigUnsatisfied { error };
break_transitive(db, dependent, id, dep_err, breakages).await?;
}
// handle backreferences
for ptr in &dep_info.pointers {
if let PackagePointerSpec::Config(cfg_ptr) = ptr {
if cfg_ptr.select(&next) != cfg_ptr.select(&prev) {
if let Err(e) = configure_rec(
ctx, db, dependent, None, timeout, dry_run, overrides, breakages,
)
.await
{
if e.kind == crate::ErrorKind::ConfigRulesViolation {
break_transitive(
db,
dependent,
id,
DependencyError::ConfigUnsatisfied {
error: format!("{}", e),
},
breakages,
)
.await?;
} else {
return Err(e);
}
}
}
}
}
heal_all_dependents_transitive(ctx, db, id).await?;
}
}
if let Some(signal) = signal {
match ctx.managers.get(&(id.clone(), version.clone())).await {
None => {
// in theory this should never happen, which indicates this function should be moved behind the
// Manager interface
return Err(Error::new(
eyre!("Manager Not Found for package being configured"),
crate::ErrorKind::Incoherent,
));
}
Some(m) => {
m.signal(&signal).await?;
}
}
}
Ok(())
}
.boxed()
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,368 +0,0 @@
use std::borrow::Cow;
use std::ops::{Bound, RangeBounds, RangeInclusive};
use rand::distributions::Distribution;
use rand::Rng;
use serde_json::Value;
use super::Config;
pub const STATIC_NULL: Value = Value::Null;
#[derive(Clone, Debug)]
pub struct CharSet(pub Vec<(RangeInclusive<char>, usize)>, usize);
impl CharSet {
pub fn contains(&self, c: &char) -> bool {
self.0.iter().any(|r| r.0.contains(c))
}
pub fn gen<R: Rng>(&self, rng: &mut R) -> char {
let mut idx = rng.gen_range(0, self.1);
for r in &self.0 {
if idx < r.1 {
return std::convert::TryFrom::try_from(
rand::distributions::Uniform::new_inclusive(
u32::from(*r.0.start()),
u32::from(*r.0.end()),
)
.sample(rng),
)
.unwrap();
} else {
idx -= r.1;
}
}
unreachable!()
}
}
impl Default for CharSet {
fn default() -> Self {
CharSet(vec![('!'..='~', 94)], 94)
}
}
impl<'de> serde::de::Deserialize<'de> for CharSet {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let mut res = Vec::new();
let mut len = 0;
let mut a: Option<char> = None;
let mut b: Option<char> = None;
let mut in_range = false;
for c in s.chars() {
match c {
',' => match (a, b, in_range) {
(Some(start), Some(end), _) => {
if !end.is_ascii() {
return Err(serde::de::Error::custom("Invalid Character"));
}
if start >= end {
return Err(serde::de::Error::custom("Invalid Bounds"));
}
let l = u32::from(end) - u32::from(start) + 1;
res.push((start..=end, l as usize));
len += l as usize;
a = None;
b = None;
in_range = false;
}
(Some(start), None, false) => {
len += 1;
res.push((start..=start, 1));
a = None;
}
(Some(_), None, true) => {
b = Some(',');
}
(None, None, false) => {
a = Some(',');
}
_ => {
return Err(serde::de::Error::custom("Syntax Error"));
}
},
'-' => {
if a.is_none() {
a = Some('-');
} else if !in_range {
in_range = true;
} else if b.is_none() {
b = Some('-')
} else {
return Err(serde::de::Error::custom("Syntax Error"));
}
}
_ => {
if a.is_none() {
a = Some(c);
} else if in_range && b.is_none() {
b = Some(c);
} else {
return Err(serde::de::Error::custom("Syntax Error"));
}
}
}
}
match (a, b) {
(Some(start), Some(end)) => {
if !end.is_ascii() {
return Err(serde::de::Error::custom("Invalid Character"));
}
if start >= end {
return Err(serde::de::Error::custom("Invalid Bounds"));
}
let l = u32::from(end) - u32::from(start) + 1;
res.push((start..=end, l as usize));
len += l as usize;
}
(Some(c), None) => {
len += 1;
res.push((c..=c, 1));
}
_ => (),
}
Ok(CharSet(res, len))
}
}
impl serde::ser::Serialize for CharSet {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
<&str>::serialize(
&self
.0
.iter()
.map(|r| match r.1 {
1 => format!("{}", r.0.start()),
_ => format!("{}-{}", r.0.start(), r.0.end()),
})
.collect::<Vec<_>>()
.join(",")
.as_str(),
serializer,
)
}
}
pub mod serde_regex {
use regex::Regex;
use serde::*;
pub fn serialize<S>(regex: &Regex, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
<&str>::serialize(&regex.as_str(), serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Regex, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Regex::new(&s).map_err(|e| de::Error::custom(e))
}
}
#[derive(Clone, Debug)]
pub struct NumRange<T: std::str::FromStr + std::fmt::Display + std::cmp::PartialOrd>(
pub (Bound<T>, Bound<T>),
);
impl<T> std::ops::Deref for NumRange<T>
where
T: std::str::FromStr + std::fmt::Display + std::cmp::PartialOrd,
{
type Target = (Bound<T>, Bound<T>);
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'de, T> serde::de::Deserialize<'de> for NumRange<T>
where
T: std::str::FromStr + std::fmt::Display + std::cmp::PartialOrd,
<T as std::str::FromStr>::Err: std::fmt::Display,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let mut split = s.split(",");
let start = split
.next()
.map(|s| match s.get(..1) {
Some("(") => match s.get(1..2) {
Some("*") => Ok(Bound::Unbounded),
_ => s[1..]
.trim()
.parse()
.map(Bound::Excluded)
.map_err(|e| serde::de::Error::custom(e)),
},
Some("[") => s[1..]
.trim()
.parse()
.map(Bound::Included)
.map_err(|e| serde::de::Error::custom(e)),
_ => Err(serde::de::Error::custom(format!(
"Could not parse left bound: {}",
s
))),
})
.transpose()?
.unwrap();
let end = split
.next()
.map(|s| match s.get(s.len() - 1..) {
Some(")") => match s.get(s.len() - 2..s.len() - 1) {
Some("*") => Ok(Bound::Unbounded),
_ => s[..s.len() - 1]
.trim()
.parse()
.map(Bound::Excluded)
.map_err(|e| serde::de::Error::custom(e)),
},
Some("]") => s[..s.len() - 1]
.trim()
.parse()
.map(Bound::Included)
.map_err(|e| serde::de::Error::custom(e)),
_ => Err(serde::de::Error::custom(format!(
"Could not parse right bound: {}",
s
))),
})
.transpose()?
.unwrap_or(Bound::Unbounded);
Ok(NumRange((start, end)))
}
}
impl<T> std::fmt::Display for NumRange<T>
where
T: std::str::FromStr + std::fmt::Display + std::cmp::PartialOrd,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.start_bound() {
Bound::Excluded(n) => write!(f, "({},", n)?,
Bound::Included(n) => write!(f, "[{},", n)?,
Bound::Unbounded => write!(f, "(*,")?,
};
match self.end_bound() {
Bound::Excluded(n) => write!(f, "{})", n),
Bound::Included(n) => write!(f, "{}]", n),
Bound::Unbounded => write!(f, "*)"),
}
}
}
impl<T> serde::ser::Serialize for NumRange<T>
where
T: std::str::FromStr + std::fmt::Display + std::cmp::PartialOrd,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
<&str>::serialize(&format!("{}", self).as_str(), serializer)
}
}
#[derive(Clone, Debug)]
pub enum UniqueBy {
Any(Vec<UniqueBy>),
All(Vec<UniqueBy>),
Exactly(String),
NotUnique,
}
impl UniqueBy {
pub fn eq(&self, lhs: &Config, rhs: &Config) -> bool {
match self {
UniqueBy::Any(any) => any.iter().any(|u| u.eq(lhs, rhs)),
UniqueBy::All(all) => all.iter().all(|u| u.eq(lhs, rhs)),
UniqueBy::Exactly(key) => lhs.get(key) == rhs.get(key),
UniqueBy::NotUnique => false,
}
}
}
impl Default for UniqueBy {
fn default() -> Self {
UniqueBy::NotUnique
}
}
impl<'de> serde::de::Deserialize<'de> for UniqueBy {
fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = UniqueBy;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a key, an \"any\" object, or an \"all\" object")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
Ok(UniqueBy::Exactly(v.to_owned()))
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
Ok(UniqueBy::Exactly(v))
}
fn visit_map<A: serde::de::MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let mut variant = None;
while let Some(key) = map.next_key::<Cow<str>>()? {
match key.as_ref() {
"any" => {
return Ok(UniqueBy::Any(map.next_value()?));
}
"all" => {
return Ok(UniqueBy::All(map.next_value()?));
}
_ => {
variant = Some(key);
}
}
}
Err(serde::de::Error::unknown_variant(
variant.unwrap_or_default().as_ref(),
&["any", "all"],
))
}
fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
Ok(UniqueBy::NotUnique)
}
fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
Ok(UniqueBy::NotUnique)
}
}
deserializer.deserialize_any(Visitor)
}
}
impl serde::ser::Serialize for UniqueBy {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeMap;
match self {
UniqueBy::Any(any) => {
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_key("any")?;
map.serialize_value(any)?;
map.end()
}
UniqueBy::All(all) => {
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_key("all")?;
map.serialize_value(all)?;
map.end()
}
UniqueBy::Exactly(key) => serializer.serialize_str(key),
UniqueBy::NotUnique => serializer.serialize_unit(),
}
}
}

View File

@@ -1,151 +0,0 @@
use std::fs::File;
use std::io::BufReader;
use std::net::{Ipv4Addr, SocketAddr};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use cookie_store::CookieStore;
use reqwest::Proxy;
use reqwest_cookie_store::CookieStoreMutex;
use rpc_toolkit::reqwest::{Client, Url};
use rpc_toolkit::url::Host;
use rpc_toolkit::Context;
use serde::Deserialize;
use tracing::instrument;
use crate::ResultExt;
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct CliContextConfig {
pub bind_rpc: Option<SocketAddr>,
pub host: Option<Url>,
#[serde(deserialize_with = "crate::util::serde::deserialize_from_str_opt")]
pub proxy: Option<Url>,
pub cookie_path: Option<PathBuf>,
}
#[derive(Debug)]
pub struct CliContextSeed {
pub base_url: Url,
pub rpc_url: Url,
pub client: Client,
pub cookie_store: Arc<CookieStoreMutex>,
pub cookie_path: PathBuf,
}
impl Drop for CliContextSeed {
fn drop(&mut self) {
let tmp = format!("{}.tmp", self.cookie_path.display());
let mut writer = fd_lock_rs::FdLock::lock(
File::create(&tmp).unwrap(),
fd_lock_rs::LockType::Exclusive,
true,
)
.unwrap();
let store = self.cookie_store.lock().unwrap();
store.save_json(&mut *writer).unwrap();
writer.sync_all().unwrap();
std::fs::rename(tmp, &self.cookie_path).unwrap();
}
}
const DEFAULT_HOST: Host<&'static str> = Host::Ipv4(Ipv4Addr::new(127, 0, 0, 1));
const DEFAULT_PORT: u16 = 5959;
#[derive(Debug, Clone)]
pub struct CliContext(Arc<CliContextSeed>);
impl CliContext {
/// BLOCKING
#[instrument(skip(matches))]
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
let cfg_path = Path::new(matches.value_of("config").unwrap_or(crate::CONFIG_PATH));
let base = if cfg_path.exists() {
serde_yaml::from_reader(
File::open(cfg_path)
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?,
)
.with_kind(crate::ErrorKind::Deserialization)?
} else {
CliContextConfig::default()
};
let mut url = if let Some(host) = matches.value_of("host") {
host.parse()?
} else if let Some(host) = base.host {
host
} else {
format!(
"http://{}",
base.bind_rpc.unwrap_or(([127, 0, 0, 1], 80).into())
)
.parse()?
};
let proxy = if let Some(proxy) = matches.value_of("proxy") {
Some(proxy.parse()?)
} else {
base.proxy
};
let cookie_path = base.cookie_path.unwrap_or_else(|| {
cfg_path
.parent()
.unwrap_or(Path::new("/"))
.join(".cookies.json")
});
let cookie_store = Arc::new(CookieStoreMutex::new(if cookie_path.exists() {
CookieStore::load_json(BufReader::new(File::open(&cookie_path)?))
.map_err(|e| eyre!("{}", e))
.with_kind(crate::ErrorKind::Deserialization)?
} else {
CookieStore::default()
}));
Ok(CliContext(Arc::new(CliContextSeed {
base_url: url.clone(),
rpc_url: {
url.path_segments_mut()
.map_err(|_| eyre!("Url cannot be base"))
.with_kind(crate::ErrorKind::ParseUrl)?
.push("rpc")
.push("v1");
url
},
client: {
let mut builder = Client::builder().cookie_provider(cookie_store.clone());
if let Some(proxy) = proxy {
builder =
builder.proxy(Proxy::all(proxy).with_kind(crate::ErrorKind::ParseUrl)?)
}
builder.build().expect("cannot fail")
},
cookie_store,
cookie_path,
})))
}
}
impl std::ops::Deref for CliContext {
type Target = CliContextSeed;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl Context for CliContext {
fn protocol(&self) -> &str {
self.0.base_url.scheme()
}
fn host(&self) -> Host<&str> {
self.0.base_url.host().unwrap_or(DEFAULT_HOST)
}
fn port(&self) -> u16 {
self.0.base_url.port().unwrap_or(DEFAULT_PORT)
}
fn path(&self) -> &str {
self.0.rpc_url.path()
}
fn url(&self) -> Url {
self.0.rpc_url.clone()
}
fn client(&self) -> &Client {
&self.0.client
}
}

View File

@@ -1,95 +0,0 @@
use std::net::{IpAddr, SocketAddr};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::Context;
use serde::Deserialize;
use tokio::fs::File;
use tokio::sync::broadcast::Sender;
use tracing::instrument;
use url::Host;
use crate::shutdown::Shutdown;
use crate::util::io::from_toml_async_reader;
use crate::util::AsyncFileExt;
use crate::{Error, ResultExt};
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct DiagnosticContextConfig {
pub bind_rpc: Option<SocketAddr>,
pub datadir: Option<PathBuf>,
}
impl DiagnosticContextConfig {
#[instrument(skip(path))]
pub async fn load<P: AsRef<Path>>(path: Option<P>) -> Result<Self, Error> {
let cfg_path = path
.as_ref()
.map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?
{
from_toml_async_reader(f).await
} else {
Ok(Self::default())
}
}
pub fn datadir(&self) -> &Path {
self.datadir
.as_deref()
.unwrap_or_else(|| Path::new("/embassy-data"))
}
}
pub struct DiagnosticContextSeed {
pub bind_rpc: SocketAddr,
pub datadir: PathBuf,
pub shutdown: Sender<Option<Shutdown>>,
pub error: Arc<RpcError>,
pub disk_guid: Option<Arc<String>>,
}
#[derive(Clone)]
pub struct DiagnosticContext(Arc<DiagnosticContextSeed>);
impl DiagnosticContext {
#[instrument(skip(path))]
pub async fn init<P: AsRef<Path>>(
path: Option<P>,
disk_guid: Option<Arc<String>>,
error: Error,
) -> Result<Self, Error> {
let cfg = DiagnosticContextConfig::load(path).await?;
let (shutdown, _) = tokio::sync::broadcast::channel(1);
Ok(Self(Arc::new(DiagnosticContextSeed {
bind_rpc: cfg.bind_rpc.unwrap_or(([127, 0, 0, 1], 5959).into()),
datadir: cfg.datadir().to_owned(),
shutdown,
disk_guid,
error: Arc::new(error.into()),
})))
}
}
impl Context for DiagnosticContext {
fn host(&self) -> Host<&str> {
match self.0.bind_rpc.ip() {
IpAddr::V4(a) => Host::Ipv4(a),
IpAddr::V6(a) => Host::Ipv6(a),
}
}
fn port(&self) -> u16 {
self.0.bind_rpc.port()
}
}
impl Deref for DiagnosticContext {
type Target = DiagnosticContextSeed;
fn deref(&self) -> &Self::Target {
&*self.0
}
}

View File

@@ -1,37 +0,0 @@
pub mod cli;
pub mod diagnostic;
pub mod rpc;
pub mod sdk;
pub mod setup;
pub use cli::CliContext;
pub use diagnostic::DiagnosticContext;
pub use rpc::RpcContext;
pub use sdk::SdkContext;
pub use setup::SetupContext;
impl From<CliContext> for () {
fn from(_: CliContext) -> Self {
()
}
}
impl From<DiagnosticContext> for () {
fn from(_: DiagnosticContext) -> Self {
()
}
}
impl From<RpcContext> for () {
fn from(_: RpcContext) -> Self {
()
}
}
impl From<SdkContext> for () {
fn from(_: SdkContext) -> Self {
()
}
}
impl From<SetupContext> for () {
fn from(_: SetupContext) -> Self {
()
}
}

View File

@@ -1,350 +0,0 @@
use std::collections::{BTreeMap, VecDeque};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
use bollard::Docker;
use color_eyre::eyre::eyre;
use patch_db::json_ptr::JsonPointer;
use patch_db::{DbHandle, LockType, PatchDb, Revision};
use reqwest::Url;
use rpc_toolkit::url::Host;
use rpc_toolkit::Context;
use serde::Deserialize;
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::SqlitePool;
use tokio::fs::File;
use tokio::process::Command;
use tokio::sync::{broadcast, oneshot, Mutex, RwLock};
use tracing::instrument;
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
use crate::db::model::{Database, InstalledPackageDataEntry, PackageDataEntry};
use crate::hostname::{derive_hostname, derive_id, get_product_key};
use crate::install::cleanup::{cleanup_failed, uninstall};
use crate::manager::ManagerMap;
use crate::middleware::auth::HashSessionToken;
use crate::net::tor::os_key;
use crate::net::wifi::WpaCli;
use crate::net::NetController;
use crate::notifications::NotificationManager;
use crate::setup::password_hash;
use crate::shutdown::Shutdown;
use crate::status::{MainStatus, Status};
use crate::util::io::from_yaml_async_reader;
use crate::util::{AsyncFileExt, Invoke};
use crate::{Error, ResultExt};
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct RpcContextConfig {
pub bind_rpc: Option<SocketAddr>,
pub bind_ws: Option<SocketAddr>,
pub bind_static: Option<SocketAddr>,
pub tor_control: Option<SocketAddr>,
pub tor_socks: Option<SocketAddr>,
pub revision_cache_size: Option<usize>,
pub datadir: Option<PathBuf>,
pub log_server: Option<Url>,
}
impl RpcContextConfig {
pub async fn load<P: AsRef<Path>>(path: Option<P>) -> Result<Self, Error> {
let cfg_path = path
.as_ref()
.map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?
{
from_yaml_async_reader(f).await
} else {
Ok(Self::default())
}
}
pub fn datadir(&self) -> &Path {
self.datadir
.as_deref()
.unwrap_or_else(|| Path::new("/embassy-data"))
}
pub async fn db(&self, secret_store: &SqlitePool, product_key: &str) -> Result<PatchDb, Error> {
let sid = derive_id(product_key);
let hostname = derive_hostname(&sid);
let db_path = self.datadir().join("main").join("embassy.db");
let db = PatchDb::open(&db_path)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, db_path.display().to_string()))?;
if !db.exists(&<JsonPointer>::default()).await? {
db.put(
&<JsonPointer>::default(),
&Database::init(
sid,
&hostname,
&os_key(&mut secret_store.acquire().await?).await?,
password_hash(&mut secret_store.acquire().await?).await?,
),
None,
)
.await?;
}
Ok(db)
}
#[instrument]
pub async fn secret_store(&self) -> Result<SqlitePool, Error> {
let secret_store = SqlitePool::connect_with(
SqliteConnectOptions::new()
.filename(self.datadir().join("main").join("secrets.db"))
.create_if_missing(true)
.busy_timeout(Duration::from_secs(30)),
)
.await?;
sqlx::migrate!()
.run(&secret_store)
.await
.with_kind(crate::ErrorKind::Database)?;
Ok(secret_store)
}
}
pub struct RpcContextSeed {
is_closed: AtomicBool,
pub bind_rpc: SocketAddr,
pub bind_ws: SocketAddr,
pub bind_static: SocketAddr,
pub datadir: PathBuf,
pub disk_guid: Arc<String>,
pub db: PatchDb,
pub secret_store: SqlitePool,
pub docker: Docker,
pub net_controller: NetController,
pub managers: ManagerMap,
pub revision_cache_size: usize,
pub revision_cache: RwLock<VecDeque<Arc<Revision>>>,
pub metrics_cache: RwLock<Option<crate::system::Metrics>>,
pub shutdown: broadcast::Sender<Option<Shutdown>>,
pub tor_socks: SocketAddr,
pub notification_manager: NotificationManager,
pub open_authed_websockets: Mutex<BTreeMap<HashSessionToken, Vec<oneshot::Sender<()>>>>,
pub rpc_stream_continuations: Mutex<BTreeMap<RequestGuid, RpcContinuation>>,
pub wifi_manager: Arc<RwLock<WpaCli>>,
}
#[derive(Clone)]
pub struct RpcContext(Arc<RpcContextSeed>);
impl RpcContext {
#[instrument(skip(cfg_path))]
pub async fn init<P: AsRef<Path>>(
cfg_path: Option<P>,
disk_guid: Arc<String>,
) -> Result<Self, Error> {
let base = RpcContextConfig::load(cfg_path).await?;
tracing::info!("Loaded Config");
let tor_proxy = base.tor_socks.unwrap_or(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(127, 0, 0, 1),
9050,
)));
let (shutdown, _) = tokio::sync::broadcast::channel(1);
let secret_store = base.secret_store().await?;
tracing::info!("Opened Sqlite DB");
let db = base.db(&secret_store, &get_product_key().await?).await?;
tracing::info!("Opened PatchDB");
let docker = Docker::connect_with_unix_defaults()?;
tracing::info!("Connected to Docker");
let net_controller = NetController::init(
([127, 0, 0, 1], 80).into(),
crate::net::tor::os_key(&mut secret_store.acquire().await?).await?,
base.tor_control
.unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))),
secret_store.clone(),
None,
)
.await?;
tracing::info!("Initialized Net Controller");
let managers = ManagerMap::default();
let metrics_cache = RwLock::new(None);
let notification_manager = NotificationManager::new(secret_store.clone());
tracing::info!("Initialized Notification Manager");
let seed = Arc::new(RpcContextSeed {
is_closed: AtomicBool::new(false),
bind_rpc: base.bind_rpc.unwrap_or(([127, 0, 0, 1], 5959).into()),
bind_ws: base.bind_ws.unwrap_or(([127, 0, 0, 1], 5960).into()),
bind_static: base.bind_static.unwrap_or(([127, 0, 0, 1], 5961).into()),
datadir: base.datadir().to_path_buf(),
disk_guid,
db,
secret_store,
docker,
net_controller,
managers,
revision_cache_size: base.revision_cache_size.unwrap_or(512),
revision_cache: RwLock::new(VecDeque::new()),
metrics_cache,
shutdown,
tor_socks: tor_proxy,
notification_manager,
open_authed_websockets: Mutex::new(BTreeMap::new()),
rpc_stream_continuations: Mutex::new(BTreeMap::new()),
wifi_manager: Arc::new(RwLock::new(WpaCli::init("wlan0".to_string()))),
});
let res = Self(seed);
res.cleanup().await?;
tracing::info!("Cleaned up transient states");
res.managers
.init(
&res,
&mut res.db.handle(),
&mut res.secret_store.acquire().await?,
)
.await?;
tracing::info!("Initialized Package Managers");
Ok(res)
}
#[instrument(skip(self, db))]
pub async fn set_nginx_conf<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
tokio::fs::write("/etc/nginx/sites-available/default", {
let info = crate::db::DatabaseModel::new()
.server_info()
.get(db, true)
.await?;
format!(
include_str!("../nginx/main-ui.conf.template"),
lan_hostname = info.lan_address.host_str().unwrap(),
tor_hostname = info.tor_address.host_str().unwrap(),
)
})
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
"/etc/nginx/sites-available/default",
)
})?;
Command::new("systemctl")
.arg("reload")
.arg("nginx")
.invoke(crate::ErrorKind::Nginx)
.await?;
Ok(())
}
#[instrument(skip(self))]
pub async fn shutdown(self) -> Result<(), Error> {
self.managers.empty().await?;
self.secret_store.close().await;
self.is_closed.store(true, Ordering::SeqCst);
Ok(())
}
#[instrument(skip(self))]
pub async fn cleanup(&self) -> Result<(), Error> {
let mut db = self.db.handle();
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut db, LockType::Write)
.await?;
for package_id in crate::db::DatabaseModel::new()
.package_data()
.keys(&mut db, true)
.await?
{
if let Err(e) = async {
let mut pde = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&package_id)
.get_mut(&mut db)
.await?;
match pde.as_mut().ok_or_else(|| {
Error::new(
eyre!("Node does not exist: /package-data/{}", package_id),
crate::ErrorKind::Database,
)
})? {
PackageDataEntry::Installing { .. }
| PackageDataEntry::Restoring { .. }
| PackageDataEntry::Updating { .. } => {
cleanup_failed(self, &mut db, &package_id).await?;
}
PackageDataEntry::Removing { .. } => {
uninstall(
self,
&mut db,
&mut self.secret_store.acquire().await?,
&package_id,
)
.await?;
}
PackageDataEntry::Installed {
installed:
InstalledPackageDataEntry {
status: Status { main, .. },
..
},
..
} => {
let new_main = match std::mem::replace(
main,
MainStatus::Stopped, /* placeholder */
) {
MainStatus::BackingUp { started, .. } => {
if let Some(_) = started {
MainStatus::Starting
} else {
MainStatus::Stopped
}
}
MainStatus::Running { .. } => MainStatus::Starting,
a => a,
};
*main = new_main;
pde.save(&mut db).await?;
}
}
Ok::<_, Error>(())
}
.await
{
tracing::error!("Failed to clean up package {}: {}", package_id, e);
tracing::debug!("{:?}", e);
}
}
Ok(())
}
}
impl Context for RpcContext {
fn host(&self) -> Host<&str> {
match self.0.bind_rpc.ip() {
IpAddr::V4(a) => Host::Ipv4(a),
IpAddr::V6(a) => Host::Ipv6(a),
}
}
fn port(&self) -> u16 {
self.0.bind_rpc.port()
}
}
impl Deref for RpcContext {
type Target = RpcContextSeed;
fn deref(&self) -> &Self::Target {
#[cfg(feature = "unstable")]
if self.0.is_closed.load(Ordering::SeqCst) {
panic!(
"RpcContext used after shutdown! {}",
tracing_error::SpanTrace::capture()
);
}
&*self.0
}
}
impl Drop for RpcContext {
fn drop(&mut self) {
#[cfg(feature = "unstable")]
if self.0.is_closed.load(Ordering::SeqCst) {
tracing::info!(
"RpcContext dropped. {} left.",
Arc::strong_count(&self.0) - 1
);
}
}
}

View File

@@ -1,67 +0,0 @@
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use clap::ArgMatches;
use color_eyre::eyre::eyre;
use rpc_toolkit::Context;
use serde::Deserialize;
use tracing::instrument;
use crate::{Error, ResultExt};
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct SdkContextConfig {
pub developer_key_path: Option<PathBuf>,
}
#[derive(Debug)]
pub struct SdkContextSeed {
pub developer_key_path: PathBuf,
}
#[derive(Debug, Clone)]
pub struct SdkContext(Arc<SdkContextSeed>);
impl SdkContext {
/// BLOCKING
#[instrument(skip(matches))]
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
let cfg_path = Path::new(matches.value_of("config").unwrap_or(crate::CONFIG_PATH));
let base = if cfg_path.exists() {
serde_yaml::from_reader(
File::open(cfg_path)
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?,
)
.with_kind(crate::ErrorKind::Deserialization)?
} else {
SdkContextConfig::default()
};
Ok(SdkContext(Arc::new(SdkContextSeed {
developer_key_path: base.developer_key_path.unwrap_or_else(|| {
cfg_path
.parent()
.unwrap_or(Path::new("/"))
.join(".developer_key")
}),
})))
}
/// BLOCKING
#[instrument]
pub fn developer_key(&self) -> Result<ed25519_dalek::Keypair, Error> {
if !self.developer_key_path.exists() {
return Err(Error::new(eyre!("Developer Key does not exist! Please run `embassy-sdk init` before running this command."), crate::ErrorKind::Uninitialized));
}
let mut keypair_buf = [0; ed25519_dalek::KEYPAIR_LENGTH];
File::open(&self.developer_key_path)?.read_exact(&mut keypair_buf)?;
Ok(ed25519_dalek::Keypair::from_bytes(&keypair_buf)?)
}
}
impl std::ops::Deref for SdkContext {
type Target = SdkContextSeed;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl Context for SdkContext {}

View File

@@ -1,169 +0,0 @@
use std::net::{IpAddr, SocketAddr};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
use patch_db::json_ptr::JsonPointer;
use patch_db::PatchDb;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::Context;
use serde::{Deserialize, Serialize};
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::SqlitePool;
use tokio::fs::File;
use tokio::sync::broadcast::Sender;
use tokio::sync::RwLock;
use tracing::instrument;
use url::Host;
use crate::db::model::Database;
use crate::hostname::{derive_hostname, derive_id, get_product_key};
use crate::net::tor::os_key;
use crate::setup::{password_hash, RecoveryStatus};
use crate::util::io::from_yaml_async_reader;
use crate::util::AsyncFileExt;
use crate::{Error, ResultExt};
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct SetupResult {
pub tor_address: String,
pub lan_address: String,
pub root_ca: String,
}
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct SetupContextConfig {
pub bind_rpc: Option<SocketAddr>,
pub datadir: Option<PathBuf>,
}
impl SetupContextConfig {
#[instrument(skip(path))]
pub async fn load<P: AsRef<Path>>(path: Option<P>) -> Result<Self, Error> {
let cfg_path = path
.as_ref()
.map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?
{
from_yaml_async_reader(f).await
} else {
Ok(Self::default())
}
}
pub fn datadir(&self) -> &Path {
self.datadir
.as_deref()
.unwrap_or_else(|| Path::new("/embassy-data"))
}
}
pub struct SetupContextSeed {
pub config_path: Option<PathBuf>,
pub bind_rpc: SocketAddr,
pub shutdown: Sender<()>,
pub datadir: PathBuf,
pub selected_v2_drive: RwLock<Option<PathBuf>>,
pub cached_product_key: RwLock<Option<Arc<String>>>,
pub recovery_status: RwLock<Option<Result<RecoveryStatus, RpcError>>>,
pub setup_result: RwLock<Option<(Arc<String>, SetupResult)>>,
}
#[derive(Clone)]
pub struct SetupContext(Arc<SetupContextSeed>);
impl SetupContext {
#[instrument(skip(path))]
pub async fn init<P: AsRef<Path>>(path: Option<P>) -> Result<Self, Error> {
let cfg = SetupContextConfig::load(path.as_ref()).await?;
let (shutdown, _) = tokio::sync::broadcast::channel(1);
let datadir = cfg.datadir().to_owned();
Ok(Self(Arc::new(SetupContextSeed {
config_path: path.as_ref().map(|p| p.as_ref().to_owned()),
bind_rpc: cfg.bind_rpc.unwrap_or(([127, 0, 0, 1], 5959).into()),
shutdown,
datadir,
selected_v2_drive: RwLock::new(None),
cached_product_key: RwLock::new(None),
recovery_status: RwLock::new(None),
setup_result: RwLock::new(None),
})))
}
#[instrument(skip(self))]
pub async fn db(&self, secret_store: &SqlitePool) -> Result<PatchDb, Error> {
let db_path = self.datadir.join("main").join("embassy.db");
let db = PatchDb::open(&db_path)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, db_path.display().to_string()))?;
if !db.exists(&<JsonPointer>::default()).await? {
let pkey = self.product_key().await?;
let sid = derive_id(&*pkey);
let hostname = derive_hostname(&sid);
db.put(
&<JsonPointer>::default(),
&Database::init(
sid,
&hostname,
&os_key(&mut secret_store.acquire().await?).await?,
password_hash(&mut secret_store.acquire().await?).await?,
),
None,
)
.await?;
}
Ok(db)
}
#[instrument(skip(self))]
pub async fn secret_store(&self) -> Result<SqlitePool, Error> {
let secret_store = SqlitePool::connect_with(
SqliteConnectOptions::new()
.filename(self.datadir.join("main").join("secrets.db"))
.create_if_missing(true)
.busy_timeout(Duration::from_secs(30)),
)
.await?;
sqlx::migrate!()
.run(&secret_store)
.await
.with_kind(crate::ErrorKind::Database)?;
Ok(secret_store)
}
#[instrument(skip(self))]
pub async fn product_key(&self) -> Result<Arc<String>, Error> {
Ok(
if let Some(k) = {
let guard = self.cached_product_key.read().await;
let res = guard.clone();
drop(guard);
res
} {
k
} else {
let k = Arc::new(get_product_key().await?);
*self.cached_product_key.write().await = Some(k.clone());
k
},
)
}
}
impl Context for SetupContext {
fn host(&self) -> Host<&str> {
match self.0.bind_rpc.ip() {
IpAddr::V4(a) => Host::Ipv4(a),
IpAddr::V6(a) => Host::Ipv6(a),
}
}
fn port(&self) -> u16 {
self.0.bind_rpc.port()
}
}
impl Deref for SetupContext {
type Target = SetupContextSeed;
fn deref(&self) -> &Self::Target {
&*self.0
}
}

View File

@@ -1,138 +0,0 @@
use std::collections::BTreeMap;
use color_eyre::eyre::eyre;
use patch_db::{DbHandle, LockType};
use rpc_toolkit::command;
use tracing::instrument;
use crate::context::RpcContext;
use crate::db::util::WithRevision;
use crate::dependencies::{
break_all_dependents_transitive, heal_all_dependents_transitive, BreakageRes, DependencyError,
TaggedDependencyError,
};
use crate::s9pk::manifest::PackageId;
use crate::status::MainStatus;
use crate::util::display_none;
use crate::util::serde::display_serializable;
use crate::{Error, ResultExt};
#[command(display(display_none))]
#[instrument(skip(ctx))]
pub async fn start(
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut tx, LockType::Write)
.await?;
let installed = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|pkg| pkg.installed())
.expect(&mut tx)
.await
.with_ctx(|_| {
(
crate::ErrorKind::NotFound,
format!("{} is not installed", id),
)
})?;
installed.lock(&mut tx, LockType::Read).await?;
let version = installed
.clone()
.manifest()
.version()
.get(&mut tx, true)
.await?
.to_owned();
let mut status = installed.status().main().get_mut(&mut tx).await?;
*status = MainStatus::Starting;
status.save(&mut tx).await?;
heal_all_dependents_transitive(&ctx, &mut tx, &id).await?;
let revision = tx.commit(None).await?;
ctx.managers
.get(&(id, version))
.await
.ok_or_else(|| Error::new(eyre!("Manager not found"), crate::ErrorKind::InvalidRequest))?
.synchronize()
.await;
Ok(WithRevision {
revision,
response: (),
})
}
#[instrument(skip(db))]
async fn stop_common<Db: DbHandle>(
db: &mut Db,
id: &PackageId,
breakages: &mut BTreeMap<PackageId, TaggedDependencyError>,
) -> Result<(), Error> {
let mut tx = db.begin().await?;
let mut status = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|pkg| pkg.installed())
.expect(&mut tx)
.await
.with_ctx(|_| {
(
crate::ErrorKind::NotFound,
format!("{} is not installed", id),
)
})?
.status()
.main()
.get_mut(&mut tx)
.await?;
*status = MainStatus::Stopping;
status.save(&mut tx).await?;
tx.save().await?;
break_all_dependents_transitive(db, &id, DependencyError::NotRunning, breakages).await?;
Ok(())
}
#[command(subcommands(self(stop_impl(async)), stop_dry), display(display_none))]
pub fn stop(#[arg] id: PackageId) -> Result<PackageId, Error> {
Ok(id)
}
#[command(rename = "dry", display(display_serializable))]
#[instrument(skip(ctx))]
pub async fn stop_dry(
#[context] ctx: RpcContext,
#[parent_data] id: PackageId,
) -> Result<BreakageRes, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
stop_common(&mut tx, &id, &mut breakages).await?;
tx.abort().await?;
Ok(BreakageRes(breakages))
}
#[instrument(skip(ctx))]
pub async fn stop_impl(ctx: RpcContext, id: PackageId) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
stop_common(&mut tx, &id, &mut BTreeMap::new()).await?;
Ok(WithRevision {
revision: tx.commit(None).await?,
response: (),
})
}

View File

@@ -1 +0,0 @@
pub mod rpc_continuations;

View File

@@ -1,53 +0,0 @@
use std::time::Instant;
use futures::future::BoxFuture;
use http::{Request, Response};
use hyper::Body;
use rand::RngCore;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
pub struct RequestGuid<T: AsRef<str> = String>(T);
impl RequestGuid {
pub fn new() -> Self {
let mut buf = [0; 40];
rand::thread_rng().fill_bytes(&mut buf);
RequestGuid(base32::encode(
base32::Alphabet::RFC4648 { padding: false },
&buf,
))
}
pub fn from(r: &str) -> Option<RequestGuid> {
if r.len() != 64 {
return None;
}
for c in r.chars() {
if !(c >= 'A' && c <= 'Z' || c >= '2' && c <= '7') {
return None;
}
}
Some(RequestGuid(r.to_owned()))
}
}
#[test]
fn parse_guid() {
println!(
"{:?}",
RequestGuid::from(&format!("{}", RequestGuid::new()))
)
}
impl<T: AsRef<str>> std::fmt::Display for RequestGuid<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.as_ref().fmt(f)
}
}
pub struct RpcContinuation {
pub created_at: Instant,
pub handler: Box<
dyn FnOnce(Request<Body>) -> BoxFuture<'static, Result<Response<Body>, crate::Error>>
+ Send
+ Sync,
>,
}

View File

@@ -1,275 +0,0 @@
pub mod model;
pub mod package;
pub mod util;
use std::borrow::Cow;
use std::future::Future;
use std::sync::Arc;
use std::time::Duration;
use color_eyre::eyre::eyre;
use futures::{FutureExt, SinkExt, StreamExt};
use patch_db::json_ptr::JsonPointer;
use patch_db::{Dump, Revision};
use rpc_toolkit::command;
use rpc_toolkit::hyper::upgrade::Upgraded;
use rpc_toolkit::hyper::{Body, Error as HyperError, Request, Response};
use rpc_toolkit::yajrc::{GenericRpcMethod, RpcError, RpcResponse};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::sync::{broadcast, oneshot};
use tokio::task::JoinError;
use tokio_tungstenite::tungstenite::Message;
use tokio_tungstenite::WebSocketStream;
use tracing::instrument;
pub use self::model::DatabaseModel;
use self::util::WithRevision;
use crate::context::RpcContext;
use crate::middleware::auth::{HasValidSession, HashSessionToken};
use crate::util::serde::{display_serializable, IoFormat};
use crate::{Error, ResultExt};
#[instrument(skip(ctx, ws_fut))]
async fn ws_handler<
WSFut: Future<Output = Result<Result<WebSocketStream<Upgraded>, HyperError>, JoinError>>,
>(
ctx: RpcContext,
ws_fut: WSFut,
) -> Result<(), Error> {
let (dump, sub) = ctx.db.dump_and_sub().await;
let mut stream = ws_fut
.await
.with_kind(crate::ErrorKind::Network)?
.with_kind(crate::ErrorKind::Unknown)?;
let (has_valid_session, token) = loop {
if let Some(Message::Text(cookie)) = stream
.next()
.await
.transpose()
.with_kind(crate::ErrorKind::Network)?
{
let cookie_str = serde_json::from_str::<Cow<str>>(&cookie)
.with_kind(crate::ErrorKind::Deserialization)?;
let id = basic_cookies::Cookie::parse(&cookie_str)
.with_kind(crate::ErrorKind::Authorization)?
.into_iter()
.find(|c| c.get_name() == "session")
.ok_or_else(|| {
Error::new(eyre!("UNAUTHORIZED"), crate::ErrorKind::Authorization)
})?;
let authenticated_session = HashSessionToken::from_cookie(&id);
match HasValidSession::from_session(&authenticated_session, &ctx).await {
Err(e) => {
stream
.send(Message::Text(
serde_json::to_string(
&RpcResponse::<GenericRpcMethod<String>>::from_result(Err::<
_,
RpcError,
>(
e.into()
)),
)
.with_kind(crate::ErrorKind::Serialization)?,
))
.await
.with_kind(crate::ErrorKind::Network)?;
return Ok(());
}
Ok(has_validation) => break (has_validation, authenticated_session),
}
}
};
let kill = subscribe_to_session_kill(&ctx, token).await;
send_dump(has_valid_session, &mut stream, dump).await?;
deal_with_messages(has_valid_session, kill, sub, stream).await?;
Ok(())
}
async fn subscribe_to_session_kill(
ctx: &RpcContext,
token: HashSessionToken,
) -> oneshot::Receiver<()> {
let (send, recv) = oneshot::channel();
let mut guard = ctx.open_authed_websockets.lock().await;
if !guard.contains_key(&token) {
guard.insert(token, vec![send]);
} else {
guard.get_mut(&token).unwrap().push(send);
}
recv
}
#[instrument(skip(_has_valid_authentication, kill, sub, stream))]
async fn deal_with_messages(
_has_valid_authentication: HasValidSession,
mut kill: oneshot::Receiver<()>,
mut sub: broadcast::Receiver<Arc<Revision>>,
mut stream: WebSocketStream<Upgraded>,
) -> Result<(), Error> {
loop {
futures::select! {
_ = (&mut kill).fuse() => {
tracing::info!("Closing WebSocket: Reason: Session Terminated");
return Ok(())
}
new_rev = sub.recv().fuse() => {
let rev = new_rev.with_kind(crate::ErrorKind::Database)?;
stream
.send(Message::Text(
serde_json::to_string(
&RpcResponse::<GenericRpcMethod<String>>::from_result(Ok::<_, RpcError>(
serde_json::to_value(&rev).with_kind(crate::ErrorKind::Serialization)?,
)),
)
.with_kind(crate::ErrorKind::Serialization)?,
))
.await
.with_kind(crate::ErrorKind::Network)?;
}
message = stream.next().fuse() => {
let message = message.transpose().with_kind(crate::ErrorKind::Network)?;
match message {
Some(Message::Ping(a)) => {
stream
.send(Message::Pong(a))
.await
.with_kind(crate::ErrorKind::Network)?;
}
Some(Message::Close(frame)) => {
if let Some(reason) = frame.as_ref() {
tracing::info!("Closing WebSocket: Reason: {} {}", reason.code, reason.reason);
} else {
tracing::info!("Closing WebSocket: Reason: Unknown");
}
return Ok(())
}
_ => (),
}
}
_ = tokio::time::sleep(Duration::from_secs(10)).fuse() => {
stream
.send(Message::Ping(Vec::new()))
.await
.with_kind(crate::ErrorKind::Network)?;
}
}
}
}
async fn send_dump(
_has_valid_authentication: HasValidSession,
stream: &mut WebSocketStream<Upgraded>,
dump: Dump,
) -> Result<(), Error> {
stream
.send(Message::Text(
serde_json::to_string(&RpcResponse::<GenericRpcMethod<String>>::from_result(Ok::<
_,
RpcError,
>(
serde_json::to_value(&dump).with_kind(crate::ErrorKind::Serialization)?,
)))
.with_kind(crate::ErrorKind::Serialization)?,
))
.await
.with_kind(crate::ErrorKind::Network)?;
Ok(())
}
pub async fn subscribe(ctx: RpcContext, req: Request<Body>) -> Result<Response<Body>, Error> {
let (parts, body) = req.into_parts();
let req = Request::from_parts(parts, body);
let (res, ws_fut) = hyper_ws_listener::create_ws(req).with_kind(crate::ErrorKind::Network)?;
if let Some(ws_fut) = ws_fut {
tokio::task::spawn(async move {
match ws_handler(ctx, ws_fut).await {
Ok(()) => (),
Err(e) => {
tracing::error!("WebSocket Closed: {}", e);
tracing::debug!("{:?}", e);
}
}
});
}
Ok(res)
}
#[command(subcommands(revisions, dump, put))]
pub fn db() -> Result<(), RpcError> {
Ok(())
}
#[derive(Deserialize, Serialize)]
#[serde(untagged)]
pub enum RevisionsRes {
Revisions(Vec<Arc<Revision>>),
Dump(Dump),
}
#[command(display(display_serializable))]
pub async fn revisions(
#[context] ctx: RpcContext,
#[arg] since: u64,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<RevisionsRes, RpcError> {
let cache = ctx.revision_cache.read().await;
if cache
.front()
.map(|rev| rev.id <= since + 1)
.unwrap_or(false)
{
Ok(RevisionsRes::Revisions(
cache
.iter()
.skip_while(|rev| rev.id < since + 1)
.cloned()
.collect(),
))
} else {
drop(cache);
Ok(RevisionsRes::Dump(ctx.db.dump().await))
}
}
#[command(display(display_serializable))]
pub async fn dump(
#[context] ctx: RpcContext,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<Dump, RpcError> {
Ok(ctx.db.dump().await)
}
#[command(subcommands(ui))]
pub fn put() -> Result<(), RpcError> {
Ok(())
}
#[command(display(display_serializable))]
#[instrument(skip(ctx))]
pub async fn ui(
#[context] ctx: RpcContext,
#[arg] pointer: JsonPointer,
#[arg] value: Value,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<WithRevision<()>, Error> {
let ptr = "/ui"
.parse::<JsonPointer>()
.with_kind(crate::ErrorKind::Database)?
+ &pointer;
Ok(WithRevision {
response: (),
revision: ctx.db.put(&ptr, &value, None).await?,
})
}

View File

@@ -1,316 +0,0 @@
use std::collections::{BTreeMap, BTreeSet};
use std::sync::Arc;
use chrono::{DateTime, Utc};
use emver::VersionRange;
use isocountry::CountryCode;
use patch_db::json_ptr::JsonPointer;
use patch_db::{HasModel, Map, MapModel, OptionModel};
use reqwest::Url;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use torut::onion::TorSecretKeyV3;
use crate::config::spec::{PackagePointerSpec, SystemPointerSpec};
use crate::install::progress::InstallProgress;
use crate::net::interface::InterfaceId;
use crate::s9pk::manifest::{Manifest, ManifestModel, PackageId};
use crate::status::health_check::HealthCheckId;
use crate::status::Status;
use crate::util::Version;
use crate::version::{Current, VersionT};
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct Database {
#[model]
pub server_info: ServerInfo,
#[model]
pub package_data: AllPackageData,
#[model]
pub recovered_packages: BTreeMap<PackageId, RecoveredPackageInfo>,
pub ui: Value,
}
impl Database {
pub fn init(
id: String,
hostname: &str,
tor_key: &TorSecretKeyV3,
password_hash: String,
) -> Self {
// TODO
Database {
server_info: ServerInfo {
id,
version: Current::new().semver().into(),
last_backup: None,
last_wifi_region: None,
eos_version_compat: Current::new().compat().clone(),
lan_address: format!("https://{}.local", hostname).parse().unwrap(),
tor_address: format!("http://{}", tor_key.public().get_onion_address())
.parse()
.unwrap(),
status_info: ServerStatus {
backing_up: false,
updated: false,
update_progress: None,
},
wifi: WifiInfo {
ssids: Vec::new(),
connected: None,
selected: None,
},
unread_notification_count: 0,
connection_addresses: ConnectionAddresses {
tor: Vec::new(),
clearnet: Vec::new(),
},
password_hash,
},
package_data: AllPackageData::default(),
recovered_packages: BTreeMap::new(),
ui: Value::Object(Default::default()),
}
}
}
impl DatabaseModel {
pub fn new() -> Self {
Self::from(JsonPointer::default())
}
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct ServerInfo {
pub id: String,
pub version: Version,
pub last_backup: Option<DateTime<Utc>>,
/// Used in the wifi to determine the region to set the system to
pub last_wifi_region: Option<CountryCode>,
pub eos_version_compat: VersionRange,
pub lan_address: Url,
pub tor_address: Url,
#[model]
#[serde(default)]
pub status_info: ServerStatus,
pub wifi: WifiInfo,
pub unread_notification_count: u64,
pub connection_addresses: ConnectionAddresses,
pub password_hash: String,
}
#[derive(Debug, Default, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct ServerStatus {
pub backing_up: bool,
pub updated: bool,
#[model]
pub update_progress: Option<UpdateProgress>,
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct UpdateProgress {
pub size: Option<u64>,
pub downloaded: u64,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct WifiInfo {
pub ssids: Vec<String>,
pub selected: Option<String>,
pub connected: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct ServerSpecs {
pub cpu: String,
pub disk: String,
pub memory: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct ConnectionAddresses {
pub tor: Vec<String>,
pub clearnet: Vec<String>,
}
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct AllPackageData(pub BTreeMap<PackageId, PackageDataEntry>);
impl Map for AllPackageData {
type Key = PackageId;
type Value = PackageDataEntry;
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
self.0.get(key)
}
}
impl HasModel for AllPackageData {
type Model = MapModel<Self>;
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct StaticFiles {
license: String,
instructions: String,
icon: String,
}
impl StaticFiles {
pub fn local(id: &PackageId, version: &Version, icon_type: &str) -> Self {
StaticFiles {
license: format!("/public/package-data/{}/{}/LICENSE.md", id, version),
instructions: format!("/public/package-data/{}/{}/INSTRUCTIONS.md", id, version),
icon: format!("/public/package-data/{}/{}/icon.{}", id, version, icon_type),
}
}
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(tag = "state")]
#[serde(rename_all = "kebab-case")]
pub enum PackageDataEntry {
#[serde(rename_all = "kebab-case")]
Installing {
static_files: StaticFiles,
manifest: Manifest,
install_progress: Arc<InstallProgress>,
},
#[serde(rename_all = "kebab-case")]
Updating {
static_files: StaticFiles,
manifest: Manifest,
installed: InstalledPackageDataEntry,
install_progress: Arc<InstallProgress>,
},
#[serde(rename_all = "kebab-case")]
Restoring {
static_files: StaticFiles,
manifest: Manifest,
install_progress: Arc<InstallProgress>,
},
#[serde(rename_all = "kebab-case")]
Removing {
static_files: StaticFiles,
manifest: Manifest,
removing: InstalledPackageDataEntry,
},
#[serde(rename_all = "kebab-case")]
Installed {
static_files: StaticFiles,
manifest: Manifest,
installed: InstalledPackageDataEntry,
},
}
impl PackageDataEntry {
pub fn installed(&self) -> Option<&InstalledPackageDataEntry> {
match self {
Self::Installing { .. } | Self::Restoring { .. } | Self::Removing { .. } => None,
Self::Updating { installed, .. } | Self::Installed { installed, .. } => Some(installed),
}
}
pub fn installed_mut(&mut self) -> Option<&mut InstalledPackageDataEntry> {
match self {
Self::Installing { .. } | Self::Restoring { .. } | Self::Removing { .. } => None,
Self::Updating { installed, .. } | Self::Installed { installed, .. } => Some(installed),
}
}
pub fn into_installed(self) -> Option<InstalledPackageDataEntry> {
match self {
Self::Installing { .. } | Self::Restoring { .. } | Self::Removing { .. } => None,
Self::Updating { installed, .. } | Self::Installed { installed, .. } => Some(installed),
}
}
pub fn manifest(self) -> Manifest {
match self {
PackageDataEntry::Installing { manifest, .. } => manifest,
PackageDataEntry::Updating { manifest, .. } => manifest,
PackageDataEntry::Restoring { manifest, .. } => manifest,
PackageDataEntry::Removing { manifest, .. } => manifest,
PackageDataEntry::Installed { manifest, .. } => manifest,
}
}
}
impl PackageDataEntryModel {
pub fn installed(self) -> OptionModel<InstalledPackageDataEntry> {
self.0.child("installed").into()
}
pub fn removing(self) -> OptionModel<InstalledPackageDataEntry> {
self.0.child("removing").into()
}
pub fn install_progress(self) -> OptionModel<InstallProgress> {
self.0.child("install-progress").into()
}
pub fn manifest(self) -> ManifestModel {
self.0.child("manifest").into()
}
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct InstalledPackageDataEntry {
#[model]
pub status: Status,
pub marketplace_url: Option<Url>,
#[serde(default)]
#[serde(with = "crate::util::serde::ed25519_pubkey")]
pub developer_key: ed25519_dalek::PublicKey,
#[model]
pub manifest: Manifest,
pub last_backup: Option<DateTime<Utc>>,
pub system_pointers: Vec<SystemPointerSpec>,
#[model]
pub dependency_info: BTreeMap<PackageId, StaticDependencyInfo>,
#[model]
pub current_dependents: BTreeMap<PackageId, CurrentDependencyInfo>,
#[model]
pub current_dependencies: BTreeMap<PackageId, CurrentDependencyInfo>,
#[model]
pub interface_addresses: InterfaceAddressMap,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct StaticDependencyInfo {
pub manifest: Option<Manifest>,
pub icon: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct CurrentDependencyInfo {
pub pointers: Vec<PackagePointerSpec>,
pub health_checks: BTreeSet<HealthCheckId>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct InterfaceAddressMap(pub BTreeMap<InterfaceId, InterfaceAddresses>);
impl Map for InterfaceAddressMap {
type Key = InterfaceId;
type Value = InterfaceAddresses;
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
self.0.get(key)
}
}
impl HasModel for InterfaceAddressMap {
type Model = MapModel<Self>;
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct InterfaceAddresses {
#[model]
pub tor_address: Option<String>,
#[model]
pub lan_address: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct RecoveredPackageInfo {
pub title: String,
pub icon: String,
pub version: Version,
}

View File

@@ -1,25 +0,0 @@
use patch_db::DbHandle;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::Error;
pub async fn get_packages<Db: DbHandle>(db: &mut Db) -> Result<Vec<PackageId>, Error> {
let packages = crate::db::DatabaseModel::new()
.package_data()
.get(db, false)
.await?;
Ok(packages.0.keys().cloned().collect())
}
pub async fn get_manifest<Db: DbHandle>(
db: &mut Db,
pkg: &PackageId,
) -> Result<Option<Manifest>, Error> {
let mpde = crate::db::DatabaseModel::new()
.package_data()
.idx_model(pkg)
.get(db, false)
.await?
.into_owned();
Ok(mpde.map(|pde| pde.manifest()))
}

View File

@@ -1,10 +0,0 @@
use std::sync::Arc;
use patch_db::Revision;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WithRevision<T> {
pub response: T,
pub revision: Option<Arc<Revision>>,
}

View File

@@ -1,911 +0,0 @@
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::time::Duration;
use color_eyre::eyre::eyre;
use emver::VersionRange;
use futures::future::BoxFuture;
use futures::FutureExt;
use patch_db::{DbHandle, HasModel, LockType, Map, MapModel, PatchDbHandle};
use rand::SeedableRng;
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use crate::action::{ActionImplementation, NoOutput};
use crate::config::action::ConfigRes;
use crate::config::spec::PackagePointerSpec;
use crate::config::{Config, ConfigSpec};
use crate::context::RpcContext;
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntry};
use crate::error::ResultExt;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::status::health_check::{HealthCheckId, HealthCheckResult};
use crate::status::{MainStatus, Status};
use crate::util::serde::display_serializable;
use crate::util::{display_none, Version};
use crate::volume::Volumes;
use crate::Error;
#[command(subcommands(configure))]
pub fn dependency() -> Result<(), Error> {
Ok(())
}
#[derive(Clone, Debug, thiserror::Error, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(tag = "type")]
pub enum DependencyError {
NotInstalled, // { "type": "not-installed" }
#[serde(rename_all = "kebab-case")]
IncorrectVersion {
expected: VersionRange,
received: Version,
}, // { "type": "incorrect-version", "expected": "0.1.0", "received": "^0.2.0" }
#[serde(rename_all = "kebab-case")]
ConfigUnsatisfied {
error: String,
}, // { "type": "config-unsatisfied", "error": "Bitcoin Core must have pruning set to manual." }
NotRunning, // { "type": "not-running" }
#[serde(rename_all = "kebab-case")]
HealthChecksFailed {
failures: BTreeMap<HealthCheckId, HealthCheckResult>,
}, // { "type": "health-checks-failed", "checks": { "rpc": { "time": "2021-05-11T18:21:29Z", "result": "starting" } } }
#[serde(rename_all = "kebab-case")]
Transitive, // { "type": "transitive" }
}
impl DependencyError {
pub fn cmp_priority(&self, other: &DependencyError) -> std::cmp::Ordering {
use std::cmp::Ordering::*;
use DependencyError::*;
match (self, other) {
(NotInstalled, NotInstalled) => Equal,
(NotInstalled, _) => Greater,
(_, NotInstalled) => Less,
(IncorrectVersion { .. }, IncorrectVersion { .. }) => Equal,
(IncorrectVersion { .. }, _) => Greater,
(_, IncorrectVersion { .. }) => Less,
(ConfigUnsatisfied { .. }, ConfigUnsatisfied { .. }) => Equal,
(ConfigUnsatisfied { .. }, _) => Greater,
(_, ConfigUnsatisfied { .. }) => Less,
(NotRunning, NotRunning) => Equal,
(NotRunning, _) => Greater,
(_, NotRunning) => Less,
(HealthChecksFailed { .. }, HealthChecksFailed { .. }) => Equal,
(HealthChecksFailed { .. }, _) => Greater,
(_, HealthChecksFailed { .. }) => Less,
(Transitive, Transitive) => Equal,
}
}
pub fn merge_with(self, other: DependencyError) -> DependencyError {
match (self, other) {
(DependencyError::NotInstalled, _) | (_, DependencyError::NotInstalled) => {
DependencyError::NotInstalled
}
(DependencyError::IncorrectVersion { expected, received }, _)
| (_, DependencyError::IncorrectVersion { expected, received }) => {
DependencyError::IncorrectVersion { expected, received }
}
(
DependencyError::ConfigUnsatisfied { error: e0 },
DependencyError::ConfigUnsatisfied { error: e1 },
) => DependencyError::ConfigUnsatisfied {
error: e0 + "\n" + &e1,
},
(DependencyError::ConfigUnsatisfied { error }, _)
| (_, DependencyError::ConfigUnsatisfied { error }) => {
DependencyError::ConfigUnsatisfied { error }
}
(DependencyError::NotRunning, _) | (_, DependencyError::NotRunning) => {
DependencyError::NotRunning
}
(
DependencyError::HealthChecksFailed { failures: f0 },
DependencyError::HealthChecksFailed { failures: f1 },
) => DependencyError::HealthChecksFailed {
failures: f0.into_iter().chain(f1.into_iter()).collect(),
},
(DependencyError::HealthChecksFailed { failures }, _)
| (_, DependencyError::HealthChecksFailed { failures }) => {
DependencyError::HealthChecksFailed { failures }
}
(DependencyError::Transitive, _) => DependencyError::Transitive,
}
}
#[instrument(skip(ctx, db))]
pub fn try_heal<'a, Db: DbHandle>(
self,
ctx: &'a RpcContext,
db: &'a mut Db,
id: &'a PackageId,
dependency: &'a PackageId,
mut dependency_config: Option<Config>,
info: &'a DepInfo,
) -> BoxFuture<'a, Result<Option<Self>, Error>> {
async move {
Ok(match self {
DependencyError::NotInstalled => {
if crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.exists(db, true)
.await?
{
DependencyError::IncorrectVersion {
expected: info.version.clone(),
received: Default::default(),
}
.try_heal(ctx, db, id, dependency, dependency_config, info)
.await?
} else {
Some(DependencyError::NotInstalled)
}
}
DependencyError::IncorrectVersion { expected, .. } => {
let version: Version = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.map(|m| m.manifest().version())
.get(db, true)
.await?
.into_owned()
.unwrap_or_default();
if version.satisfies(&expected) {
DependencyError::ConfigUnsatisfied {
error: String::new(),
}
.try_heal(ctx, db, id, dependency, dependency_config, info)
.await?
} else {
Some(DependencyError::IncorrectVersion {
expected,
received: version,
})
}
}
DependencyError::ConfigUnsatisfied { .. } => {
let dependent_manifest = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.map::<_, Manifest>(|m| m.manifest())
.expect(db)
.await?
.get(db, true)
.await?;
let dependency_manifest = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.map::<_, Manifest>(|m| m.manifest())
.expect(db)
.await?
.get(db, true)
.await?;
let dependency_config = if let Some(cfg) = dependency_config.take() {
cfg
} else if let Some(cfg_info) = &dependency_manifest.config {
cfg_info
.get(
ctx,
dependency,
&dependency_manifest.version,
&dependency_manifest.volumes,
)
.await?
.config
.unwrap_or_default()
} else {
Config::default()
};
if let Some(cfg_req) = &info.config {
if let Err(error) = cfg_req
.check(
ctx,
id,
&dependent_manifest.version,
&dependent_manifest.volumes,
&dependency_config,
)
.await?
{
return Ok(Some(DependencyError::ConfigUnsatisfied { error }));
}
}
DependencyError::NotRunning
.try_heal(ctx, db, id, dependency, Some(dependency_config), info)
.await?
}
DependencyError::NotRunning => {
let status = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.map::<_, Status>(|m| m.status())
.expect(db)
.await?
.get(db, true)
.await?;
if status.main.running() {
DependencyError::HealthChecksFailed {
failures: BTreeMap::new(),
}
.try_heal(ctx, db, id, dependency, dependency_config, info)
.await?
} else {
Some(DependencyError::NotRunning)
}
}
DependencyError::HealthChecksFailed { .. } => {
let status = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.map::<_, Status>(|m| m.status())
.expect(db)
.await?
.get(db, true)
.await?
.into_owned();
match status.main {
MainStatus::BackingUp {
started: Some(_),
health,
}
| MainStatus::Running { health, .. } => {
let mut failures = BTreeMap::new();
for (check, res) in health {
if !matches!(res, HealthCheckResult::Success)
&& crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.and_then::<_, CurrentDependencyInfo>(|m| {
m.current_dependencies().idx_model(dependency)
})
.get(db, true)
.await?
.into_owned()
.map(|i| i.health_checks)
.unwrap_or_default()
.contains(&check)
{
failures.insert(check.clone(), res.clone());
}
}
if !failures.is_empty() {
Some(DependencyError::HealthChecksFailed { failures })
} else {
DependencyError::Transitive
.try_heal(ctx, db, id, dependency, dependency_config, info)
.await?
}
}
MainStatus::Starting => {
DependencyError::Transitive
.try_heal(ctx, db, id, dependency, dependency_config, info)
.await?
}
_ => return Ok(Some(DependencyError::NotRunning)),
}
}
DependencyError::Transitive => {
if crate::db::DatabaseModel::new()
.package_data()
.idx_model(dependency)
.and_then(|m| m.installed())
.map::<_, DependencyErrors>(|m| m.status().dependency_errors())
.get(db, true)
.await?
.into_owned()
.unwrap_or_default()
.0
.is_empty()
{
None
} else {
Some(DependencyError::Transitive)
}
}
})
}
.boxed()
}
}
impl std::fmt::Display for DependencyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DependencyError::NotInstalled => write!(f, "Not Installed"),
DependencyError::IncorrectVersion { expected, received } => write!(
f,
"Incorrect Version: Expected {}, Received {}",
expected,
received.as_str()
),
DependencyError::ConfigUnsatisfied { error } => {
write!(f, "Configuration Requirements Not Satisfied: {}", error)
}
DependencyError::NotRunning => write!(f, "Not Running"),
DependencyError::HealthChecksFailed { failures } => {
write!(f, "Failed Health Check(s): ")?;
let mut comma = false;
for (check, res) in failures {
if !comma {
comma = true;
} else {
write!(f, ", ")?;
}
write!(f, "{}: {}", check, res)?;
}
Ok(())
}
DependencyError::Transitive => {
write!(f, "Dependency Error(s)")
}
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct TaggedDependencyError {
pub dependency: PackageId,
pub error: DependencyError,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct BreakageRes(pub BTreeMap<PackageId, TaggedDependencyError>);
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Dependencies(pub BTreeMap<PackageId, DepInfo>);
impl Map for Dependencies {
type Key = PackageId;
type Value = DepInfo;
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
self.0.get(key)
}
}
impl HasModel for Dependencies {
type Model = MapModel<Self>;
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
#[serde(tag = "type")]
pub enum DependencyRequirement {
OptIn { how: String },
OptOut { how: String },
Required,
}
impl DependencyRequirement {
pub fn required(&self) -> bool {
matches!(self, &DependencyRequirement::Required)
}
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct DepInfo {
pub version: VersionRange,
pub requirement: DependencyRequirement,
pub description: Option<String>,
#[serde(default)]
#[model]
pub config: Option<DependencyConfig>,
}
impl DepInfo {
pub async fn satisfied<Db: DbHandle>(
&self,
ctx: &RpcContext,
db: &mut Db,
dependency_id: &PackageId,
dependency_config: Option<Config>, // fetch if none
dependent_id: &PackageId,
) -> Result<Result<(), DependencyError>, Error> {
Ok(
if let Some(err) = DependencyError::NotInstalled
.try_heal(
ctx,
db,
dependent_id,
dependency_id,
dependency_config,
self,
)
.await?
{
Err(err)
} else {
Ok(())
},
)
}
}
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)]
#[serde(rename_all = "kebab-case")]
pub struct DependencyConfig {
check: ActionImplementation,
auto_configure: ActionImplementation,
}
impl DependencyConfig {
pub async fn check(
&self,
ctx: &RpcContext,
dependent_id: &PackageId,
dependent_version: &Version,
dependent_volumes: &Volumes,
dependency_config: &Config,
) -> Result<Result<NoOutput, String>, Error> {
Ok(self
.check
.sandboxed(
ctx,
dependent_id,
dependent_version,
dependent_volumes,
Some(dependency_config),
None,
)
.await?
.map_err(|(_, e)| e))
}
pub async fn auto_configure(
&self,
ctx: &RpcContext,
dependent_id: &PackageId,
dependent_version: &Version,
dependent_volumes: &Volumes,
old: &Config,
) -> Result<Config, Error> {
self.auto_configure
.sandboxed(
ctx,
dependent_id,
dependent_version,
dependent_volumes,
Some(old),
None,
)
.await?
.map_err(|e| Error::new(eyre!("{}", e.1), crate::ErrorKind::AutoConfigure))
}
}
#[command(
subcommands(self(configure_impl(async)), configure_dry),
display(display_none)
)]
pub async fn configure(
#[arg(rename = "dependent-id")] dependent_id: PackageId,
#[arg(rename = "dependency-id")] dependency_id: PackageId,
) -> Result<(PackageId, PackageId), Error> {
Ok((dependent_id, dependency_id))
}
pub async fn configure_impl(
ctx: RpcContext,
(pkg_id, dep_id): (PackageId, PackageId),
) -> Result<(), Error> {
let mut db = ctx.db.handle();
let ConfigDryRes {
old_config: _,
new_config,
spec: _,
} = configure_logic(ctx.clone(), &mut db, (pkg_id, dep_id.clone())).await?;
Ok(crate::config::configure(
&ctx,
&mut db,
&dep_id,
Some(new_config),
&Some(Duration::from_secs(3).into()),
false,
&mut BTreeMap::new(),
&mut BTreeMap::new(),
)
.await?)
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct ConfigDryRes {
pub old_config: Config,
pub new_config: Config,
pub spec: ConfigSpec,
}
#[command(rename = "dry", display(display_serializable))]
#[instrument(skip(ctx))]
pub async fn configure_dry(
#[context] ctx: RpcContext,
#[parent_data] (pkg_id, dependency_id): (PackageId, PackageId),
) -> Result<ConfigDryRes, Error> {
let mut db = ctx.db.handle();
configure_logic(ctx, &mut db, (pkg_id, dependency_id)).await
}
pub async fn configure_logic(
ctx: RpcContext,
db: &mut PatchDbHandle,
(pkg_id, dependency_id): (PackageId, PackageId),
) -> Result<ConfigDryRes, Error> {
crate::db::DatabaseModel::new()
.package_data()
.lock(db, LockType::Read)
.await?;
let pkg_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&pkg_id)
.and_then(|m| m.installed())
.expect(db)
.await
.with_kind(crate::ErrorKind::NotFound)?;
let pkg_version = pkg_model.clone().manifest().version().get(db, true).await?;
let pkg_volumes = pkg_model.clone().manifest().volumes().get(db, true).await?;
let dependency_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dependency_id)
.and_then(|m| m.installed())
.expect(db)
.await
.with_kind(crate::ErrorKind::NotFound)?;
let dependency_config_action = dependency_model
.clone()
.manifest()
.config()
.get(db, true)
.await?
.to_owned()
.ok_or_else(|| {
Error::new(
eyre!("{} has no config", dependency_id),
crate::ErrorKind::NotFound,
)
})?;
let dependency_version = dependency_model
.clone()
.manifest()
.version()
.get(db, true)
.await?;
let dependency_volumes = dependency_model
.clone()
.manifest()
.volumes()
.get(db, true)
.await?;
let dependencies = pkg_model
.clone()
.manifest()
.dependencies()
.get(db, true)
.await?;
let dependency = dependencies
.get(&dependency_id)
.ok_or_else(|| {
Error::new(
eyre!(
"dependency for {} not found in the manifest for {}",
dependency_id,
pkg_id
),
crate::ErrorKind::NotFound,
)
})?
.config
.as_ref()
.ok_or_else(|| {
Error::new(
eyre!(
"dependency config for {} not found on {}",
dependency_id,
pkg_id
),
crate::ErrorKind::NotFound,
)
})?;
let ConfigRes {
config: maybe_config,
spec,
} = dependency_config_action
.get(
&ctx,
&dependency_id,
&*dependency_version,
&*dependency_volumes,
)
.await?;
let old_config = if let Some(config) = maybe_config {
config
} else {
spec.gen(
&mut rand::rngs::StdRng::from_entropy(),
&Some(Duration::new(10, 0)),
)?
};
let new_config = dependency
.auto_configure
.sandboxed(
&ctx,
&pkg_id,
&pkg_version,
&pkg_volumes,
Some(&old_config),
None,
)
.await?
.map_err(|e| Error::new(eyre!("{}", e.1), crate::ErrorKind::AutoConfigure))?;
Ok(ConfigDryRes {
old_config,
new_config,
spec,
})
}
#[instrument(skip(db, current_dependencies))]
pub async fn add_dependent_to_current_dependents_lists<
'a,
Db: DbHandle,
I: IntoIterator<Item = (&'a PackageId, &'a CurrentDependencyInfo)>,
>(
db: &mut Db,
dependent_id: &PackageId,
current_dependencies: I,
) -> Result<(), Error> {
for (dependency, dep_info) in current_dependencies {
if let Some(dependency_model) = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dependency)
.and_then(|pkg| pkg.installed())
.check(db)
.await?
{
dependency_model
.current_dependents()
.idx_model(dependent_id)
.put(db, &dep_info)
.await?;
}
}
Ok(())
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct DependencyErrors(pub BTreeMap<PackageId, DependencyError>);
impl Map for DependencyErrors {
type Key = PackageId;
type Value = DependencyError;
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
self.0.get(key)
}
}
impl HasModel for DependencyErrors {
type Model = MapModel<Self>;
}
impl DependencyErrors {
pub async fn init<Db: DbHandle>(
ctx: &RpcContext,
db: &mut Db,
manifest: &Manifest,
current_dependencies: &BTreeMap<PackageId, CurrentDependencyInfo>,
) -> Result<DependencyErrors, Error> {
let mut res = BTreeMap::new();
for (dependency_id, info) in current_dependencies.keys().filter_map(|dependency_id| {
manifest
.dependencies
.0
.get(dependency_id)
.map(|info| (dependency_id, info))
}) {
if let Err(e) = info
.satisfied(ctx, db, dependency_id, None, &manifest.id)
.await?
{
res.insert(dependency_id.clone(), e);
}
}
Ok(DependencyErrors(res))
}
}
impl std::fmt::Display for DependencyErrors {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{{ ")?;
for (idx, (id, err)) in self.0.iter().enumerate() {
write!(f, "{}: {}", id, err)?;
if idx < self.0.len() - 1 {
// not last
write!(f, ", ")?;
}
}
write!(f, " }}")
}
}
pub async fn break_all_dependents_transitive<'a, Db: DbHandle>(
db: &'a mut Db,
id: &'a PackageId,
error: DependencyError,
breakages: &'a mut BTreeMap<PackageId, TaggedDependencyError>,
) -> Result<(), Error> {
for dependent in crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.expect(db)
.await?
.current_dependents()
.keys(db, true)
.await?
.into_iter()
.filter(|dependent| id != dependent)
{
break_transitive(db, &dependent, id, error.clone(), breakages).await?;
}
Ok(())
}
#[instrument(skip(db))]
pub fn break_transitive<'a, Db: DbHandle>(
db: &'a mut Db,
id: &'a PackageId,
dependency: &'a PackageId,
error: DependencyError,
breakages: &'a mut BTreeMap<PackageId, TaggedDependencyError>,
) -> BoxFuture<'a, Result<(), Error>> {
async move {
let mut tx = db.begin().await?;
let model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?;
let mut status = model.clone().status().get_mut(&mut tx).await?;
let old = status.dependency_errors.0.remove(dependency);
let newly_broken = if let Some(e) = &old {
error.cmp_priority(&e) == Ordering::Greater
} else {
true
};
status.dependency_errors.0.insert(
dependency.clone(),
if let Some(old) = old {
old.merge_with(error.clone())
} else {
error.clone()
},
);
if newly_broken {
breakages.insert(
id.clone(),
TaggedDependencyError {
dependency: dependency.clone(),
error: error.clone(),
},
);
status.save(&mut tx).await?;
tx.save().await?;
break_all_dependents_transitive(db, id, DependencyError::Transitive, breakages).await?;
} else {
status.save(&mut tx).await?;
tx.save().await?;
}
Ok(())
}
.boxed()
}
#[instrument(skip(ctx, db))]
pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>(
ctx: &'a RpcContext,
db: &'a mut Db,
id: &'a PackageId,
) -> Result<(), Error> {
for dependent in crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.expect(db)
.await?
.current_dependents()
.keys(db, true)
.await?
.into_iter()
.filter(|dependent| id != dependent)
{
heal_transitive(ctx, db, &dependent, id).await?;
}
Ok(())
}
#[instrument(skip(ctx, db))]
pub fn heal_transitive<'a, Db: DbHandle>(
ctx: &'a RpcContext,
db: &'a mut Db,
id: &'a PackageId,
dependency: &'a PackageId,
) -> BoxFuture<'a, Result<(), Error>> {
async move {
let mut tx = db.begin().await?;
let model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?;
let mut status = model.clone().status().get_mut(&mut tx).await?;
let old = status.dependency_errors.0.remove(dependency);
if let Some(old) = old {
let info = model
.manifest()
.dependencies()
.idx_model(dependency)
.expect(&mut tx)
.await?
.get(&mut tx, true)
.await?;
if let Some(new) = old
.try_heal(ctx, &mut tx, id, dependency, None, &*info)
.await?
{
status.dependency_errors.0.insert(dependency.clone(), new);
status.save(&mut tx).await?;
tx.save().await?;
} else {
status.save(&mut tx).await?;
tx.save().await?;
heal_all_dependents_transitive(ctx, db, id).await?;
}
}
Ok(())
}
.boxed()
}
pub async fn reconfigure_dependents_with_live_pointers(
ctx: &RpcContext,
mut tx: impl DbHandle,
pde: &InstalledPackageDataEntry,
) -> Result<(), Error> {
let dependents = &pde.current_dependents;
let me = &pde.manifest.id;
for (dependent_id, dependency_info) in dependents {
if dependency_info.pointers.iter().any(|ptr| match ptr {
// dependency id matches the package being uninstalled
PackagePointerSpec::TorAddress(ptr) => &ptr.package_id == me && dependent_id != me,
PackagePointerSpec::LanAddress(ptr) => &ptr.package_id == me && dependent_id != me,
// we never need to retarget these
PackagePointerSpec::TorKey(_) => false,
PackagePointerSpec::Config(_) => false,
}) {
crate::config::configure(
ctx,
&mut tx,
dependent_id,
None,
&None,
false,
&mut BTreeMap::new(),
&mut BTreeMap::new(),
)
.await?;
}
}
Ok(())
}

View File

@@ -1,35 +0,0 @@
use std::fs::File;
use std::io::Write;
use std::path::Path;
use ed25519_dalek::Keypair;
use rpc_toolkit::command;
use tracing::instrument;
use crate::context::SdkContext;
use crate::util::display_none;
use crate::{Error, ResultExt};
#[command(cli_only, blocking, display(display_none))]
#[instrument(skip(ctx))]
pub fn init(#[context] ctx: SdkContext) -> Result<(), Error> {
if !ctx.developer_key_path.exists() {
let parent = ctx.developer_key_path.parent().unwrap_or(Path::new("/"));
if !parent.exists() {
std::fs::create_dir_all(parent)
.with_ctx(|_| (crate::ErrorKind::Filesystem, parent.display().to_string()))?;
}
tracing::info!("Generating new developer key...");
let keypair = Keypair::generate(&mut rand::thread_rng());
tracing::info!("Writing key to {}", ctx.developer_key_path.display());
let mut dev_key_file = File::create(&ctx.developer_key_path)?;
dev_key_file.write_all(&keypair.to_bytes())?;
dev_key_file.sync_all()?;
}
Ok(())
}
#[command(subcommands(crate::s9pk::verify, crate::config::verify_spec))]
pub fn verify() -> Result<(), Error> {
Ok(())
}

View File

@@ -1,72 +0,0 @@
use std::path::Path;
use std::sync::Arc;
use rpc_toolkit::command;
use rpc_toolkit::yajrc::RpcError;
use crate::context::DiagnosticContext;
use crate::disk::repair;
use crate::logs::{display_logs, fetch_logs, LogResponse, LogSource};
use crate::shutdown::Shutdown;
use crate::util::display_none;
use crate::Error;
pub const SYSTEMD_UNIT: &'static str = "embassy-init";
#[command(subcommands(error, logs, exit, restart, forget_disk, disk))]
pub fn diagnostic() -> Result<(), Error> {
Ok(())
}
#[command]
pub fn error(#[context] ctx: DiagnosticContext) -> Result<Arc<RpcError>, Error> {
Ok(ctx.error.clone())
}
#[command(display(display_logs))]
pub async fn logs(
#[arg] limit: Option<usize>,
#[arg] cursor: Option<String>,
#[arg] before_flag: Option<bool>,
) -> Result<LogResponse, Error> {
Ok(fetch_logs(
LogSource::Service(SYSTEMD_UNIT),
limit,
cursor,
before_flag.unwrap_or(false),
)
.await?)
}
#[command(display(display_none))]
pub fn exit(#[context] ctx: DiagnosticContext) -> Result<(), Error> {
ctx.shutdown.send(None).expect("receiver dropped");
Ok(())
}
#[command(display(display_none))]
pub fn restart(#[context] ctx: DiagnosticContext) -> Result<(), Error> {
ctx.shutdown
.send(Some(Shutdown {
datadir: ctx.datadir.clone(),
disk_guid: ctx.disk_guid.clone(),
db_handle: None,
restart: true,
}))
.expect("receiver dropped");
Ok(())
}
#[command(subcommands(forget_disk, repair))]
pub fn disk() -> Result<(), Error> {
Ok(())
}
#[command(rename = "forget", display(display_none))]
pub async fn forget_disk() -> Result<(), Error> {
let disk_guid = Path::new("/embassy-os/disk.guid");
if tokio::fs::metadata(disk_guid).await.is_ok() {
tokio::fs::remove_file(disk_guid).await?;
}
Ok(())
}

View File

@@ -1,90 +0,0 @@
use clap::ArgMatches;
use rpc_toolkit::command;
use self::util::DiskListResponse;
use crate::util::display_none;
use crate::util::serde::{display_serializable, IoFormat};
use crate::Error;
pub mod fsck;
pub mod main;
pub mod mount;
pub mod quirks;
pub mod util;
pub const BOOT_RW_PATH: &str = "/media/boot-rw";
pub const REPAIR_DISK_PATH: &str = "/embassy-os/repair-disk";
#[command(subcommands(list, repair))]
pub fn disk() -> Result<(), Error> {
Ok(())
}
fn display_disk_info(info: DiskListResponse, matches: &ArgMatches<'_>) {
use prettytable::*;
if matches.is_present("format") {
return display_serializable(info, matches);
}
let mut table = Table::new();
table.add_row(row![bc =>
"LOGICALNAME",
"LABEL",
"CAPACITY",
"USED",
"EMBASSY OS VERSION"
]);
for disk in info.disks {
let row = row![
disk.logicalname.display(),
"N/A",
&format!("{:.2} GiB", disk.capacity as f64 / 1024.0 / 1024.0 / 1024.0),
"N/A",
"N/A",
];
table.add_row(row);
for part in disk.partitions {
let row = row![
part.logicalname.display(),
if let Some(label) = part.label.as_ref() {
label
} else {
"N/A"
},
part.capacity,
if let Some(used) = part
.used
.map(|u| format!("{:.2} GiB", u as f64 / 1024.0 / 1024.0 / 1024.0))
.as_ref()
{
used
} else {
"N/A"
},
if let Some(eos) = part.embassy_os.as_ref() {
eos.version.as_str()
} else {
"N/A"
},
];
table.add_row(row);
}
}
table.print_tty(false);
}
#[command(display(display_disk_info))]
pub async fn list(
#[allow(unused_variables)]
#[arg]
format: Option<IoFormat>,
) -> Result<DiskListResponse, Error> {
crate::disk::util::list().await
}
#[command(display(display_none))]
pub async fn repair() -> Result<(), Error> {
tokio::fs::write(REPAIR_DISK_PATH, b"").await?;
Ok(())
}

View File

@@ -1,65 +0,0 @@
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use async_trait::async_trait;
use digest::generic_array::GenericArray;
use digest::Digest;
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use super::{FileSystem, MountType, ReadOnly};
use crate::util::Invoke;
use crate::{Error, ResultExt};
pub async fn mount(
logicalname: impl AsRef<Path>,
mountpoint: impl AsRef<Path>,
mount_type: MountType,
) -> Result<(), Error> {
tokio::fs::create_dir_all(mountpoint.as_ref()).await?;
let mut cmd = tokio::process::Command::new("mount");
cmd.arg(logicalname.as_ref()).arg(mountpoint.as_ref());
if mount_type == ReadOnly {
cmd.arg("-o").arg("ro");
}
cmd.invoke(crate::ErrorKind::Filesystem).await?;
Ok(())
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct BlockDev<LogicalName: AsRef<Path>> {
logicalname: LogicalName,
}
impl<LogicalName: AsRef<Path>> BlockDev<LogicalName> {
pub fn new(logicalname: LogicalName) -> Self {
BlockDev { logicalname }
}
}
#[async_trait]
impl<LogicalName: AsRef<Path> + Send + Sync> FileSystem for BlockDev<LogicalName> {
async fn mount<P: AsRef<Path> + Send + Sync>(
&self,
mountpoint: P,
mount_type: MountType,
) -> Result<(), Error> {
mount(self.logicalname.as_ref(), mountpoint, mount_type).await
}
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> {
let mut sha = Sha256::new();
sha.update("BlockDev");
sha.update(
tokio::fs::canonicalize(self.logicalname.as_ref())
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
self.logicalname.as_ref().display().to_string(),
)
})?
.as_os_str()
.as_bytes(),
);
Ok(sha.finalize())
}
}

View File

@@ -1,83 +0,0 @@
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use async_trait::async_trait;
use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray;
use digest::Digest;
use sha2::Sha256;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use super::{FileSystem, MountType};
use crate::{Error, ResultExt};
pub async fn mount_ecryptfs<P0: AsRef<Path>, P1: AsRef<Path>>(
src: P0,
dst: P1,
key: &str,
) -> Result<(), Error> {
tokio::fs::create_dir_all(dst.as_ref()).await?;
let mut ecryptfs = tokio::process::Command::new("mount")
.arg("-t")
.arg("ecryptfs")
.arg(src.as_ref())
.arg(dst.as_ref())
.arg("-o")
// for more information `man ecryptfs`
.arg(format!("key=passphrase:passphrase_passwd={},ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y,no_sig_cache", key))
.stdin(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()?;
let mut stdin = ecryptfs.stdin.take().unwrap();
let mut stderr = ecryptfs.stderr.take().unwrap();
stdin.write_all(b"\n").await?;
stdin.flush().await?;
stdin.shutdown().await?;
drop(stdin);
let mut err = String::new();
stderr.read_to_string(&mut err).await?;
if !ecryptfs.wait().await?.success() {
Err(Error::new(eyre!("{}", err), crate::ErrorKind::Filesystem))
} else {
Ok(())
}
}
pub struct EcryptFS<EncryptedDir: AsRef<Path>, Key: AsRef<str>> {
encrypted_dir: EncryptedDir,
key: Key,
}
impl<EncryptedDir: AsRef<Path>, Key: AsRef<str>> EcryptFS<EncryptedDir, Key> {
pub fn new(encrypted_dir: EncryptedDir, key: Key) -> Self {
EcryptFS { encrypted_dir, key }
}
}
#[async_trait]
impl<EncryptedDir: AsRef<Path> + Send + Sync, Key: AsRef<str> + Send + Sync> FileSystem
for EcryptFS<EncryptedDir, Key>
{
async fn mount<P: AsRef<Path> + Send + Sync>(
&self,
mountpoint: P,
_mount_type: MountType, // ignored - inherited from parent fs
) -> Result<(), Error> {
mount_ecryptfs(self.encrypted_dir.as_ref(), mountpoint, self.key.as_ref()).await
}
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> {
let mut sha = Sha256::new();
sha.update("EcryptFS");
sha.update(
tokio::fs::canonicalize(self.encrypted_dir.as_ref())
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
self.encrypted_dir.as_ref().display().to_string(),
)
})?
.as_os_str()
.as_bytes(),
);
Ok(sha.finalize())
}
}

View File

@@ -1,50 +0,0 @@
use std::path::Path;
use async_trait::async_trait;
use digest::generic_array::GenericArray;
use digest::Digest;
use sha2::Sha256;
use super::{FileSystem, MountType, ReadOnly};
use crate::util::Invoke;
use crate::Error;
pub async fn mount_label(
label: &str,
mountpoint: impl AsRef<Path>,
mount_type: MountType,
) -> Result<(), Error> {
tokio::fs::create_dir_all(mountpoint.as_ref()).await?;
let mut cmd = tokio::process::Command::new("mount");
cmd.arg("-L").arg(label).arg(mountpoint.as_ref());
if mount_type == ReadOnly {
cmd.arg("-o").arg("ro");
}
cmd.invoke(crate::ErrorKind::Filesystem).await?;
Ok(())
}
pub struct Label<S: AsRef<str>> {
label: S,
}
impl<S: AsRef<str>> Label<S> {
pub fn new(label: S) -> Self {
Label { label }
}
}
#[async_trait]
impl<S: AsRef<str> + Send + Sync> FileSystem for Label<S> {
async fn mount<P: AsRef<Path> + Send + Sync>(
&self,
mountpoint: P,
mount_type: MountType,
) -> Result<(), Error> {
mount_label(self.label.as_ref(), mountpoint, mount_type).await
}
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> {
let mut sha = Sha256::new();
sha.update("Label");
sha.update(self.label.as_ref().as_bytes());
Ok(sha.finalize())
}
}

View File

@@ -1,31 +0,0 @@
use std::path::Path;
use async_trait::async_trait;
use digest::generic_array::GenericArray;
use digest::Digest;
use sha2::Sha256;
use crate::Error;
pub mod block_dev;
pub mod cifs;
pub mod ecryptfs;
pub mod label;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MountType {
ReadOnly,
ReadWrite,
}
pub use MountType::*;
#[async_trait]
pub trait FileSystem {
async fn mount<P: AsRef<Path> + Send + Sync>(
&self,
mountpoint: P,
mount_type: MountType,
) -> Result<(), Error>;
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error>;
}

View File

@@ -1,129 +0,0 @@
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Weak};
use lazy_static::lazy_static;
use tokio::sync::Mutex;
use tracing::instrument;
use super::filesystem::{FileSystem, MountType, ReadOnly, ReadWrite};
use super::util::unmount;
use crate::util::Invoke;
use crate::Error;
pub const TMP_MOUNTPOINT: &'static str = "/media/embassy-os/tmp";
#[async_trait::async_trait]
pub trait GenericMountGuard: AsRef<Path> + std::fmt::Debug + Send + Sync + 'static {
async fn unmount(mut self) -> Result<(), Error>;
}
#[derive(Debug)]
pub struct MountGuard {
mountpoint: PathBuf,
mounted: bool,
}
impl MountGuard {
pub async fn mount(
filesystem: &impl FileSystem,
mountpoint: impl AsRef<Path>,
mount_type: MountType,
) -> Result<Self, Error> {
let mountpoint = mountpoint.as_ref().to_owned();
filesystem.mount(&mountpoint, mount_type).await?;
Ok(MountGuard {
mountpoint,
mounted: true,
})
}
pub async fn unmount(mut self) -> Result<(), Error> {
if self.mounted {
unmount(&self.mountpoint).await?;
self.mounted = false;
}
Ok(())
}
}
impl AsRef<Path> for MountGuard {
fn as_ref(&self) -> &Path {
&self.mountpoint
}
}
impl Drop for MountGuard {
fn drop(&mut self) {
if self.mounted {
let mountpoint = std::mem::take(&mut self.mountpoint);
tokio::spawn(async move { unmount(mountpoint).await.unwrap() });
}
}
}
#[async_trait::async_trait]
impl GenericMountGuard for MountGuard {
async fn unmount(mut self) -> Result<(), Error> {
MountGuard::unmount(self).await
}
}
async fn tmp_mountpoint(source: &impl FileSystem) -> Result<PathBuf, Error> {
Ok(Path::new(TMP_MOUNTPOINT).join(base32::encode(
base32::Alphabet::RFC4648 { padding: false },
&source.source_hash().await?,
)))
}
lazy_static! {
static ref TMP_MOUNTS: Mutex<BTreeMap<PathBuf, (MountType, Weak<MountGuard>)>> =
Mutex::new(BTreeMap::new());
}
#[derive(Debug)]
pub struct TmpMountGuard {
guard: Arc<MountGuard>,
}
impl TmpMountGuard {
/// DRAGONS: if you try to mount something as ro and rw at the same time, the ro mount will be upgraded to rw.
#[instrument(skip(filesystem))]
pub async fn mount(filesystem: &impl FileSystem, mount_type: MountType) -> Result<Self, Error> {
let mountpoint = tmp_mountpoint(filesystem).await?;
let mut tmp_mounts = TMP_MOUNTS.lock().await;
if !tmp_mounts.contains_key(&mountpoint) {
tmp_mounts.insert(mountpoint.clone(), (mount_type, Weak::new()));
}
let (prev_mt, weak_slot) = tmp_mounts.get_mut(&mountpoint).unwrap();
if let Some(guard) = weak_slot.upgrade() {
// upgrade to rw
if *prev_mt == ReadOnly && mount_type == ReadWrite {
tokio::process::Command::new("mount")
.arg("-o")
.arg("remount,rw")
.arg(&mountpoint)
.invoke(crate::ErrorKind::Filesystem)
.await?;
*prev_mt = ReadWrite;
}
Ok(TmpMountGuard { guard })
} else {
let guard = Arc::new(MountGuard::mount(filesystem, &mountpoint, mount_type).await?);
*weak_slot = Arc::downgrade(&guard);
*prev_mt = mount_type;
Ok(TmpMountGuard { guard })
}
}
pub async fn unmount(self) -> Result<(), Error> {
if let Ok(guard) = Arc::try_unwrap(self.guard) {
guard.unmount().await?;
}
Ok(())
}
}
impl AsRef<Path> for TmpMountGuard {
fn as_ref(&self) -> &Path {
(&*self.guard).as_ref()
}
}
#[async_trait::async_trait]
impl GenericMountGuard for TmpMountGuard {
async fn unmount(mut self) -> Result<(), Error> {
TmpMountGuard::unmount(self).await
}
}

View File

@@ -1,170 +0,0 @@
use std::collections::BTreeSet;
use std::num::ParseIntError;
use std::path::Path;
use color_eyre::eyre::eyre;
use tokio::io::AsyncWriteExt;
use tracing::instrument;
use super::BOOT_RW_PATH;
use crate::util::AtomicFile;
use crate::Error;
pub const QUIRK_PATH: &'static str = "/sys/module/usb_storage/parameters/quirks";
pub const WHITELIST: [(VendorId, ProductId); 5] = [
(VendorId(0x1d6b), ProductId(0x0002)), // root hub usb2
(VendorId(0x1d6b), ProductId(0x0003)), // root hub usb3
(VendorId(0x2109), ProductId(0x3431)),
(VendorId(0x1058), ProductId(0x262f)), // western digital black HDD
(VendorId(0x04e8), ProductId(0x4001)), // Samsung T7
];
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct VendorId(u16);
impl std::str::FromStr for VendorId {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
u16::from_str_radix(s.trim(), 16).map(VendorId)
}
}
impl std::fmt::Display for VendorId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:04x}", self.0)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProductId(u16);
impl std::str::FromStr for ProductId {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
u16::from_str_radix(s.trim(), 16).map(ProductId)
}
}
impl std::fmt::Display for ProductId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:04x}", self.0)
}
}
#[derive(Clone, Debug)]
pub struct Quirks(BTreeSet<(VendorId, ProductId)>);
impl Quirks {
pub fn add(&mut self, vendor: VendorId, product: ProductId) {
self.0.insert((vendor, product));
}
pub fn remove(&mut self, vendor: VendorId, product: ProductId) {
self.0.remove(&(vendor, product));
}
pub fn contains(&self, vendor: VendorId, product: ProductId) -> bool {
self.0.contains(&(vendor, product))
}
}
impl std::fmt::Display for Quirks {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut comma = false;
for (vendor, product) in &self.0 {
if comma {
write!(f, ",")?;
} else {
comma = true;
}
write!(f, "{}:{}:u", vendor, product)?;
}
Ok(())
}
}
impl std::str::FromStr for Quirks {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.trim();
let mut quirks = BTreeSet::new();
for item in s.split(",") {
if let [vendor, product, "u"] = item.splitn(3, ":").collect::<Vec<_>>().as_slice() {
quirks.insert((vendor.parse()?, product.parse()?));
} else {
return Err(Error::new(
eyre!("Invalid quirk: `{}`", item),
crate::ErrorKind::DiskManagement,
));
}
}
Ok(Quirks(quirks))
}
}
#[instrument]
pub async fn update_quirks(quirks: &mut Quirks) -> Result<Vec<String>, Error> {
let mut usb_devices = tokio::fs::read_dir("/sys/bus/usb/devices/").await?;
let mut to_reconnect = Vec::new();
while let Some(usb_device) = usb_devices.next_entry().await? {
if tokio::fs::metadata(usb_device.path().join("idVendor"))
.await
.is_err()
{
continue;
}
let vendor = tokio::fs::read_to_string(usb_device.path().join("idVendor"))
.await?
.parse()?;
let product = tokio::fs::read_to_string(usb_device.path().join("idProduct"))
.await?
.parse()?;
if WHITELIST.contains(&(vendor, product)) {
quirks.remove(vendor, product);
continue;
}
if quirks.contains(vendor, product) {
continue;
}
quirks.add(vendor, product);
{
// write quirks to sysfs
let mut quirk_file = tokio::fs::File::create(QUIRK_PATH).await?;
quirk_file.write_all(quirks.to_string().as_bytes()).await?;
quirk_file.sync_all().await?;
drop(quirk_file);
}
disconnect_usb(usb_device.path()).await?;
let (vendor_name, product_name) = tokio::try_join!(
tokio::fs::read_to_string(usb_device.path().join("manufacturer")),
tokio::fs::read_to_string(usb_device.path().join("product")),
)?;
to_reconnect.push(format!("{} {}", vendor_name, product_name));
}
Ok(to_reconnect)
}
#[instrument(skip(usb_device_path))]
pub async fn disconnect_usb(usb_device_path: impl AsRef<Path>) -> Result<(), Error> {
let authorized_path = usb_device_path.as_ref().join("bConfigurationValue");
let mut authorized_file = tokio::fs::File::create(&authorized_path).await?;
authorized_file.write_all(b"0").await?;
authorized_file.sync_all().await?;
drop(authorized_file);
Ok(())
}
#[instrument]
pub async fn fetch_quirks() -> Result<Quirks, Error> {
Ok(tokio::fs::read_to_string(QUIRK_PATH).await?.parse()?)
}
#[instrument]
pub async fn save_quirks(quirks: &Quirks) -> Result<(), Error> {
let orig_path = Path::new(BOOT_RW_PATH).join("cmdline.txt.orig");
let target_path = Path::new(BOOT_RW_PATH).join("cmdline.txt");
if tokio::fs::metadata(&orig_path).await.is_err() {
tokio::fs::copy(&target_path, &orig_path).await?;
}
let cmdline = tokio::fs::read_to_string(&orig_path).await?;
let mut target = AtomicFile::new(&target_path).await?;
target
.write_all(format!("usb-storage.quirks={} {}", quirks, cmdline).as_bytes())
.await?;
target.save().await?;
Ok(())
}

View File

@@ -1,435 +0,0 @@
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use color_eyre::eyre::{self, eyre};
use futures::TryStreamExt;
use indexmap::IndexSet;
use nom::bytes::complete::{tag, take_till1};
use nom::character::complete::multispace1;
use nom::character::is_space;
use nom::combinator::{opt, rest};
use nom::sequence::{pair, preceded, terminated};
use nom::IResult;
use regex::Regex;
use serde::{Deserialize, Serialize};
use tokio::fs::File;
use tokio::process::Command;
use tracing::instrument;
use super::mount::filesystem::block_dev::BlockDev;
use super::mount::filesystem::ReadOnly;
use super::mount::guard::TmpMountGuard;
use super::quirks::{fetch_quirks, save_quirks, update_quirks};
use crate::util::io::from_yaml_async_reader;
use crate::util::serde::IoFormat;
use crate::util::{Invoke, Version};
use crate::{Error, ResultExt as _};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct DiskListResponse {
pub disks: Vec<DiskInfo>,
pub reconnect: Vec<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct DiskInfo {
pub logicalname: PathBuf,
pub vendor: Option<String>,
pub model: Option<String>,
pub partitions: Vec<PartitionInfo>,
pub capacity: u64,
pub guid: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct PartitionInfo {
pub logicalname: PathBuf,
pub label: Option<String>,
pub capacity: u64,
pub used: Option<u64>,
pub embassy_os: Option<EmbassyOsRecoveryInfo>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct EmbassyOsRecoveryInfo {
pub version: Version,
pub full: bool,
pub password_hash: Option<String>,
pub wrapped_key: Option<String>,
}
const DISK_PATH: &'static str = "/dev/disk/by-path";
const SYS_BLOCK_PATH: &'static str = "/sys/block";
lazy_static::lazy_static! {
static ref PARTITION_REGEX: Regex = Regex::new("-part[0-9]+$").unwrap();
}
#[instrument(skip(path))]
pub async fn get_vendor<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
let vendor = tokio::fs::read_to_string(
Path::new(SYS_BLOCK_PATH)
.join(path.as_ref().strip_prefix("/dev").map_err(|_| {
Error::new(
eyre!("not a canonical block device"),
crate::ErrorKind::BlockDevice,
)
})?)
.join("device")
.join("vendor"),
)
.await?
.trim()
.to_owned();
Ok(if vendor.is_empty() {
None
} else {
Some(vendor)
})
}
#[instrument(skip(path))]
pub async fn get_model<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
let model = tokio::fs::read_to_string(
Path::new(SYS_BLOCK_PATH)
.join(path.as_ref().strip_prefix("/dev").map_err(|_| {
Error::new(
eyre!("not a canonical block device"),
crate::ErrorKind::BlockDevice,
)
})?)
.join("device")
.join("model"),
)
.await?
.trim()
.to_owned();
Ok(if model.is_empty() { None } else { Some(model) })
}
#[instrument(skip(path))]
pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
Ok(String::from_utf8(
Command::new("blockdev")
.arg("--getsize64")
.arg(path.as_ref())
.invoke(crate::ErrorKind::BlockDevice)
.await?,
)?
.trim()
.parse::<u64>()?)
}
#[instrument(skip(path))]
pub async fn get_label<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
let label = String::from_utf8(
Command::new("lsblk")
.arg("-no")
.arg("label")
.arg(path.as_ref())
.invoke(crate::ErrorKind::BlockDevice)
.await?,
)?
.trim()
.to_owned();
Ok(if label.is_empty() { None } else { Some(label) })
}
#[instrument(skip(path))]
pub async fn get_used<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
Ok(String::from_utf8(
Command::new("df")
.arg("--output=used")
.arg("--block-size=1")
.arg(path.as_ref())
.invoke(crate::ErrorKind::Filesystem)
.await?,
)?
.lines()
.skip(1)
.next()
.unwrap_or_default()
.trim()
.parse::<u64>()?)
}
#[instrument(skip(path))]
pub async fn get_available<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
Ok(String::from_utf8(
Command::new("df")
.arg("--output=avail")
.arg("--block-size=1")
.arg(path.as_ref())
.invoke(crate::ErrorKind::Filesystem)
.await?,
)?
.lines()
.skip(1)
.next()
.unwrap_or_default()
.trim()
.parse::<u64>()?)
}
#[instrument(skip(path))]
pub async fn get_percentage<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
Ok(String::from_utf8(
Command::new("df")
.arg("--output=pcent")
.arg(path.as_ref())
.invoke(crate::ErrorKind::Filesystem)
.await?,
)?
.lines()
.skip(1)
.next()
.unwrap_or_default()
.trim()
.strip_suffix("%")
.unwrap()
.parse::<u64>()?)
}
#[instrument]
pub async fn pvscan() -> Result<BTreeMap<PathBuf, Option<String>>, Error> {
let pvscan_out = Command::new("pvscan")
.invoke(crate::ErrorKind::DiskManagement)
.await?;
let pvscan_out_str = std::str::from_utf8(&pvscan_out)?;
Ok(parse_pvscan_output(pvscan_out_str))
}
pub async fn recovery_info(
mountpoint: impl AsRef<Path>,
) -> Result<Option<EmbassyOsRecoveryInfo>, Error> {
let backup_unencrypted_metadata_path = mountpoint
.as_ref()
.join("EmbassyBackups/unencrypted-metadata.cbor");
if tokio::fs::metadata(&backup_unencrypted_metadata_path)
.await
.is_ok()
{
return Ok(Some(
IoFormat::Cbor.from_slice(
&tokio::fs::read(&backup_unencrypted_metadata_path)
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
backup_unencrypted_metadata_path.display().to_string(),
)
})?,
)?,
));
}
let version_path = mountpoint.as_ref().join("root/appmgr/version");
if tokio::fs::metadata(&version_path).await.is_ok() {
return Ok(Some(EmbassyOsRecoveryInfo {
version: from_yaml_async_reader(File::open(&version_path).await?).await?,
full: true,
password_hash: None,
wrapped_key: None,
}));
}
Ok(None)
}
#[instrument]
pub async fn list() -> Result<DiskListResponse, Error> {
let mut quirks = fetch_quirks().await?;
let reconnect = update_quirks(&mut quirks).await?;
save_quirks(&mut quirks).await?;
let disk_guids = pvscan().await?;
let disks = tokio_stream::wrappers::ReadDirStream::new(
tokio::fs::read_dir(DISK_PATH)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, DISK_PATH))?,
)
.map_err(|e| {
Error::new(
eyre::Error::from(e).wrap_err(DISK_PATH),
crate::ErrorKind::Filesystem,
)
})
.try_fold(BTreeMap::new(), |mut disks, dir_entry| async move {
if let Some(disk_path) = dir_entry.path().file_name().and_then(|s| s.to_str()) {
let (disk_path, part_path) = if let Some(end) = PARTITION_REGEX.find(disk_path) {
(
disk_path.strip_suffix(end.as_str()).unwrap_or_default(),
Some(disk_path),
)
} else {
(disk_path, None)
};
let disk_path = Path::new(DISK_PATH).join(disk_path);
let disk = tokio::fs::canonicalize(&disk_path).await.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
disk_path.display().to_string(),
)
})?;
if &*disk == Path::new("/dev/mmcblk0") {
return Ok(disks);
}
if !disks.contains_key(&disk) {
disks.insert(disk.clone(), IndexSet::new());
}
if let Some(part_path) = part_path {
let part_path = Path::new(DISK_PATH).join(part_path);
let part = tokio::fs::canonicalize(&part_path).await.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
part_path.display().to_string(),
)
})?;
disks.get_mut(&disk).unwrap().insert(part);
}
}
Ok(disks)
})
.await?;
let mut res = Vec::with_capacity(disks.len());
for (disk, parts) in disks {
let mut guid: Option<String> = None;
let mut partitions = Vec::with_capacity(parts.len());
let vendor = get_vendor(&disk)
.await
.map_err(|e| tracing::warn!("Could not get vendor of {}: {}", disk.display(), e.source))
.unwrap_or_default();
let model = get_model(&disk)
.await
.map_err(|e| tracing::warn!("Could not get model of {}: {}", disk.display(), e.source))
.unwrap_or_default();
let capacity = get_capacity(&disk)
.await
.map_err(|e| {
tracing::warn!("Could not get capacity of {}: {}", disk.display(), e.source)
})
.unwrap_or_default();
if let Some(g) = disk_guids.get(&disk) {
guid = g.clone();
} else {
for part in parts {
let mut embassy_os = None;
let label = get_label(&part).await?;
let capacity = get_capacity(&part)
.await
.map_err(|e| {
tracing::warn!("Could not get capacity of {}: {}", part.display(), e.source)
})
.unwrap_or_default();
let mut used = None;
match TmpMountGuard::mount(&BlockDev::new(&part), ReadOnly).await {
Err(e) => tracing::warn!("Could not collect usage information: {}", e.source),
Ok(mount_guard) => {
used = get_used(&mount_guard)
.await
.map_err(|e| {
tracing::warn!(
"Could not get usage of {}: {}",
part.display(),
e.source
)
})
.ok();
if let Some(recovery_info) = match recovery_info(&mount_guard).await {
Ok(a) => a,
Err(e) => {
tracing::error!(
"Error fetching unencrypted backup metadata: {}",
e
);
None
}
} {
embassy_os = Some(recovery_info)
}
mount_guard.unmount().await?;
}
}
partitions.push(PartitionInfo {
logicalname: part,
label,
capacity,
used,
embassy_os,
});
}
}
res.push(DiskInfo {
logicalname: disk,
vendor,
model,
partitions,
capacity,
guid,
})
}
Ok(DiskListResponse {
disks: res,
reconnect,
})
}
fn parse_pvscan_output(pvscan_output: &str) -> BTreeMap<PathBuf, Option<String>> {
fn parse_line(line: &str) -> IResult<&str, (&str, Option<&str>)> {
let pv_parse = preceded(
tag(" PV "),
terminated(take_till1(|c| is_space(c as u8)), multispace1),
);
let vg_parse = preceded(
opt(tag("is in exported ")),
preceded(
tag("VG "),
terminated(take_till1(|c| is_space(c as u8)), multispace1),
),
);
let mut parser = terminated(pair(pv_parse, opt(vg_parse)), rest);
parser(line)
}
let lines = pvscan_output.lines();
let n = lines.clone().count();
let entries = lines.take(n.saturating_sub(1));
let mut ret = BTreeMap::new();
for entry in entries {
match parse_line(entry) {
Ok((_, (pv, vg))) => {
ret.insert(PathBuf::from(pv), vg.map(|s| s.to_owned()));
}
Err(_) => {
tracing::warn!("Failed to parse pvscan output line: {}", entry);
}
}
}
ret
}
#[test]
fn test_pvscan_parser() {
let s1 = r#" PV /dev/mapper/cryptdata VG data lvm2 [1.81 TiB / 0 free]
PV /dev/sdb lvm2 [931.51 GiB]
Total: 2 [2.72 TiB] / in use: 1 [1.81 TiB] / in no VG: 1 [931.51 GiB]
"#;
let s2 = r#" PV /dev/sdb VG EMBASSY_LZHJAENWGPCJJL6C6AXOD7OOOIJG7HFBV4GYRJH6HADXUCN4BRWQ lvm2 [931.51 GiB / 0 free]
Total: 1 [931.51 GiB] / in use: 1 [931.51 GiB] / in no VG: 0 [0 ]
"#;
let s3 = r#" PV /dev/mapper/cryptdata VG data lvm2 [1.81 TiB / 0 free]
Total: 1 [1.81 TiB] / in use: 1 [1.81 TiB] / in no VG: 0 [0 ]
"#;
let s4 = r#" PV /dev/sda is in exported VG EMBASSY_ZFHOCTYV3ZJMJW3OTFMG55LSQZLP667EDNZKDNUJKPJX5HE6S5HQ [931.51 GiB / 0 free]
Total: 1 [931.51 GiB] / in use: 1 [931.51 GiB] / in no VG: 0 [0 ]
"#;
println!("{:?}", parse_pvscan_output(s1));
println!("{:?}", parse_pvscan_output(s2));
println!("{:?}", parse_pvscan_output(s3));
println!("{:?}", parse_pvscan_output(s4));
}

View File

@@ -1,348 +0,0 @@
use std::fmt::Display;
use color_eyre::eyre::eyre;
use patch_db::Revision;
use rpc_toolkit::yajrc::RpcError;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorKind {
Unknown = 1,
Filesystem = 2,
Docker = 3,
ConfigSpecViolation = 4,
ConfigRulesViolation = 5,
NotFound = 6,
IncorrectPassword = 7,
VersionIncompatible = 8,
Network = 9,
Registry = 10,
Serialization = 11,
Deserialization = 12,
Utf8 = 13,
ParseVersion = 14,
IncorrectDisk = 15,
Nginx = 16,
Dependency = 17,
ParseS9pk = 18,
ParseUrl = 19,
DiskNotAvailable = 20,
BlockDevice = 21,
InvalidOnionAddress = 22,
Pack = 23,
ValidateS9pk = 24,
DiskCorrupted = 25,
Tor = 26,
ConfigGen = 27,
ParseNumber = 28,
Database = 29,
InvalidPackageId = 30,
InvalidSignature = 31,
Backup = 32,
Restore = 33,
Authorization = 34,
AutoConfigure = 35,
Action = 36,
RateLimited = 37,
InvalidRequest = 38,
MigrationFailed = 39,
Uninitialized = 40,
ParseNetAddress = 41,
ParseSshKey = 42,
SoundError = 43,
ParseTimestamp = 44,
ParseSysInfo = 45,
Wifi = 46,
Journald = 47,
DiskManagement = 48,
OpenSsl = 49,
PasswordHashGeneration = 50,
DiagnosticMode = 51,
ParseDbField = 52,
Duplicate = 53,
MultipleErrors = 54,
Incoherent = 55,
InvalidBackupTargetId = 56,
ProductKeyMismatch = 57,
LanPortConflict = 58,
}
impl ErrorKind {
pub fn as_str(&self) -> &'static str {
use ErrorKind::*;
match self {
Unknown => "Unknown Error",
Filesystem => "Filesystem I/O Error",
Docker => "Docker Error",
ConfigSpecViolation => "Config Spec Violation",
ConfigRulesViolation => "Config Rules Violation",
NotFound => "Not Found",
IncorrectPassword => "Incorrect Password",
VersionIncompatible => "Version Incompatible",
Network => "Network Error",
Registry => "Registry Error",
Serialization => "Serialization Error",
Deserialization => "Deserialization Error",
Utf8 => "UTF-8 Parse Error",
ParseVersion => "Version Parsing Error",
IncorrectDisk => "Incorrect Disk",
Nginx => "Nginx Error",
Dependency => "Dependency Error",
ParseS9pk => "S9PK Parsing Error",
ParseUrl => "URL Parsing Error",
DiskNotAvailable => "Disk Not Available",
BlockDevice => "Block Device Error",
InvalidOnionAddress => "Invalid Onion Address",
Pack => "Pack Error",
ValidateS9pk => "S9PK Validation Error",
DiskCorrupted => "Disk Corrupted", // Remove
Tor => "Tor Daemon Error",
ConfigGen => "Config Generation Error",
ParseNumber => "Number Parsing Error",
Database => "Database Error",
InvalidPackageId => "Invalid Package ID",
InvalidSignature => "Invalid Signature",
Backup => "Backup Error",
Restore => "Restore Error",
Authorization => "Unauthorized",
AutoConfigure => "Auto-Configure Error",
Action => "Action Failed",
RateLimited => "Rate Limited",
InvalidRequest => "Invalid Request",
MigrationFailed => "Migration Failed",
Uninitialized => "Uninitialized",
ParseNetAddress => "Net Address Parsing Error",
ParseSshKey => "SSH Key Parsing Error",
SoundError => "Sound Interface Error",
ParseTimestamp => "Timestamp Parsing Error",
ParseSysInfo => "System Info Parsing Error",
Wifi => "WiFi Internal Error",
Journald => "Journald Error",
DiskManagement => "Disk Management Error",
OpenSsl => "OpenSSL Internal Error",
PasswordHashGeneration => "Password Hash Generation Error",
DiagnosticMode => "Embassy is in Diagnostic Mode",
ParseDbField => "Database Field Parse Error",
Duplicate => "Duplication Error",
MultipleErrors => "Multiple Errors",
Incoherent => "Incoherent",
InvalidBackupTargetId => "Invalid Backup Target ID",
ProductKeyMismatch => "Incompatible Product Keys",
LanPortConflict => "Incompatible LAN port configuration",
}
}
}
impl Display for ErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Debug)]
pub struct Error {
pub source: color_eyre::eyre::Error,
pub kind: ErrorKind,
pub revision: Option<Revision>,
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.kind.as_str(), self.source)
}
}
impl Error {
pub fn new<E: Into<color_eyre::eyre::Error>>(source: E, kind: ErrorKind) -> Self {
Error {
source: source.into(),
kind,
revision: None,
}
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::new(e, ErrorKind::Filesystem)
}
}
impl From<std::str::Utf8Error> for Error {
fn from(e: std::str::Utf8Error) -> Self {
Error::new(e, ErrorKind::Utf8)
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(e: std::string::FromUtf8Error) -> Self {
Error::new(e, ErrorKind::Utf8)
}
}
impl From<emver::ParseError> for Error {
fn from(e: emver::ParseError) -> Self {
Error::new(e, ErrorKind::ParseVersion)
}
}
impl From<rpc_toolkit::url::ParseError> for Error {
fn from(e: rpc_toolkit::url::ParseError) -> Self {
Error::new(e, ErrorKind::ParseUrl)
}
}
impl From<std::num::ParseIntError> for Error {
fn from(e: std::num::ParseIntError) -> Self {
Error::new(e, ErrorKind::ParseNumber)
}
}
impl From<std::num::ParseFloatError> for Error {
fn from(e: std::num::ParseFloatError) -> Self {
Error::new(e, ErrorKind::ParseNumber)
}
}
impl From<patch_db::Error> for Error {
fn from(e: patch_db::Error) -> Self {
Error::new(e, ErrorKind::Database)
}
}
impl From<sqlx::Error> for Error {
fn from(e: sqlx::Error) -> Self {
Error::new(e, ErrorKind::Database)
}
}
impl From<ed25519_dalek::SignatureError> for Error {
fn from(e: ed25519_dalek::SignatureError) -> Self {
Error::new(e, ErrorKind::InvalidSignature)
}
}
impl From<bollard::errors::Error> for Error {
fn from(e: bollard::errors::Error) -> Self {
Error::new(e, ErrorKind::Docker)
}
}
impl From<torut::control::ConnError> for Error {
fn from(e: torut::control::ConnError) -> Self {
Error::new(eyre!("{:?}", e), ErrorKind::Tor)
}
}
impl From<std::net::AddrParseError> for Error {
fn from(e: std::net::AddrParseError) -> Self {
Error::new(e, ErrorKind::ParseNetAddress)
}
}
impl From<openssl::error::ErrorStack> for Error {
fn from(e: openssl::error::ErrorStack) -> Self {
Error::new(eyre!("OpenSSL ERROR:\n{}", e), ErrorKind::OpenSsl)
}
}
impl From<Error> for RpcError {
fn from(e: Error) -> Self {
let mut data_object = serde_json::Map::with_capacity(3);
data_object.insert("details".to_owned(), format!("{}", e.source).into());
data_object.insert("debug".to_owned(), format!("{:?}", e.source).into());
data_object.insert(
"revision".to_owned(),
match serde_json::to_value(&e.revision) {
Ok(a) => a,
Err(e) => {
tracing::warn!("Error serializing revision for Error object: {}", e);
serde_json::Value::Null
}
},
);
RpcError {
code: e.kind as i32,
message: e.kind.as_str().into(),
data: Some(data_object.into()),
}
}
}
#[derive(Debug, Default)]
pub struct ErrorCollection(Vec<Error>);
impl ErrorCollection {
pub fn new() -> Self {
Self::default()
}
pub fn handle<T, E: Into<Error>>(&mut self, result: Result<T, E>) -> Option<T> {
match result {
Ok(a) => Some(a),
Err(e) => {
self.0.push(e.into());
None
}
}
}
pub fn into_result(self) -> Result<(), Error> {
if self.0.is_empty() {
Ok(())
} else {
Err(Error::new(eyre!("{}", self), ErrorKind::MultipleErrors))
}
}
}
impl From<ErrorCollection> for Result<(), Error> {
fn from(e: ErrorCollection) -> Self {
e.into_result()
}
}
impl<T, E: Into<Error>> Extend<Result<T, E>> for ErrorCollection {
fn extend<I: IntoIterator<Item = Result<T, E>>>(&mut self, iter: I) {
for item in iter {
self.handle(item);
}
}
}
impl std::fmt::Display for ErrorCollection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for (idx, e) in self.0.iter().enumerate() {
if idx > 0 {
write!(f, "; ")?;
}
write!(f, "{}", e)?;
}
Ok(())
}
}
pub trait ResultExt<T, E>
where
Self: Sized,
{
fn with_kind(self, kind: ErrorKind) -> Result<T, Error>;
fn with_ctx<F: FnOnce(&E) -> (ErrorKind, D), D: Display + Send + Sync + 'static>(
self,
f: F,
) -> Result<T, Error>;
}
impl<T, E> ResultExt<T, E> for Result<T, E>
where
color_eyre::eyre::Error: From<E>,
{
fn with_kind(self, kind: ErrorKind) -> Result<T, Error> {
self.map_err(|e| Error {
source: e.into(),
kind,
revision: None,
})
}
fn with_ctx<F: FnOnce(&E) -> (ErrorKind, D), D: Display + Send + Sync + 'static>(
self,
f: F,
) -> Result<T, Error> {
self.map_err(|e| {
let (kind, ctx) = f(&e);
let source = color_eyre::eyre::Error::from(e);
let ctx = format!("{}: {}", ctx, source);
let source = source.wrap_err(ctx);
Error {
kind,
source: source.into(),
revision: None,
}
})
}
}
#[macro_export]
macro_rules! ensure_code {
($x:expr, $c:expr, $fmt:expr $(, $arg:expr)*) => {
if !($x) {
return Err(crate::Error::new(color_eyre::eyre::eyre!($fmt, $($arg, )*), $c));
}
};
}

View File

@@ -1,78 +0,0 @@
use digest::Digest;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use tracing::instrument;
use crate::util::Invoke;
use crate::{Error, ErrorKind, ResultExt};
pub const PRODUCT_KEY_PATH: &'static str = "/embassy-os/product_key.txt";
#[instrument]
pub async fn get_hostname() -> Result<String, Error> {
Ok(derive_hostname(&get_id().await?))
}
pub fn derive_hostname(id: &str) -> String {
format!("embassy-{}", id)
}
#[instrument]
pub async fn get_current_hostname() -> Result<String, Error> {
let out = Command::new("hostname")
.invoke(ErrorKind::ParseSysInfo)
.await?;
let out_string = String::from_utf8(out)?;
Ok(out_string.trim().to_owned())
}
#[instrument]
pub async fn set_hostname(hostname: &str) -> Result<(), Error> {
let _out = Command::new("hostnamectl")
.arg("set-hostname")
.arg(hostname)
.invoke(ErrorKind::ParseSysInfo)
.await?;
Ok(())
}
#[instrument]
pub async fn get_product_key() -> Result<String, Error> {
let out = tokio::fs::read_to_string(PRODUCT_KEY_PATH)
.await
.with_ctx(|_| (crate::ErrorKind::Filesystem, PRODUCT_KEY_PATH))?;
Ok(out.trim().to_owned())
}
#[instrument]
pub async fn set_product_key(key: &str) -> Result<(), Error> {
let mut pkey_file = File::create(PRODUCT_KEY_PATH).await?;
pkey_file.write_all(key.as_bytes()).await?;
Ok(())
}
pub fn derive_id(key: &str) -> String {
let mut hasher = sha2::Sha256::new();
hasher.update(key.as_bytes());
let res = hasher.finalize();
hex::encode(&res[0..4])
}
#[instrument]
pub async fn get_id() -> Result<String, Error> {
let key = get_product_key().await?;
Ok(derive_id(&key))
}
// cat /embassy-os/product_key.txt | shasum -a 256 | head -c 8 | awk '{print "embassy-"$1}' | xargs hostnamectl set-hostname && systemctl restart avahi-daemon
#[instrument]
pub async fn sync_hostname() -> Result<(), Error> {
set_hostname(&format!("embassy-{}", get_id().await?)).await?;
Command::new("systemctl")
.arg("restart")
.arg("avahi-daemon")
.invoke(crate::ErrorKind::Network)
.await?;
Ok(())
}

View File

@@ -1,179 +0,0 @@
use std::borrow::{Borrow, Cow};
use std::fmt::Debug;
use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::util::Version;
use crate::Error;
pub const SYSTEM_ID: Id<&'static str> = Id("x_system");
#[derive(Debug, thiserror::Error)]
#[error("Invalid ID")]
pub struct InvalidId;
impl From<InvalidId> for Error {
fn from(err: InvalidId) -> Self {
Error::new(err, crate::error::ErrorKind::InvalidPackageId)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct IdUnchecked<S: AsRef<str>>(pub S);
impl<'de> Deserialize<'de> for IdUnchecked<Cow<'de, str>> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = IdUnchecked<Cow<'de, str>>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a valid ID")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(IdUnchecked(Cow::Owned(v.to_owned())))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(IdUnchecked(Cow::Owned(v)))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(IdUnchecked(Cow::Borrowed(v)))
}
}
deserializer.deserialize_any(Visitor)
}
}
impl<'de> Deserialize<'de> for IdUnchecked<String> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(IdUnchecked(String::deserialize(deserializer)?))
}
}
impl<'de> Deserialize<'de> for IdUnchecked<&'de str> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(IdUnchecked(<&'de str>::deserialize(deserializer)?))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id<S: AsRef<str> = String>(S);
impl<S: AsRef<str>> Id<S> {
pub fn try_from(value: S) -> Result<Self, InvalidId> {
if value
.as_ref()
.chars()
.all(|c| c.is_ascii_lowercase() || c == '-')
{
Ok(Id(value))
} else {
Err(InvalidId)
}
}
}
impl<'a> Id<&'a str> {
pub fn owned(&self) -> Id {
Id(self.0.to_owned())
}
}
impl From<Id> for String {
fn from(value: Id) -> Self {
value.0
}
}
impl<S: AsRef<str>> std::ops::Deref for Id<S> {
type Target = S;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<S: AsRef<str>> std::fmt::Display for Id<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.as_ref())
}
}
impl<S: AsRef<str>> AsRef<str> for Id<S> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<S: AsRef<str>> Borrow<str> for Id<S> {
fn borrow(&self) -> &str {
self.0.as_ref()
}
}
impl<'de, S> Deserialize<'de> for Id<S>
where
S: AsRef<str>,
IdUnchecked<S>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let unchecked: IdUnchecked<S> = Deserialize::deserialize(deserializer)?;
Id::try_from(unchecked.0).map_err(serde::de::Error::custom)
}
}
impl<S: AsRef<str>> Serialize for Id<S> {
fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
where
Ser: Serializer,
{
serializer.serialize_str(self.as_ref())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct ImageId<S: AsRef<str> = String>(Id<S>);
impl<S: AsRef<str>> std::fmt::Display for ImageId<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.0)
}
}
impl<S: AsRef<str>> ImageId<S> {
pub fn for_package<PkgId: AsRef<crate::s9pk::manifest::PackageId<S0>>, S0: AsRef<str>>(
&self,
pkg_id: PkgId,
pkg_version: Option<&Version>,
) -> String {
format!(
"start9/{}/{}:{}",
pkg_id.as_ref(),
self.0,
pkg_version.map(|v| { v.as_str() }).unwrap_or("latest")
)
}
}
impl FromStr for ImageId {
type Err = InvalidId;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(ImageId(Id::try_from(s.to_owned())?))
}
}
impl<'de, S> Deserialize<'de> for ImageId<S>
where
S: AsRef<str>,
Id<S>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(ImageId(Deserialize::deserialize(deserializer)?))
}
}

View File

@@ -1,137 +0,0 @@
use std::time::Duration;
use tokio::process::Command;
use crate::context::rpc::RpcContextConfig;
use crate::db::model::ServerStatus;
use crate::install::PKG_DOCKER_DIR;
use crate::util::Invoke;
use crate::Error;
pub const SYSTEM_REBUILD_PATH: &str = "/embassy-os/system-rebuild";
pub async fn check_time_is_synchronized() -> Result<bool, Error> {
Ok(String::from_utf8(
Command::new("timedatectl")
.arg("show")
.arg("-p")
.arg("NTPSynchronized")
.invoke(crate::ErrorKind::Unknown)
.await?,
)?
.trim()
== "NTPSynchronized=yes")
}
pub async fn init(cfg: &RpcContextConfig, product_key: &str) -> Result<(), Error> {
let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok();
let secret_store = cfg.secret_store().await?;
let log_dir = cfg.datadir().join("main").join("logs");
if tokio::fs::metadata(&log_dir).await.is_err() {
tokio::fs::create_dir_all(&log_dir).await?;
}
crate::disk::mount::util::bind(&log_dir, "/var/log/journal", false).await?;
Command::new("systemctl")
.arg("restart")
.arg("systemd-journald")
.invoke(crate::ErrorKind::Journald)
.await?;
tracing::info!("Mounted Logs");
let tmp_dir = cfg.datadir().join("package-data/tmp");
if tokio::fs::metadata(&tmp_dir).await.is_err() {
tokio::fs::create_dir_all(&tmp_dir).await?;
}
let tmp_docker = cfg.datadir().join("package-data/tmp/docker");
let tmp_docker_exists = tokio::fs::metadata(&tmp_docker).await.is_ok();
if should_rebuild || !tmp_docker_exists {
if tmp_docker_exists {
tokio::fs::remove_dir_all(&tmp_docker).await?;
}
Command::new("cp")
.arg("-r")
.arg("/var/lib/docker")
.arg(&tmp_docker)
.invoke(crate::ErrorKind::Filesystem)
.await?;
}
Command::new("systemctl")
.arg("stop")
.arg("docker")
.invoke(crate::ErrorKind::Docker)
.await?;
crate::disk::mount::util::bind(&tmp_docker, "/var/lib/docker", false).await?;
Command::new("systemctl")
.arg("reset-failed")
.arg("docker")
.invoke(crate::ErrorKind::Docker)
.await?;
Command::new("systemctl")
.arg("start")
.arg("docker")
.invoke(crate::ErrorKind::Docker)
.await?;
tracing::info!("Mounted Docker Data");
if should_rebuild || !tmp_docker_exists {
tracing::info!("Loading System Docker Images");
crate::install::load_images("/var/lib/embassy/system-images").await?;
tracing::info!("Loaded System Docker Images");
tracing::info!("Loading Package Docker Images");
crate::install::load_images(cfg.datadir().join(PKG_DOCKER_DIR)).await?;
tracing::info!("Loaded Package Docker Images");
}
crate::ssh::sync_keys_from_db(&secret_store, "/root/.ssh/authorized_keys").await?;
tracing::info!("Synced SSH Keys");
let db = cfg.db(&secret_store, product_key).await?;
let mut handle = db.handle();
crate::net::wifi::synchronize_wpa_supplicant_conf(
&cfg.datadir().join("main"),
&*crate::db::DatabaseModel::new()
.server_info()
.last_wifi_region()
.get(&mut handle, false)
.await
.map_err(|_e| {
Error::new(
color_eyre::eyre::eyre!("Could not find the last wifi region"),
crate::ErrorKind::NotFound,
)
})?,
)
.await?;
tracing::info!("Synchronized wpa_supplicant.conf");
let mut info = crate::db::DatabaseModel::new()
.server_info()
.get_mut(&mut handle)
.await?;
info.status_info = ServerStatus {
backing_up: false,
updated: false,
update_progress: None,
};
info.save(&mut handle).await?;
let mut warn_time_not_synced = true;
for _ in 0..60 {
if check_time_is_synchronized().await? {
warn_time_not_synced = false;
break;
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
if warn_time_not_synced {
tracing::warn!("Timed out waiting for system time to synchronize");
}
crate::version::init(&mut handle).await?;
if should_rebuild {
tokio::fs::remove_file(SYSTEM_REBUILD_PATH).await?;
}
Ok(())
}

View File

@@ -1,92 +0,0 @@
use std::path::PathBuf;
use rpc_toolkit::command;
use crate::s9pk::manifest::Manifest;
use crate::s9pk::reader::S9pkReader;
use crate::util::display_none;
use crate::util::serde::{display_serializable, IoFormat};
use crate::Error;
#[command(subcommands(hash, manifest, license, icon, instructions, docker_images))]
pub fn inspect() -> Result<(), Error> {
Ok(())
}
#[command(cli_only)]
pub async fn hash(#[arg] path: PathBuf) -> Result<String, Error> {
Ok(S9pkReader::open(path, true)
.await?
.hash_str()
.unwrap()
.to_owned())
}
#[command(cli_only, display(display_serializable))]
pub async fn manifest(
#[arg] path: PathBuf,
#[arg(rename = "no-verify", long = "no-verify")] no_verify: bool,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<Manifest, Error> {
S9pkReader::open(path, !no_verify).await?.manifest().await
}
#[command(cli_only, display(display_none))]
pub async fn license(
#[arg] path: PathBuf,
#[arg(rename = "no-verify", long = "no-verify")] no_verify: bool,
) -> Result<(), Error> {
tokio::io::copy(
&mut S9pkReader::open(path, !no_verify).await?.license().await?,
&mut tokio::io::stdout(),
)
.await?;
Ok(())
}
#[command(cli_only, display(display_none))]
pub async fn icon(
#[arg] path: PathBuf,
#[arg(rename = "no-verify", long = "no-verify")] no_verify: bool,
) -> Result<(), Error> {
tokio::io::copy(
&mut S9pkReader::open(path, !no_verify).await?.icon().await?,
&mut tokio::io::stdout(),
)
.await?;
Ok(())
}
#[command(cli_only, display(display_none))]
pub async fn instructions(
#[arg] path: PathBuf,
#[arg(rename = "no-verify", long = "no-verify")] no_verify: bool,
) -> Result<(), Error> {
tokio::io::copy(
&mut S9pkReader::open(path, !no_verify)
.await?
.instructions()
.await?,
&mut tokio::io::stdout(),
)
.await?;
Ok(())
}
#[command(cli_only, display(display_none), rename = "docker-images")]
pub async fn docker_images(
#[arg] path: PathBuf,
#[arg(rename = "no-verify", long = "no-verify")] no_verify: bool,
) -> Result<(), Error> {
tokio::io::copy(
&mut S9pkReader::open(path, !no_verify)
.await?
.docker_images()
.await?,
&mut tokio::io::stdout(),
)
.await?;
Ok(())
}

View File

@@ -1,310 +0,0 @@
use std::collections::{BTreeMap, HashMap};
use bollard::image::ListImagesOptions;
use color_eyre::eyre::eyre;
use patch_db::{DbHandle, LockType, PatchDbHandle};
use sqlx::{Executor, Sqlite};
use tracing::instrument;
use super::{PKG_ARCHIVE_DIR, PKG_DOCKER_DIR};
use crate::context::RpcContext;
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry};
use crate::dependencies::reconfigure_dependents_with_live_pointers;
use crate::error::ErrorCollection;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::util::{Apply, Version};
use crate::Error;
#[instrument(skip(ctx, db, deps))]
pub async fn update_dependency_errors_of_dependents<
'a,
Db: DbHandle,
I: IntoIterator<Item = &'a PackageId>,
>(
ctx: &RpcContext,
db: &mut Db,
id: &PackageId,
deps: I,
) -> Result<(), Error> {
for dep in deps {
if let Some(man) = &*crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dep)
.and_then(|m| m.installed())
.map::<_, Manifest>(|m| m.manifest())
.get(db, true)
.await?
{
if let Err(e) = if let Some(info) = man.dependencies.0.get(id) {
info.satisfied(ctx, db, id, None, dep).await?
} else {
Ok(())
} {
let mut errs = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dep)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.status()
.dependency_errors()
.get_mut(db)
.await?;
errs.0.insert(id.clone(), e);
errs.save(db).await?;
} else {
let mut errs = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dep)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.status()
.dependency_errors()
.get_mut(db)
.await?;
errs.0.remove(id);
errs.save(db).await?;
}
}
}
Ok(())
}
#[instrument(skip(ctx))]
pub async fn cleanup(ctx: &RpcContext, id: &PackageId, version: &Version) -> Result<(), Error> {
let mut errors = ErrorCollection::new();
ctx.managers.remove(&(id.clone(), version.clone())).await;
// docker images start9/$APP_ID/*:$VERSION -q | xargs docker rmi
let images = ctx
.docker
.list_images(Some(ListImagesOptions {
all: false,
filters: {
let mut f = HashMap::new();
f.insert(
"reference".to_owned(),
vec![format!("start9/{}/*:{}", id, version)],
);
f
},
digests: false,
}))
.await
.apply(|res| errors.handle(res));
errors.extend(
futures::future::join_all(images.into_iter().flatten().map(|image| async {
let image = image; // move into future
ctx.docker.remove_image(&image.id, None, None).await
}))
.await,
);
let pkg_archive_dir = ctx
.datadir
.join(PKG_ARCHIVE_DIR)
.join(id)
.join(version.as_str());
if tokio::fs::metadata(&pkg_archive_dir).await.is_ok() {
tokio::fs::remove_dir_all(&pkg_archive_dir)
.await
.apply(|res| errors.handle(res));
}
let docker_path = ctx
.datadir
.join(PKG_DOCKER_DIR)
.join(id)
.join(version.as_str());
if tokio::fs::metadata(&docker_path).await.is_ok() {
tokio::fs::remove_dir_all(&docker_path)
.await
.apply(|res| errors.handle(res));
}
errors.into_result()
}
#[instrument(skip(ctx, db))]
pub async fn cleanup_failed<Db: DbHandle>(
ctx: &RpcContext,
db: &mut Db,
id: &PackageId,
) -> Result<(), Error> {
crate::db::DatabaseModel::new()
.package_data()
.lock(db, LockType::Write)
.await?;
let pde = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.expect(db)
.await?
.get(db, true)
.await?
.into_owned();
if let Some(manifest) = match &pde {
PackageDataEntry::Installing { manifest, .. }
| PackageDataEntry::Restoring { manifest, .. } => Some(manifest),
PackageDataEntry::Updating {
manifest,
installed:
InstalledPackageDataEntry {
manifest: installed_manifest,
..
},
..
} => {
if &manifest.version != &installed_manifest.version {
Some(manifest)
} else {
None
}
}
_ => {
tracing::warn!("{}: Nothing to clean up!", id);
None
}
} {
cleanup(ctx, id, &manifest.version).await?;
}
match pde {
PackageDataEntry::Installing { .. } | PackageDataEntry::Restoring { .. } => {
crate::db::DatabaseModel::new()
.package_data()
.remove(db, id)
.await?;
}
PackageDataEntry::Updating {
installed,
static_files,
..
} => {
crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.put(
db,
&PackageDataEntry::Installed {
manifest: installed.manifest.clone(),
installed,
static_files,
},
)
.await?;
}
_ => (),
}
Ok(())
}
#[instrument(skip(db, current_dependencies))]
pub async fn remove_from_current_dependents_lists<
'a,
Db: DbHandle,
I: IntoIterator<Item = &'a PackageId>,
>(
db: &mut Db,
id: &'a PackageId,
current_dependencies: I,
) -> Result<(), Error> {
for dep in current_dependencies.into_iter().chain(std::iter::once(id)) {
if let Some(current_dependents) = crate::db::DatabaseModel::new()
.package_data()
.idx_model(dep)
.and_then(|m| m.installed())
.map::<_, BTreeMap<PackageId, CurrentDependencyInfo>>(|m| m.current_dependents())
.check(db)
.await?
{
if current_dependents
.clone()
.idx_model(id)
.exists(db, true)
.await?
{
current_dependents.remove(db, id).await?
}
}
}
Ok(())
}
#[instrument(skip(ctx, secrets, db))]
pub async fn uninstall<Ex>(
ctx: &RpcContext,
db: &mut PatchDbHandle,
secrets: &mut Ex,
id: &PackageId,
) -> Result<(), Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let mut tx = db.begin().await?;
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut tx, LockType::Write)
.await?;
let entry = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
.and_then(|pde| pde.removing())
.get(&mut tx, true)
.await?
.into_owned()
.ok_or_else(|| {
Error::new(
eyre!("Package not in removing state: {}", id),
crate::ErrorKind::NotFound,
)
})?;
cleanup(ctx, &entry.manifest.id, &entry.manifest.version).await?;
crate::db::DatabaseModel::new()
.package_data()
.remove(&mut tx, id)
.await?;
// once we have removed the package entry, we can change all the dependent pointers to null
reconfigure_dependents_with_live_pointers(ctx, &mut tx, &entry).await?;
remove_from_current_dependents_lists(
&mut tx,
&entry.manifest.id,
entry.current_dependencies.keys(),
)
.await?;
update_dependency_errors_of_dependents(
ctx,
&mut tx,
&entry.manifest.id,
entry.current_dependents.keys(),
)
.await?;
let volumes = ctx
.datadir
.join(crate::volume::PKG_VOLUME_DIR)
.join(&entry.manifest.id);
if tokio::fs::metadata(&volumes).await.is_ok() {
tokio::fs::remove_dir_all(&volumes).await?;
}
tx.commit(None).await?;
remove_tor_keys(secrets, &entry.manifest.id).await?;
Ok(())
}
#[instrument(skip(secrets))]
pub async fn remove_tor_keys<Ex>(secrets: &mut Ex, id: &PackageId) -> Result<(), Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let id_str = id.as_str();
sqlx::query!("DELETE FROM tor WHERE package = ?", id_str)
.execute(secrets)
.await?;
Ok(())
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,217 +0,0 @@
use std::future::Future;
use std::io::SeekFrom;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll};
use std::time::Duration;
use patch_db::{DbHandle, HasModel, OptionModel, PatchDb};
use serde::{Deserialize, Serialize};
use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
use crate::Error;
#[derive(Debug, Deserialize, Serialize, HasModel, Default)]
#[serde(rename_all = "kebab-case")]
pub struct InstallProgress {
pub size: Option<u64>,
pub downloaded: AtomicU64,
pub download_complete: AtomicBool,
pub validated: AtomicU64,
pub validation_complete: AtomicBool,
pub unpacked: AtomicU64,
pub unpack_complete: AtomicBool,
}
impl InstallProgress {
pub fn new(size: Option<u64>) -> Arc<Self> {
Arc::new(InstallProgress {
size,
downloaded: AtomicU64::new(0),
download_complete: AtomicBool::new(false),
validated: AtomicU64::new(0),
validation_complete: AtomicBool::new(false),
unpacked: AtomicU64::new(0),
unpack_complete: AtomicBool::new(false),
})
}
pub fn download_complete(&self) {
self.download_complete.store(true, Ordering::SeqCst)
}
pub async fn track_download<Db: DbHandle>(
self: Arc<Self>,
model: OptionModel<InstallProgress>,
mut db: Db,
) -> Result<(), Error> {
while !self.download_complete.load(Ordering::SeqCst) {
model.put(&mut db, &self).await?;
tokio::time::sleep(Duration::from_secs(1)).await;
}
model.put(&mut db, &self).await?;
Ok(())
}
pub async fn track_download_during<
F: FnOnce() -> Fut,
Fut: Future<Output = Result<T, Error>>,
T,
>(
self: &Arc<Self>,
model: OptionModel<InstallProgress>,
db: &PatchDb,
f: F,
) -> Result<T, Error> {
let local_db = db.handle();
let tracker = tokio::spawn(self.clone().track_download(model.clone(), local_db));
let res = f().await;
self.download_complete.store(true, Ordering::SeqCst);
tracker.await.unwrap()?;
res
}
pub async fn track_read<Db: DbHandle>(
self: Arc<Self>,
model: OptionModel<InstallProgress>,
mut db: Db,
complete: Arc<AtomicBool>,
) -> Result<(), Error> {
while !complete.load(Ordering::SeqCst) {
model.put(&mut db, &self).await?;
tokio::time::sleep(Duration::from_secs(1)).await;
}
model.put(&mut db, &self).await?;
Ok(())
}
pub async fn track_read_during<
F: FnOnce() -> Fut,
Fut: Future<Output = Result<T, Error>>,
T,
>(
self: &Arc<Self>,
model: OptionModel<InstallProgress>,
db: &PatchDb,
f: F,
) -> Result<T, Error> {
let local_db = db.handle();
let complete = Arc::new(AtomicBool::new(false));
let tracker = tokio::spawn(self.clone().track_read(
model.clone(),
local_db,
complete.clone(),
));
let res = f().await;
complete.store(true, Ordering::SeqCst);
tracker.await.unwrap()?;
res
}
}
#[pin_project::pin_project]
pub struct InstallProgressTracker<RW> {
#[pin]
inner: RW,
validating: bool,
progress: Arc<InstallProgress>,
}
impl<RW> InstallProgressTracker<RW> {
pub fn new(inner: RW, progress: Arc<InstallProgress>) -> Self {
InstallProgressTracker {
inner,
validating: true,
progress,
}
}
pub fn validated(&mut self) {
self.progress
.validation_complete
.store(true, Ordering::SeqCst);
self.validating = false;
}
}
impl<W: AsyncWrite> AsyncWrite for InstallProgressTracker<W> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, std::io::Error>> {
let this = self.project();
match this.inner.poll_write(cx, buf) {
Poll::Ready(Ok(n)) => {
this.progress
.downloaded
.fetch_add(n as u64, Ordering::SeqCst);
Poll::Ready(Ok(n))
}
a => a,
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
let this = self.project();
this.inner.poll_flush(cx)
}
fn poll_shutdown(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), std::io::Error>> {
let this = self.project();
this.inner.poll_shutdown(cx)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[std::io::IoSlice<'_>],
) -> Poll<Result<usize, std::io::Error>> {
let this = self.project();
match this.inner.poll_write_vectored(cx, bufs) {
Poll::Ready(Ok(n)) => {
this.progress
.downloaded
.fetch_add(n as u64, Ordering::SeqCst);
Poll::Ready(Ok(n))
}
a => a,
}
}
}
impl<R: AsyncRead> AsyncRead for InstallProgressTracker<R> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
let this = self.project();
let prev = buf.filled().len() as u64;
match this.inner.poll_read(cx, buf) {
Poll::Ready(Ok(())) => {
if *this.validating {
&this.progress.validated
} else {
&this.progress.unpacked
}
.fetch_add(buf.filled().len() as u64 - prev, Ordering::SeqCst);
Poll::Ready(Ok(()))
}
a => a,
}
}
}
impl<R: AsyncSeek> AsyncSeek for InstallProgressTracker<R> {
fn start_seek(self: Pin<&mut Self>, position: SeekFrom) -> std::io::Result<()> {
let this = self.project();
this.inner.start_seek(position)
}
fn poll_complete(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<u64>> {
let this = self.project();
match this.inner.poll_complete(cx) {
Poll::Ready(Ok(n)) => {
if *this.validating {
&this.progress.validated
} else {
&this.progress.unpacked
}
.store(n, Ordering::SeqCst);
Poll::Ready(Ok(n))
}
a => a,
}
}
}

View File

@@ -1,74 +0,0 @@
use std::collections::BTreeMap;
use patch_db::{DbHandle, LockType};
use rpc_toolkit::command;
use crate::context::RpcContext;
use crate::dependencies::{break_transitive, BreakageRes, DependencyError};
use crate::s9pk::manifest::PackageId;
use crate::util::serde::display_serializable;
use crate::util::Version;
use crate::Error;
#[command(subcommands(dry))]
pub async fn update() -> Result<(), Error> {
Ok(())
}
#[command(display(display_serializable))]
pub async fn dry(
#[context] ctx: RpcContext,
#[arg] id: PackageId,
#[arg] version: Version,
) -> Result<BreakageRes, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut tx, LockType::Read)
.await?;
for dependent in crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?
.current_dependents()
.keys(&mut tx, true)
.await?
.into_iter()
.filter(|dependent| &id != dependent)
{
let version_req = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dependent)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?
.manifest()
.dependencies()
.idx_model(&id)
.expect(&mut tx)
.await?
.get(&mut tx, true)
.await?
.into_owned()
.version;
if !version.satisfies(&version_req) {
break_transitive(
&mut tx,
&dependent,
&id,
DependencyError::IncorrectVersion {
expected: version_req,
received: version.clone(),
},
&mut breakages,
)
.await?;
}
}
tx.abort().await?;
Ok(BreakageRes(breakages))
}

View File

@@ -1,130 +0,0 @@
pub const CONFIG_PATH: &str = "/etc/embassy/config.yaml";
#[cfg(not(feature = "beta"))]
pub const DEFAULT_MARKETPLACE: &str = "https://marketplace.start9.com";
#[cfg(feature = "beta")]
pub const DEFAULT_MARKETPLACE: &str = "https://beta-registry-0-3.start9labs.com";
pub const BUFFER_SIZE: usize = 1024;
pub const HOST_IP: [u8; 4] = [172, 18, 0, 1];
pub mod action;
pub mod auth;
pub mod backup;
pub mod config;
pub mod context;
pub mod control;
pub mod core;
pub mod db;
pub mod dependencies;
pub mod developer;
pub mod diagnostic;
pub mod disk;
pub mod error;
pub mod hostname;
pub mod id;
pub mod init;
pub mod inspect;
pub mod install;
pub mod logs;
pub mod manager;
pub mod marketplace;
pub mod middleware;
pub mod migration;
pub mod net;
pub mod notifications;
pub mod properties;
pub mod s9pk;
pub mod setup;
pub mod shutdown;
pub mod sound;
pub mod ssh;
pub mod static_server;
pub mod status;
pub mod system;
pub mod update;
pub mod util;
pub mod version;
pub mod volume;
pub use config::Config;
pub use error::{Error, ErrorKind, ResultExt};
use rpc_toolkit::command;
use rpc_toolkit::yajrc::RpcError;
#[command(metadata(authenticated = false))]
pub fn echo(#[arg] message: String) -> Result<String, RpcError> {
Ok(message)
}
#[command(subcommands(
version::git_info,
echo,
inspect::inspect,
server,
package,
net::net,
auth::auth,
db::db,
ssh::ssh,
net::wifi::wifi,
disk::disk,
notifications::notification,
backup::backup,
marketplace::marketplace,
))]
pub fn main_api() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(
system::logs,
system::kernel_logs,
system::metrics,
shutdown::shutdown,
shutdown::restart,
shutdown::rebuild,
update::update_system,
))]
pub fn server() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(
action::action,
install::install,
install::sideload,
install::uninstall,
install::delete_recovered,
install::list,
install::update::update,
config::config,
control::start,
control::stop,
logs::logs,
properties::properties,
dependencies::dependency,
backup::package_backup,
))]
pub fn package() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(
version::git_info,
s9pk::pack,
developer::verify,
developer::init,
inspect::inspect
))]
pub fn portable_api() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(version::git_info, echo, diagnostic::diagnostic))]
pub fn diagnostic_api() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(version::git_info, echo, setup::setup))]
pub fn setup_api() -> Result<(), RpcError> {
Ok(())
}

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