Compare commits
18 Commits
v0.3.4.1-r
...
v0.3.4.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efc56c0a88 | ||
|
|
321fca2c0a | ||
|
|
bbd66e9cb0 | ||
|
|
eb0277146c | ||
|
|
10ee32ec48 | ||
|
|
bdb4be89ff | ||
|
|
61445e0b56 | ||
|
|
f15a010e0e | ||
|
|
58747004fe | ||
|
|
e7ff1eb66b | ||
|
|
4a00bd4797 | ||
|
|
2e6fc7e4a0 | ||
|
|
4a8f323be7 | ||
|
|
c7d82102ed | ||
|
|
068b861edc | ||
|
|
3c908c6a09 | ||
|
|
ba3805786c | ||
|
|
70afb197f1 |
16
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: 🐛 Bug Report
|
name: 🐛 Bug Report
|
||||||
description: Create a report to help us improve embassyOS
|
description: Create a report to help us improve StartOS
|
||||||
title: '[bug]: '
|
title: "[bug]: "
|
||||||
labels: [Bug, Needs Triage]
|
labels: [Bug, Needs Triage]
|
||||||
assignees:
|
assignees:
|
||||||
- MattDHill
|
- MattDHill
|
||||||
@@ -10,19 +10,19 @@ body:
|
|||||||
label: Prerequisites
|
label: Prerequisites
|
||||||
description: Please confirm you have completed the following.
|
description: Please confirm you have completed the following.
|
||||||
options:
|
options:
|
||||||
- label: I have searched for [existing issues](https://github.com/start9labs/embassy-os/issues) that already report this problem.
|
- label: I have searched for [existing issues](https://github.com/start9labs/start-os/issues) that already report this problem.
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
attributes:
|
attributes:
|
||||||
label: embassyOS Version
|
label: StartOS Version
|
||||||
description: What version of embassyOS are you running?
|
description: What version of StartOS are you running?
|
||||||
placeholder: e.g. 0.3.0
|
placeholder: e.g. 0.3.4.2
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
attributes:
|
attributes:
|
||||||
label: Device
|
label: Device
|
||||||
description: What device are you using to connect to Embassy?
|
description: What device are you using to connect to your server?
|
||||||
options:
|
options:
|
||||||
- Phone/tablet
|
- Phone/tablet
|
||||||
- Laptop/Desktop
|
- Laptop/Desktop
|
||||||
@@ -52,7 +52,7 @@ body:
|
|||||||
- type: dropdown
|
- type: dropdown
|
||||||
attributes:
|
attributes:
|
||||||
label: Browser
|
label: Browser
|
||||||
description: What browser are you using to connect to Embassy?
|
description: What browser are you using to connect to your server?
|
||||||
options:
|
options:
|
||||||
- Firefox
|
- Firefox
|
||||||
- Brave
|
- Brave
|
||||||
|
|||||||
8
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: 💡 Feature Request
|
name: 💡 Feature Request
|
||||||
description: Suggest an idea for embassyOS
|
description: Suggest an idea for StartOS
|
||||||
title: '[feat]: '
|
title: "[feat]: "
|
||||||
labels: [Enhancement]
|
labels: [Enhancement]
|
||||||
assignees:
|
assignees:
|
||||||
- MattDHill
|
- MattDHill
|
||||||
@@ -10,7 +10,7 @@ body:
|
|||||||
label: Prerequisites
|
label: Prerequisites
|
||||||
description: Please confirm you have completed the following.
|
description: Please confirm you have completed the following.
|
||||||
options:
|
options:
|
||||||
- label: I have searched for [existing issues](https://github.com/start9labs/embassy-os/issues) that already suggest this feature.
|
- label: I have searched for [existing issues](https://github.com/start9labs/start-os/issues) that already suggest this feature.
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
@@ -27,7 +27,7 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Describe Preferred Solution
|
label: Describe Preferred Solution
|
||||||
description: How you want this feature added to embassyOS?
|
description: How you want this feature added to StartOS?
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Describe Alternatives
|
label: Describe Alternatives
|
||||||
|
|||||||
63
.github/workflows/debian.yaml
vendored
@@ -1,63 +0,0 @@
|
|||||||
name: Debian Package
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODEJS_VERSION: '16.11.0'
|
|
||||||
ENVIRONMENT: "dev"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dpkg:
|
|
||||||
name: Build dpkg
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: Start9Labs/embassy-os-deb
|
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
path: embassyos-0.3.x
|
|
||||||
- run: |
|
|
||||||
cp -r debian embassyos-0.3.x/
|
|
||||||
VERSION=0.3.x ./control.sh
|
|
||||||
cp embassyos-0.3.x/backend/embassyd.service embassyos-0.3.x/debian/embassyos.embassyd.service
|
|
||||||
cp embassyos-0.3.x/backend/embassy-init.service embassyos-0.3.x/debian/embassyos.embassy-init.service
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.NODEJS_VERSION }}
|
|
||||||
|
|
||||||
- name: Get npm cache directory
|
|
||||||
id: npm-cache-dir
|
|
||||||
run: |
|
|
||||||
echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
id: npm-cache
|
|
||||||
with:
|
|
||||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-node-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install debmake debhelper-compat
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v2
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Run build
|
|
||||||
run: "make VERSION=0.3.x TAG=${{ github.ref_name }}"
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: deb
|
|
||||||
path: embassyos_0.3.x-1_amd64.deb
|
|
||||||
2
.github/workflows/frontend.yaml
vendored
@@ -5,7 +5,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NODEJS_VERSION: '16.11.0'
|
NODEJS_VERSION: '18.15.0'
|
||||||
ENVIRONMENT: "dev"
|
ENVIRONMENT: "dev"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
129
.github/workflows/product.yaml
vendored
@@ -1,129 +0,0 @@
|
|||||||
name: Build Pipeline
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
|
|
||||||
env:
|
|
||||||
ENVIRONMENT: "dev"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
compat:
|
|
||||||
uses: ./.github/workflows/reusable-workflow.yaml
|
|
||||||
with:
|
|
||||||
build_command: make system-images/compat/docker-images/aarch64.tar
|
|
||||||
artifact_name: compat.tar
|
|
||||||
artifact_path: system-images/compat/docker-images/aarch64.tar
|
|
||||||
|
|
||||||
utils:
|
|
||||||
uses: ./.github/workflows/reusable-workflow.yaml
|
|
||||||
with:
|
|
||||||
build_command: make system-images/utils/docker-images/aarch64.tar
|
|
||||||
artifact_name: utils.tar
|
|
||||||
artifact_path: system-images/utils/docker-images/aarch64.tar
|
|
||||||
|
|
||||||
binfmt:
|
|
||||||
uses: ./.github/workflows/reusable-workflow.yaml
|
|
||||||
with:
|
|
||||||
build_command: make system-images/binfmt/docker-images/aarch64.tar
|
|
||||||
artifact_name: binfmt.tar
|
|
||||||
artifact_path: system-images/binfmt/docker-images/aarch64.tar
|
|
||||||
|
|
||||||
backend:
|
|
||||||
uses: ./.github/workflows/backend.yaml
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
uses: ./.github/workflows/frontend.yaml
|
|
||||||
|
|
||||||
image:
|
|
||||||
name: Build image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 60
|
|
||||||
needs: [compat,utils,binfmt,backend,frontend]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Download compat.tar artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: compat.tar
|
|
||||||
path: system-images/compat/docker-images/
|
|
||||||
|
|
||||||
- name: Download utils.tar artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: utils.tar
|
|
||||||
path: system-images/utils/docker-images/
|
|
||||||
|
|
||||||
- name: Download binfmt.tar artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: binfmt.tar
|
|
||||||
path: system-images/binfmt/docker-images/
|
|
||||||
|
|
||||||
- name: Download js_snapshot artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: js_snapshot
|
|
||||||
path: libs/js_engine/src/artifacts/
|
|
||||||
|
|
||||||
- name: Download arm_js_snapshot artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: arm_js_snapshot
|
|
||||||
path: libs/js_engine/src/artifacts/
|
|
||||||
|
|
||||||
- name: Download backend artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: backend-aarch64
|
|
||||||
|
|
||||||
- name: 'Extract backend'
|
|
||||||
run:
|
|
||||||
tar -mxvf backend-aarch64.tar
|
|
||||||
|
|
||||||
- name: Download frontend artifact
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: frontend
|
|
||||||
|
|
||||||
- name: Skip frontend build
|
|
||||||
run: |
|
|
||||||
mkdir frontend/node_modules
|
|
||||||
mkdir frontend/dist
|
|
||||||
mkdir patch-db/client/node_modules
|
|
||||||
mkdir patch-db/client/dist
|
|
||||||
|
|
||||||
- name: 'Extract frontend'
|
|
||||||
run: |
|
|
||||||
tar -mxvf frontend.tar frontend/config.json
|
|
||||||
tar -mxvf frontend.tar frontend/dist
|
|
||||||
tar -xvf frontend.tar GIT_HASH.txt
|
|
||||||
tar -xvf frontend.tar ENVIRONMENT.txt
|
|
||||||
tar -xvf frontend.tar VERSION.txt
|
|
||||||
rm frontend.tar
|
|
||||||
|
|
||||||
- name: Cache raspiOS
|
|
||||||
id: cache-raspios
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: raspios.img
|
|
||||||
key: cache-raspios
|
|
||||||
|
|
||||||
- name: Build image
|
|
||||||
run: |
|
|
||||||
make V=1 eos_raspberrypi-uninit.img --debug
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: image
|
|
||||||
path: eos_raspberrypi-uninit.img
|
|
||||||
70
.github/workflows/pureos-iso.yaml
vendored
@@ -1,70 +0,0 @@
|
|||||||
name: PureOS Based ISO
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
|
|
||||||
env:
|
|
||||||
ENVIRONMENT: "dev"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dpkg:
|
|
||||||
uses: ./.github/workflows/debian.yaml
|
|
||||||
|
|
||||||
iso:
|
|
||||||
name: Build iso
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
needs: [dpkg]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: Start9Labs/eos-image-recipes
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
wget http://ftp.us.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.1-1_all.deb
|
|
||||||
sha256sum ./debspawn_0.6.1-1_all.deb | grep fb8a3f588438ff9ef51e713ec1d83306db893f0aa97447565e28bbba9c6e90c6
|
|
||||||
sudo apt-get install -y ./debspawn_0.6.1-1_all.deb
|
|
||||||
wget https://repo.pureos.net/pureos/pool/main/d/debootstrap/debootstrap_1.0.125pureos1_all.deb
|
|
||||||
sudo apt-get install -y --allow-downgrades ./debootstrap_1.0.125pureos1_all.deb
|
|
||||||
wget https://repo.pureos.net/pureos/pool/main/p/pureos-archive-keyring/pureos-archive-keyring_2021.11.0_all.deb
|
|
||||||
sudo apt-get install -y ./pureos-archive-keyring_2021.11.0_all.deb
|
|
||||||
|
|
||||||
- name: Configure debspawn
|
|
||||||
run: |
|
|
||||||
sudo mkdir -p /etc/debspawn/
|
|
||||||
echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: /var/lib/debspawn
|
|
||||||
key: ${{ runner.os }}-debspawn-init-byzantium
|
|
||||||
|
|
||||||
- name: Make build container
|
|
||||||
run: "debspawn list | grep byzantium || debspawn create --with-init byzantium"
|
|
||||||
|
|
||||||
- run: "mkdir -p overlays/vendor/root"
|
|
||||||
|
|
||||||
- name: Download dpkg
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: deb
|
|
||||||
path: overlays/vendor/root
|
|
||||||
|
|
||||||
- name: Run build
|
|
||||||
run: |
|
|
||||||
./run-local-build.sh --no-fakemachine byzantium none custom "" true
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: iso
|
|
||||||
path: results/*.iso
|
|
||||||
173
.github/workflows/startos-iso.yaml
vendored
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
name: Debian-based ISO and SquashFS
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
environment:
|
||||||
|
type: choice
|
||||||
|
description: Environment
|
||||||
|
options:
|
||||||
|
- "<NONE>"
|
||||||
|
- dev
|
||||||
|
- unstable
|
||||||
|
- dev-unstable
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- next
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- next
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODEJS_VERSION: "18.15.0"
|
||||||
|
ENVIRONMENT: '${{ fromJson(format(''["{0}", ""]'', github.event.inputs.environment || ''dev''))[github.event.inputs.environment == ''<NONE>''] }}'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dpkg:
|
||||||
|
name: Build dpkg
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
[x86_64, x86_64-nonfree, aarch64, aarch64-nonfree, raspberrypi]
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: Start9Labs/embassy-os-deb
|
||||||
|
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
path: embassyos-0.3.x
|
||||||
|
- run: |
|
||||||
|
cp -r debian embassyos-0.3.x/
|
||||||
|
VERSION=0.3.x ./control.sh
|
||||||
|
cp embassyos-0.3.x/backend/embassyd.service embassyos-0.3.x/debian/embassyos.embassyd.service
|
||||||
|
cp embassyos-0.3.x/backend/embassy-init.service embassyos-0.3.x/debian/embassyos.embassy-init.service
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODEJS_VERSION }}
|
||||||
|
|
||||||
|
- name: Get npm cache directory
|
||||||
|
id: npm-cache-dir
|
||||||
|
run: |
|
||||||
|
echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
id: npm-cache
|
||||||
|
with:
|
||||||
|
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install \
|
||||||
|
debmake \
|
||||||
|
debhelper-compat \
|
||||||
|
crossbuild-essential-arm64
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Run build
|
||||||
|
run: "make VERSION=0.3.x TAG=${{ github.ref_name }}"
|
||||||
|
env:
|
||||||
|
OS_ARCH: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}.deb
|
||||||
|
path: embassyos_0.3.x-1_*.deb
|
||||||
|
|
||||||
|
iso:
|
||||||
|
name: Build iso
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
[x86_64, x86_64-nonfree, aarch64, aarch64-nonfree, raspberrypi]
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
needs: [dpkg]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: Start9Labs/startos-image-recipes
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y qemu-user-static
|
||||||
|
wget http://ftp.us.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.1-1_all.deb
|
||||||
|
sha256sum ./debspawn_0.6.1-1_all.deb | grep fb8a3f588438ff9ef51e713ec1d83306db893f0aa97447565e28bbba9c6e90c6
|
||||||
|
sudo apt-get install -y ./debspawn_0.6.1-1_all.deb
|
||||||
|
|
||||||
|
- name: Configure debspawn
|
||||||
|
run: |
|
||||||
|
sudo mkdir -p /etc/debspawn/
|
||||||
|
echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml
|
||||||
|
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /var/lib/debspawn
|
||||||
|
key: ${{ runner.os }}-debspawn-init-bullseye
|
||||||
|
|
||||||
|
- name: Make build container
|
||||||
|
run: "debspawn list | grep bullseye || debspawn create bullseye"
|
||||||
|
|
||||||
|
- run: "mkdir -p overlays/deb"
|
||||||
|
|
||||||
|
- name: Download dpkg
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}.deb
|
||||||
|
path: overlays/deb
|
||||||
|
|
||||||
|
- name: Run build
|
||||||
|
run: |
|
||||||
|
./run-local-build.sh ${{ matrix.platform }}
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}.squashfs
|
||||||
|
path: results/*.squashfs
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}.iso
|
||||||
|
path: results/*.iso
|
||||||
|
if: ${{ matrix.platform != 'raspberrypi' }}
|
||||||
|
|
||||||
|
image:
|
||||||
|
name: Build image
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
timeout-minutes: 60
|
||||||
|
needs: [iso]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Download raspberrypi.squashfs artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: raspberrypi.squashfs
|
||||||
|
|
||||||
|
- run: mv startos-*_raspberrypi.squashfs startos.raspberrypi.squashfs
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
run: make startos_raspberrypi.img
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: raspberrypi.img
|
||||||
|
path: startos-*_raspberrypi.img
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<!-- omit in toc -->
|
<!-- omit in toc -->
|
||||||
|
|
||||||
# Contributing to Embassy OS
|
# Contributing to StartOS
|
||||||
|
|
||||||
First off, thanks for taking the time to contribute! ❤️
|
First off, thanks for taking the time to contribute! ❤️
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ forward to your contributions. 🎉
|
|||||||
> - Tweet about it
|
> - Tweet about it
|
||||||
> - Refer this project in your project's readme
|
> - Refer this project in your project's readme
|
||||||
> - Mention the project at local meetups and tell your friends/colleagues
|
> - Mention the project at local meetups and tell your friends/colleagues
|
||||||
> - Buy an [Embassy](https://start9labs.com)
|
> - Buy a [Start9 server](https://start9.com)
|
||||||
|
|
||||||
<!-- omit in toc -->
|
<!-- omit in toc -->
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ forward to your contributions. 🎉
|
|||||||
> [Documentation](https://docs.start9labs.com).
|
> [Documentation](https://docs.start9labs.com).
|
||||||
|
|
||||||
Before you ask a question, it is best to search for existing
|
Before you ask a question, it is best to search for existing
|
||||||
[Issues](https://github.com/Start9Labs/embassy-os/issues) that might help you.
|
[Issues](https://github.com/Start9Labs/start-os/issues) that might help you.
|
||||||
In case you have found a suitable issue and still need clarification, you can
|
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
|
write your question in this issue. It is also advisable to search the internet
|
||||||
for answers first.
|
for answers first.
|
||||||
@@ -57,7 +57,7 @@ for answers first.
|
|||||||
If you then still feel the need to ask a question and need clarification, we
|
If you then still feel the need to ask a question and need clarification, we
|
||||||
recommend the following:
|
recommend the following:
|
||||||
|
|
||||||
- Open an [Issue](https://github.com/Start9Labs/embassy-os/issues/new).
|
- Open an [Issue](https://github.com/Start9Labs/start-os/issues/new).
|
||||||
- Provide as much context as you can about what you're running into.
|
- Provide as much context as you can about what you're running into.
|
||||||
- Provide project and platform versions, depending on what seems relevant.
|
- Provide project and platform versions, depending on what seems relevant.
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ steps in advance to help us fix any potential bug as fast as possible.
|
|||||||
- To see if other users have experienced (and potentially already solved) the
|
- 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
|
same issue you are having, check if there is not already a bug report existing
|
||||||
for your bug or error in the
|
for your bug or error in the
|
||||||
[bug tracker](https://github.com/Start9Labs/embassy-os/issues?q=label%3Abug).
|
[bug tracker](https://github.com/Start9Labs/start-os/issues?q=label%3Abug).
|
||||||
- Also make sure to search the internet (including Stack Overflow) to see if
|
- Also make sure to search the internet (including Stack Overflow) to see if
|
||||||
users outside of the GitHub community have discussed the issue.
|
users outside of the GitHub community have discussed the issue.
|
||||||
- Collect information about the bug:
|
- Collect information about the bug:
|
||||||
@@ -131,7 +131,7 @@ steps in advance to help us fix any potential bug as fast as possible.
|
|||||||
We use GitHub issues to track bugs and errors. If you run into an issue with the
|
We use GitHub issues to track bugs and errors. If you run into an issue with the
|
||||||
project:
|
project:
|
||||||
|
|
||||||
- Open an [Issue](https://github.com/Start9Labs/embassy-os/issues/new/choose)
|
- Open an [Issue](https://github.com/Start9Labs/start-os/issues/new/choose)
|
||||||
selecting the appropriate type.
|
selecting the appropriate type.
|
||||||
- Explain the behavior you would expect and the actual behavior.
|
- Explain the behavior you would expect and the actual behavior.
|
||||||
- Please provide as much context as possible and describe the _reproduction
|
- Please provide as much context as possible and describe the _reproduction
|
||||||
@@ -155,8 +155,7 @@ Once it's filed:
|
|||||||
|
|
||||||
### Suggesting Enhancements
|
### Suggesting Enhancements
|
||||||
|
|
||||||
This section guides you through submitting an enhancement suggestion for Embassy
|
This section guides you through submitting an enhancement suggestion for StartOS, **including completely new features and minor improvements to existing
|
||||||
OS, **including completely new features and minor improvements to existing
|
|
||||||
functionality**. Following these guidelines will help maintainers and the
|
functionality**. Following these guidelines will help maintainers and the
|
||||||
community to understand your suggestion and find related suggestions.
|
community to understand your suggestion and find related suggestions.
|
||||||
|
|
||||||
@@ -168,7 +167,7 @@ community to understand your suggestion and find related suggestions.
|
|||||||
- Read the [documentation](https://start9.com/latest/user-manual) carefully and
|
- Read the [documentation](https://start9.com/latest/user-manual) carefully and
|
||||||
find out if the functionality is already covered, maybe by an individual
|
find out if the functionality is already covered, maybe by an individual
|
||||||
configuration.
|
configuration.
|
||||||
- Perform a [search](https://github.com/Start9Labs/embassy-os/issues) to see if
|
- Perform a [search](https://github.com/Start9Labs/start-os/issues) to see if
|
||||||
the enhancement has already been suggested. If it has, add a comment to the
|
the enhancement has already been suggested. If it has, add a comment to the
|
||||||
existing issue instead of opening a new one.
|
existing issue instead of opening a new one.
|
||||||
- Find out whether your idea fits with the scope and aims of the project. It's
|
- Find out whether your idea fits with the scope and aims of the project. It's
|
||||||
@@ -182,7 +181,7 @@ community to understand your suggestion and find related suggestions.
|
|||||||
#### How Do I Submit a Good Enhancement Suggestion?
|
#### How Do I Submit a Good Enhancement Suggestion?
|
||||||
|
|
||||||
Enhancement suggestions are tracked as
|
Enhancement suggestions are tracked as
|
||||||
[GitHub issues](https://github.com/Start9Labs/embassy-os/issues).
|
[GitHub issues](https://github.com/Start9Labs/start-os/issues).
|
||||||
|
|
||||||
- Use a **clear and descriptive title** for the issue to identify the
|
- Use a **clear and descriptive title** for the issue to identify the
|
||||||
suggestion.
|
suggestion.
|
||||||
@@ -197,7 +196,7 @@ Enhancement suggestions are tracked as
|
|||||||
macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast)
|
macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast)
|
||||||
or [this tool](https://github.com/GNOME/byzanz) on Linux.
|
or [this tool](https://github.com/GNOME/byzanz) on Linux.
|
||||||
<!-- this should only be included if the project has a GUI -->
|
<!-- this should only be included if the project has a GUI -->
|
||||||
- **Explain why this enhancement would be useful** to most Embassy OS users. You
|
- **Explain why this enhancement would be useful** to most StartOS users. You
|
||||||
may also want to point out the other projects that solved it better and which
|
may also want to point out the other projects that solved it better and which
|
||||||
could serve as inspiration.
|
could serve as inspiration.
|
||||||
|
|
||||||
@@ -205,24 +204,24 @@ Enhancement suggestions are tracked as
|
|||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
||||||
embassyOS is composed of the following components. Please visit the README for
|
StartOS is composed of the following components. Please visit the README for
|
||||||
each component to understand the dependency requirements and installation
|
each component to understand the dependency requirements and installation
|
||||||
instructions.
|
instructions.
|
||||||
|
|
||||||
- [`backend`](backend/README.md) (Rust) is a command line utility, daemon, and
|
- [`backend`](backend/README.md) (Rust) is a command line utility, daemon, and
|
||||||
software development kit that sets up and manages services and their
|
software development kit that sets up and manages services and their
|
||||||
environments, provides the interface for the ui, manages system state, and
|
environments, provides the interface for the ui, manages system state, and
|
||||||
provides utilities for packaging services for embassyOS.
|
provides utilities for packaging services for StartOS.
|
||||||
- [`build`](build/README.md) contains scripts and necessary for deploying
|
- [`build`](build/README.md) contains scripts and necessary for deploying
|
||||||
embassyOS to a debian/raspbian system.
|
StartOS to a debian/raspbian system.
|
||||||
- [`frontend`](frontend/README.md) (Typescript Ionic Angular) is the code that
|
- [`frontend`](frontend/README.md) (Typescript Ionic Angular) is the code that
|
||||||
is deployed to the browser to provide the user interface for embassyOS.
|
is deployed to the browser to provide the user interface for StartOS.
|
||||||
- `projects/ui` - Code for the user interface that is displayed when embassyOS
|
- `projects/ui` - Code for the user interface that is displayed when StartOS
|
||||||
is running normally.
|
is running normally.
|
||||||
- `projects/setup-wizard`(frontend/README.md) - Code for the user interface
|
- `projects/setup-wizard`(frontend/README.md) - Code for the user interface
|
||||||
that is displayed during the setup and recovery process for embassyOS.
|
that is displayed during the setup and recovery process for StartOS.
|
||||||
- `projects/diagnostic-ui` - Code for the user interface that is displayed
|
- `projects/diagnostic-ui` - Code for the user interface that is displayed
|
||||||
when something has gone wrong with starting up embassyOS, which provides
|
when something has gone wrong with starting up StartOS, which provides
|
||||||
helpful debugging tools.
|
helpful debugging tools.
|
||||||
- `libs` (Rust) is a set of standalone crates that were separated out of
|
- `libs` (Rust) is a set of standalone crates that were separated out of
|
||||||
`backend` for the purpose of portability
|
`backend` for the purpose of portability
|
||||||
@@ -232,18 +231,18 @@ instructions.
|
|||||||
[client](https://github.com/Start9Labs/patch-db/tree/master/client) with its
|
[client](https://github.com/Start9Labs/patch-db/tree/master/client) with its
|
||||||
own dependency and installation requirements.
|
own dependency and installation requirements.
|
||||||
- `system-images` - (Docker, Rust) A suite of utility Docker images that are
|
- `system-images` - (Docker, Rust) A suite of utility Docker images that are
|
||||||
preloaded with embassyOS to assist with functions relating to services (eg.
|
preloaded with StartOS to assist with functions relating to services (eg.
|
||||||
configuration, backups, health checks).
|
configuration, backups, health checks).
|
||||||
|
|
||||||
### Your First Code Contribution
|
### Your First Code Contribution
|
||||||
|
|
||||||
#### Setting Up Your Development Environment
|
#### Setting Up Your Development Environment
|
||||||
|
|
||||||
First, clone the embassyOS repository and from the project root, pull in the
|
First, clone the StartOS repository and from the project root, pull in the
|
||||||
submodules for dependent libraries.
|
submodules for dependent libraries.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/Start9Labs/embassy-os.git
|
git clone https://github.com/Start9Labs/start-os.git
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -254,7 +253,7 @@ to, follow the installation requirements listed in that component's README
|
|||||||
#### Building The Raspberry Pi Image
|
#### Building The Raspberry Pi Image
|
||||||
|
|
||||||
This step is for setting up an environment in which to test your code changes if
|
This step is for setting up an environment in which to test your code changes if
|
||||||
you do not yet have a embassyOS.
|
you do not yet have a StartOS.
|
||||||
|
|
||||||
- Requirements
|
- Requirements
|
||||||
- `ext4fs` (available if running on the Linux kernel)
|
- `ext4fs` (available if running on the Linux kernel)
|
||||||
@@ -262,7 +261,7 @@ you do not yet have a embassyOS.
|
|||||||
- GNU Make
|
- GNU Make
|
||||||
- Building
|
- Building
|
||||||
- see setup instructions [here](build/README.md)
|
- see setup instructions [here](build/README.md)
|
||||||
- run `make embassyos-raspi.img ARCH=aarch64` from the project root
|
- run `make startos-raspi.img ARCH=aarch64` from the project root
|
||||||
|
|
||||||
### Improving The Documentation
|
### Improving The Documentation
|
||||||
|
|
||||||
@@ -286,7 +285,7 @@ seamless and intuitive experience.
|
|||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
Each component of embassyOS contains its own style guide. Code must be formatted
|
Each component of StartOS contains its own style guide. Code must be formatted
|
||||||
with the formatter designated for each component. These are outlined within each
|
with the formatter designated for each component. These are outlined within each
|
||||||
component folder's README.
|
component folder's README.
|
||||||
|
|
||||||
@@ -306,7 +305,7 @@ component. i.e. `backend: update to tokio v0.3`.
|
|||||||
|
|
||||||
The body of a pull request should contain sufficient description of what the
|
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
|
changes do, as well as a justification. You should include references to any
|
||||||
relevant [issues](https://github.com/Start9Labs/embassy-os/issues).
|
relevant [issues](https://github.com/Start9Labs/start-os/issues).
|
||||||
|
|
||||||
### Rebasing Changes
|
### Rebasing Changes
|
||||||
|
|
||||||
|
|||||||
31
Makefile
@@ -1,6 +1,5 @@
|
|||||||
RASPI_TARGETS := eos_raspberrypi-uninit.img eos_raspberrypi-uninit.tar.gz
|
OS_ARCH := $(shell echo "${OS_ARCH}")
|
||||||
OS_ARCH := $(shell if echo $(RASPI_TARGETS) | grep -qw "$(MAKECMDGOALS)"; then echo raspberrypi; else uname -m; fi)
|
ARCH := $(shell if [ "$(OS_ARCH)" = "raspberrypi" ]; then echo aarch64; else echo $(OS_ARCH) | sed 's/-nonfree$$//g'; fi)
|
||||||
ARCH := $(shell if [ "$(OS_ARCH)" = "raspberrypi" ]; then echo aarch64; else echo $(OS_ARCH); fi)
|
|
||||||
ENVIRONMENT_FILE = $(shell ./check-environment.sh)
|
ENVIRONMENT_FILE = $(shell ./check-environment.sh)
|
||||||
GIT_HASH_FILE = $(shell ./check-git-hash.sh)
|
GIT_HASH_FILE = $(shell ./check-git-hash.sh)
|
||||||
VERSION_FILE = $(shell ./check-version.sh)
|
VERSION_FILE = $(shell ./check-version.sh)
|
||||||
@@ -19,7 +18,7 @@ FRONTEND_DIAGNOSTIC_UI_SRC := $(shell find frontend/projects/diagnostic-ui)
|
|||||||
FRONTEND_INSTALL_WIZARD_SRC := $(shell find frontend/projects/install-wizard)
|
FRONTEND_INSTALL_WIZARD_SRC := $(shell find frontend/projects/install-wizard)
|
||||||
PATCH_DB_CLIENT_SRC := $(shell find patch-db/client -not -path patch-db/client/dist)
|
PATCH_DB_CLIENT_SRC := $(shell find patch-db/client -not -path patch-db/client/dist)
|
||||||
GZIP_BIN := $(shell which pigz || which gzip)
|
GZIP_BIN := $(shell which pigz || which gzip)
|
||||||
ALL_TARGETS := $(EMBASSY_BINS) system-images/compat/docker-images/$(ARCH).tar system-images/utils/docker-images/$(ARCH).tar system-images/binfmt/docker-images/$(ARCH).tar $(EMBASSY_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE)
|
ALL_TARGETS := $(EMBASSY_BINS) system-images/compat/docker-images/$(ARCH).tar system-images/utils/docker-images/$(ARCH).tar system-images/binfmt/docker-images/$(ARCH).tar $(EMBASSY_SRC) $(shell if [ "$(OS_ARCH)" = "raspberrypi" ]; then echo cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep; fi) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE)
|
||||||
|
|
||||||
ifeq ($(REMOTE),)
|
ifeq ($(REMOTE),)
|
||||||
mkdir = mkdir -p $1
|
mkdir = mkdir -p $1
|
||||||
@@ -35,7 +34,7 @@ endif
|
|||||||
|
|
||||||
.DELETE_ON_ERROR:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
.PHONY: all gzip install clean format sdk snapshots frontends ui backend reflash eos_raspberrypi.img sudo
|
.PHONY: all gzip install clean format sdk snapshots frontends ui backend reflash startos_raspberrypi.img sudo
|
||||||
|
|
||||||
all: $(ALL_TARGETS)
|
all: $(ALL_TARGETS)
|
||||||
|
|
||||||
@@ -43,12 +42,6 @@ sudo:
|
|||||||
sudo true
|
sudo true
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f 2022-01-28-raspios-bullseye-arm64-lite.zip
|
|
||||||
rm -f raspios.img
|
|
||||||
rm -f eos_raspberrypi-uninit.img
|
|
||||||
rm -f eos_raspberrypi-uninit.tar.gz
|
|
||||||
rm -f ubuntu.img
|
|
||||||
rm -f product_key.txt
|
|
||||||
rm -f system-images/**/*.tar
|
rm -f system-images/**/*.tar
|
||||||
rm -rf system-images/compat/target
|
rm -rf system-images/compat/target
|
||||||
rm -rf backend/target
|
rm -rf backend/target
|
||||||
@@ -72,17 +65,8 @@ format:
|
|||||||
sdk:
|
sdk:
|
||||||
cd backend/ && ./install-sdk.sh
|
cd backend/ && ./install-sdk.sh
|
||||||
|
|
||||||
eos_raspberrypi-uninit.img: $(ALL_TARGETS) raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep | sudo
|
startos_raspberrypi.img: $(BUILD_SRC) startos.raspberrypi.squashfs $(VERSION_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep | sudo
|
||||||
! test -f eos_raspberrypi-uninit.img || rm eos_raspberrypi-uninit.img
|
./build/raspberrypi/make-image.sh
|
||||||
./build/raspberry-pi/make-image.sh
|
|
||||||
|
|
||||||
lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $(BUILD_SRC) eos.raspberrypi.squashfs
|
|
||||||
! test -f lite-upgrade.img || rm lite-upgrade.img
|
|
||||||
./build/raspberry-pi/make-upgrade-image.sh
|
|
||||||
|
|
||||||
eos_raspberrypi.img: raspios.img $(BUILD_SRC) eos.raspberrypi.squashfs $(VERSION_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) | sudo
|
|
||||||
! test -f eos_raspberrypi.img || rm eos_raspberrypi.img
|
|
||||||
./build/raspberry-pi/make-initialized-image.sh
|
|
||||||
|
|
||||||
# For creating os images. DO NOT USE
|
# For creating os images. DO NOT USE
|
||||||
install: $(ALL_TARGETS)
|
install: $(ALL_TARGETS)
|
||||||
@@ -91,6 +75,7 @@ install: $(ALL_TARGETS)
|
|||||||
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/embassyd,$(DESTDIR)/usr/bin/embassyd)
|
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/embassyd,$(DESTDIR)/usr/bin/embassyd)
|
||||||
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/embassy-cli,$(DESTDIR)/usr/bin/embassy-cli)
|
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/embassy-cli,$(DESTDIR)/usr/bin/embassy-cli)
|
||||||
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/avahi-alias,$(DESTDIR)/usr/bin/avahi-alias)
|
$(call cp,backend/target/$(ARCH)-unknown-linux-gnu/release/avahi-alias,$(DESTDIR)/usr/bin/avahi-alias)
|
||||||
|
if [ "$(OS_ARCH)" = "raspberrypi" ]; then $(call cp,cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep,$(DESTDIR)/usr/bin/pi-beep); fi
|
||||||
|
|
||||||
$(call mkdir,$(DESTDIR)/usr/lib)
|
$(call mkdir,$(DESTDIR)/usr/lib)
|
||||||
$(call rm,$(DESTDIR)/usr/lib/embassy)
|
$(call rm,$(DESTDIR)/usr/lib/embassy)
|
||||||
@@ -183,7 +168,7 @@ frontend/config.json: $(GIT_HASH_FILE) frontend/config-sample.json
|
|||||||
npm --prefix frontend run-script build-config
|
npm --prefix frontend run-script build-config
|
||||||
|
|
||||||
frontend/patchdb-ui-seed.json: frontend/package.json
|
frontend/patchdb-ui-seed.json: frontend/package.json
|
||||||
jq '."ack-welcome" = "$(shell yq '.version' frontend/package.json)"' frontend/patchdb-ui-seed.json > ui-seed.tmp
|
jq '."ack-welcome" = $(shell yq '.version' frontend/package.json)' frontend/patchdb-ui-seed.json > ui-seed.tmp
|
||||||
mv ui-seed.tmp frontend/patchdb-ui-seed.json
|
mv ui-seed.tmp frontend/patchdb-ui-seed.json
|
||||||
|
|
||||||
patch-db/client/node_modules: patch-db/client/package.json
|
patch-db/client/node_modules: patch-db/client/package.json
|
||||||
|
|||||||
38
README.md
@@ -1,6 +1,6 @@
|
|||||||
# embassyOS
|
# StartOS
|
||||||
[](https://github.com/Start9Labs/embassy-os/releases)
|
[](https://github.com/Start9Labs/start-os/releases)
|
||||||
[](https://github.com/Start9Labs/embassy-os/actions/workflows/product.yaml)
|
[](https://github.com/Start9Labs/start-os/actions/workflows/startos-iso.yaml)
|
||||||
[](https://matrix.to/#/#community:matrix.start9labs.com)
|
[](https://matrix.to/#/#community:matrix.start9labs.com)
|
||||||
[](https://t.me/start9_labs)
|
[](https://t.me/start9_labs)
|
||||||
[](https://docs.start9.com)
|
[](https://docs.start9.com)
|
||||||
@@ -12,16 +12,16 @@
|
|||||||
|
|
||||||
### _Welcome to the era of Sovereign Computing_ ###
|
### _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.
|
StartOS is a browser-based, graphical operating system for a personal server. StartOS 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
|
## Running StartOS
|
||||||
There are multiple ways to get your hands on embassyOS.
|
There are multiple ways to get your hands on StartOS.
|
||||||
|
|
||||||
### :moneybag: Buy an Embassy
|
### :moneybag: Buy a Start9 server
|
||||||
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.
|
This is the most convenient option. Simply [buy a server](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
|
### :construction_worker: Build your own server
|
||||||
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:
|
This option is easier than you might imagine, and there are 4 reasons why you might prefer it:
|
||||||
1. You already have your own hardware.
|
1. You already have your own hardware.
|
||||||
1. You want to save on shipping costs.
|
1. You want to save on shipping costs.
|
||||||
1. You prefer not to divulge your physical address.
|
1. You prefer not to divulge your physical address.
|
||||||
@@ -29,23 +29,23 @@ While not as convenient as buying an Embassy, this option is easier than you mig
|
|||||||
|
|
||||||
To pursue this option, follow one of our [DIY guides](https://start9.com/latest/diy).
|
To pursue this option, follow one of our [DIY guides](https://start9.com/latest/diy).
|
||||||
|
|
||||||
### :hammer_and_wrench: Build embassyOS from Source
|
### :hammer_and_wrench: Build StartOS from Source
|
||||||
|
|
||||||
embassyOS can be built from source, for personal use, for free.
|
StartOS 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).
|
A detailed guide for doing so can be found [here](https://github.com/Start9Labs/start-os/blob/master/build/README.md).
|
||||||
|
|
||||||
## :heart: Contributing
|
## :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://docs.start9.com/latest/contribute/) or [here](https://github.com/Start9Labs/embassy-os/blob/master/CONTRIBUTING.md).
|
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://docs.start9.com/latest/contribute/) or [here](https://github.com/Start9Labs/start-os/blob/master/CONTRIBUTING.md).
|
||||||
|
|
||||||
## UI Screenshots
|
## UI Screenshots
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/embassyOS.png" alt="embassyOS" width="85%">
|
<img src="assets/StartOS.png" alt="StartOS" width="85%">
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/eOS-preferences.png" alt="Embassy Preferences" width="49%">
|
<img src="assets/preferences.png" alt="StartOS Preferences" width="49%">
|
||||||
<img src="assets/eOS-ghost.png" alt="Embassy Ghost Service" width="49%">
|
<img src="assets/ghost.png" alt="StartOS Ghost Service" width="49%">
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/eOS-synapse-health-check.png" alt="Embassy Synapse Health Checks" width="49%">
|
<img src="assets/synapse-health-check.png" alt="StartOS Synapse Health Checks" width="49%">
|
||||||
<img src="assets/eOS-sideload.png" alt="Embassy Sideload Service" width="49%">
|
<img src="assets/sideload.png" alt="StartOS Sideload Service" width="49%">
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 281 KiB After Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 266 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
2
backend/Cargo.lock
generated
@@ -1354,7 +1354,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embassy-os"
|
name = "embassy-os"
|
||||||
version = "0.3.4-rev.1"
|
version = "0.3.4-rev.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"async-compression",
|
"async-compression",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["Aiden McClelland <me@drbonez.dev>"]
|
authors = ["Aiden McClelland <me@drbonez.dev>"]
|
||||||
description = "The core of the Start9 Embassy Operating System"
|
description = "The core of StartOS"
|
||||||
documentation = "https://docs.rs/embassy-os"
|
documentation = "https://docs.rs/embassy-os"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
keywords = [
|
keywords = [
|
||||||
@@ -13,8 +13,8 @@ keywords = [
|
|||||||
]
|
]
|
||||||
name = "embassy-os"
|
name = "embassy-os"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/Start9Labs/embassy-os"
|
repository = "https://github.com/Start9Labs/start-os"
|
||||||
version = "0.3.4-rev.1"
|
version = "0.3.4-rev.2"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "embassy"
|
name = "embassy"
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
# embassyOS Backend
|
# StartOS Backend
|
||||||
|
|
||||||
- Requirements:
|
- Requirements:
|
||||||
- [Install Rust](https://rustup.rs)
|
- [Install Rust](https://rustup.rs)
|
||||||
- Recommended: [rust-analyzer](https://rust-analyzer.github.io/)
|
- Recommended: [rust-analyzer](https://rust-analyzer.github.io/)
|
||||||
- [Docker](https://docs.docker.com/get-docker/)
|
- [Docker](https://docs.docker.com/get-docker/)
|
||||||
- [Rust ARM64 Build Container](https://github.com/Start9Labs/rust-arm-builder)
|
- [Rust ARM64 Build Container](https://github.com/Start9Labs/rust-arm-builder)
|
||||||
- Scripts (run withing the `./backend` directory)
|
- Scripts (run within the `./backend` directory)
|
||||||
- `build-prod.sh` - compiles a release build of the artifacts for running on
|
- `build-prod.sh` - compiles a release build of the artifacts for running on
|
||||||
ARM64
|
ARM64
|
||||||
- A Linux computer or VM
|
- A Linux computer or VM
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
The embassyOS backend is broken up into 4 different binaries:
|
The StartOS backend is broken up into 4 different binaries:
|
||||||
|
|
||||||
- embassyd: This is the main workhorse of embassyOS - any new functionality you
|
- embassyd: This is the main workhorse of StartOS - any new functionality you
|
||||||
want will likely go here
|
want will likely go here
|
||||||
- embassy-init: This is the component responsible for allowing you to set up
|
- embassy-init: This is the component responsible for allowing you to set up
|
||||||
your device, and handles system initialization on startup
|
your device, and handles system initialization on startup
|
||||||
- embassy-cli: This is a CLI tool that will allow you to issue commands to
|
- embassy-cli: This is a CLI tool that will allow you to issue commands to
|
||||||
embassyd and control it similarly to the UI
|
embassyd and control it similarly to the UI
|
||||||
- embassy-sdk: This is a CLI tool that aids in building and packaging services
|
- embassy-sdk: This is a CLI tool that aids in building and packaging services
|
||||||
you wish to deploy to the Embassy
|
you wish to deploy to StartOS
|
||||||
|
|
||||||
Finally there is a library `embassy` that supports all four of these tools.
|
Finally there is a library `embassy` that supports all four of these tools.
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ See [here](/backend/Cargo.toml) for details.
|
|||||||
## Building
|
## Building
|
||||||
|
|
||||||
You can build the entire operating system image using `make` from the root of
|
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
|
the StartOS project. This will subsequently invoke the build scripts above to
|
||||||
actually create the requisite binaries and put them onto the final operating
|
actually create the requisite binaries and put them onto the final operating
|
||||||
system image.
|
system image.
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
set -e
|
set -e
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
|
|
||||||
|
if [ -z "$OS_ARCH" ]; then
|
||||||
|
>&2 echo '$OS_ARCH is required'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$ARCH" ]; then
|
if [ -z "$ARCH" ]; then
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
fi
|
fi
|
||||||
@@ -17,8 +22,8 @@ if tty -s; then
|
|||||||
USE_TTY="-it"
|
USE_TTY="-it"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-gnu-builder'='docker run $USE_TTY --rm -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src -P start9/rust-arm-cross:aarch64'
|
alias 'rust-gnu-builder'='docker run $USE_TTY --rm -e "OS_ARCH=$OS_ARCH" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src -P start9/rust-arm-cross:aarch64'
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "OS_ARCH=$OS_ARCH" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$(pwd)":/home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
FLAGS=""
|
FLAGS=""
|
||||||
|
|||||||
@@ -13,13 +13,50 @@ use embassy::shutdown::Shutdown;
|
|||||||
use embassy::sound::CHIME;
|
use embassy::sound::CHIME;
|
||||||
use embassy::util::logger::EmbassyLogger;
|
use embassy::util::logger::EmbassyLogger;
|
||||||
use embassy::util::Invoke;
|
use embassy::util::Invoke;
|
||||||
use embassy::{Error, ErrorKind, ResultExt, IS_RASPBERRY_PI};
|
use embassy::{Error, ErrorKind, ResultExt, OS_ARCH};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<(), Error> {
|
async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<(), Error> {
|
||||||
if tokio::fs::metadata("/cdrom").await.is_ok() {
|
Command::new("ln")
|
||||||
|
.arg("-sf")
|
||||||
|
.arg("/usr/lib/embassy/scripts/fake-apt")
|
||||||
|
.arg("/usr/local/bin/apt")
|
||||||
|
.invoke(crate::ErrorKind::OpenSsh)
|
||||||
|
.await?;
|
||||||
|
Command::new("ln")
|
||||||
|
.arg("-sf")
|
||||||
|
.arg("/usr/lib/embassy/scripts/fake-apt")
|
||||||
|
.arg("/usr/local/bin/apt-get")
|
||||||
|
.invoke(crate::ErrorKind::OpenSsh)
|
||||||
|
.await?;
|
||||||
|
Command::new("ln")
|
||||||
|
.arg("-sf")
|
||||||
|
.arg("/usr/lib/embassy/scripts/fake-apt")
|
||||||
|
.arg("/usr/local/bin/aptitude")
|
||||||
|
.invoke(crate::ErrorKind::OpenSsh)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Command::new("make-ssl-cert")
|
||||||
|
.arg("generate-default-snakeoil")
|
||||||
|
.arg("--force-overwrite")
|
||||||
|
.invoke(crate::ErrorKind::OpenSsl)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if tokio::fs::metadata("/run/live/medium").await.is_ok() {
|
||||||
|
Command::new("sed")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("s/PasswordAuthentication no/PasswordAuthentication yes/g")
|
||||||
|
.arg("/etc/ssh/sshd_config")
|
||||||
|
.invoke(crate::ErrorKind::Filesystem)
|
||||||
|
.await?;
|
||||||
|
Command::new("systemctl")
|
||||||
|
.arg("reload")
|
||||||
|
.arg("ssh")
|
||||||
|
.invoke(crate::ErrorKind::OpenSsh)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let ctx = InstallContext::init(cfg_path).await?;
|
let ctx = InstallContext::init(cfg_path).await?;
|
||||||
|
|
||||||
let server = WebServer::install(([0, 0, 0, 0], 80).into(), ctx.clone()).await?;
|
let server = WebServer::install(([0, 0, 0, 0], 80).into(), ctx.clone()).await?;
|
||||||
@@ -119,7 +156,7 @@ async fn run_script_if_exists<P: AsRef<Path>>(path: P) {
|
|||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||||
if *IS_RASPBERRY_PI && tokio::fs::metadata(STANDBY_MODE_PATH).await.is_ok() {
|
if OS_ARCH == "raspberrypi" && tokio::fs::metadata(STANDBY_MODE_PATH).await.is_ok() {
|
||||||
tokio::fs::remove_file(STANDBY_MODE_PATH).await?;
|
tokio::fs::remove_file(STANDBY_MODE_PATH).await?;
|
||||||
Command::new("sync").invoke(ErrorKind::Filesystem).await?;
|
Command::new("sync").invoke(ErrorKind::Filesystem).await?;
|
||||||
embassy::sound::SHUTDOWN.play().await?;
|
embassy::sound::SHUTDOWN.play().await?;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
embassy::hostname::sync_hostname(&*rpc_ctx.account.read().await).await?;
|
embassy::hostname::sync_hostname(&rpc_ctx.account.read().await.hostname).await?;
|
||||||
let server = WebServer::main(([0, 0, 0, 0], 80).into(), rpc_ctx.clone()).await?;
|
let server = WebServer::main(([0, 0, 0, 0], 80).into(), rpc_ctx.clone()).await?;
|
||||||
|
|
||||||
let mut shutdown_recv = rpc_ctx.shutdown.subscribe();
|
let mut shutdown_recv = rpc_ctx.shutdown.subscribe();
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ pub async fn import<P: AsRef<Path>>(
|
|||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("Embassy disk not found."),
|
eyre!("StartOS disk not found."),
|
||||||
crate::ErrorKind::DiskNotAvailable,
|
crate::ErrorKind::DiskNotAvailable,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ pub async fn import<P: AsRef<Path>>(
|
|||||||
.any(|id| id == guid)
|
.any(|id| id == guid)
|
||||||
{
|
{
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("An Embassy disk was found, but it is not the correct disk for this device."),
|
eyre!("A StartOS disk was found, but it is not the correct disk for this device."),
|
||||||
crate::ErrorKind::IncorrectDisk,
|
crate::ErrorKind::IncorrectDisk,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub const REPAIR_DISK_PATH: &str = "/media/embassy/config/repair-disk";
|
|||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct OsPartitionInfo {
|
pub struct OsPartitionInfo {
|
||||||
pub efi: Option<PathBuf>,
|
pub efi: Option<PathBuf>,
|
||||||
|
pub bios: Option<PathBuf>,
|
||||||
pub boot: PathBuf,
|
pub boot: PathBuf,
|
||||||
pub root: PathBuf,
|
pub root: PathBuf,
|
||||||
}
|
}
|
||||||
@@ -31,6 +32,11 @@ impl OsPartitionInfo {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p == logicalname.as_ref())
|
.map(|p| p == logicalname.as_ref())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
|| self
|
||||||
|
.bios
|
||||||
|
.as_ref()
|
||||||
|
.map(|p| p == logicalname.as_ref())
|
||||||
|
.unwrap_or(false)
|
||||||
|| &*self.boot == logicalname.as_ref()
|
|| &*self.boot == logicalname.as_ref()
|
||||||
|| &*self.root == logicalname.as_ref()
|
|| &*self.root == logicalname.as_ref()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ pub async fn set_hostname(hostname: &Hostname) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn sync_hostname(account: &AccountInfo) -> Result<(), Error> {
|
pub async fn sync_hostname(hostname: &Hostname) -> Result<(), Error> {
|
||||||
set_hostname(&account.hostname).await?;
|
set_hostname(hostname).await?;
|
||||||
Command::new("systemctl")
|
Command::new("systemctl")
|
||||||
.arg("restart")
|
.arg("restart")
|
||||||
.arg("avahi-daemon")
|
.arg("avahi-daemon")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::fs::Permissions;
|
use std::fs::Permissions;
|
||||||
|
use std::net::SocketAddr;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
@@ -39,6 +40,10 @@ pub async fn check_time_is_synchronized() -> Result<bool, Error> {
|
|||||||
== "NTPSynchronized=yes")
|
== "NTPSynchronized=yes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn check_tor_is_ready(tor_control: SocketAddr) -> bool {
|
||||||
|
tokio::net::TcpStream::connect(tor_control).await.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub struct InitReceipts {
|
pub struct InitReceipts {
|
||||||
pub server_version: LockReceipt<crate::util::Version, ()>,
|
pub server_version: LockReceipt<crate::util::Version, ()>,
|
||||||
pub version_range: LockReceipt<emver::VersionRange, ()>,
|
pub version_range: LockReceipt<emver::VersionRange, ()>,
|
||||||
@@ -258,7 +263,7 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
|
|||||||
|
|
||||||
// write to ca cert store
|
// write to ca cert store
|
||||||
tokio::fs::write(
|
tokio::fs::write(
|
||||||
"/usr/local/share/ca-certificates/embassy-root-ca.crt",
|
"/usr/local/share/ca-certificates/startos-root-ca.crt",
|
||||||
account.root_ca_cert.to_pem()?,
|
account.root_ca_cert.to_pem()?,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -404,6 +409,20 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
|
|||||||
.invoke(crate::ErrorKind::Tor)
|
.invoke(crate::ErrorKind::Tor)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let mut warn_tor_not_ready = true;
|
||||||
|
for _ in 0..60 {
|
||||||
|
if check_tor_is_ready(cfg.tor_control.unwrap_or(([127, 0, 0, 1], 9051).into())).await {
|
||||||
|
warn_tor_not_ready = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
if warn_tor_not_ready {
|
||||||
|
tracing::warn!("Timed out waiting for tor to start");
|
||||||
|
} else {
|
||||||
|
tracing::info!("Tor is started");
|
||||||
|
}
|
||||||
|
|
||||||
receipts
|
receipts
|
||||||
.ip_info
|
.ip_info
|
||||||
.set(&mut handle, crate::net::dhcp::init_ips().await?)
|
.set(&mut handle, crate::net::dhcp::init_ips().await?)
|
||||||
|
|||||||
@@ -1449,6 +1449,7 @@ pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
|||||||
"Error loading docker images from s9pk: {e}"
|
"Error loading docker images from s9pk: {e}"
|
||||||
);
|
);
|
||||||
tracing::debug!("{e:?}");
|
tracing::debug!("{e:?}");
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ pub const DEFAULT_MARKETPLACE: &str = "https://registry.start9.com";
|
|||||||
pub const BUFFER_SIZE: usize = 1024;
|
pub const BUFFER_SIZE: usize = 1024;
|
||||||
pub const HOST_IP: [u8; 4] = [172, 18, 0, 1];
|
pub const HOST_IP: [u8; 4] = [172, 18, 0, 1];
|
||||||
pub const TARGET: &str = current_platform::CURRENT_PLATFORM;
|
pub const TARGET: &str = current_platform::CURRENT_PLATFORM;
|
||||||
|
pub const OS_ARCH: &str = env!("OS_ARCH");
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref ARCH: &'static str = {
|
pub static ref ARCH: &'static str = {
|
||||||
let (arch, _) = TARGET.split_once("-").unwrap();
|
let (arch, _) = TARGET.split_once("-").unwrap();
|
||||||
arch
|
arch
|
||||||
};
|
};
|
||||||
pub static ref IS_RASPBERRY_PI: bool = {
|
|
||||||
*ARCH == "aarch64"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod account;
|
pub mod account;
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ prompt = no
|
|||||||
[req_distinguished_name]
|
[req_distinguished_name]
|
||||||
CN = {hostname}.local
|
CN = {hostname}.local
|
||||||
O = Start9 Labs
|
O = Start9 Labs
|
||||||
OU = Embassy
|
OU = StartOS
|
||||||
@@ -11,6 +11,7 @@ use models::PackageId;
|
|||||||
use tokio::net::{TcpListener, UdpSocket};
|
use tokio::net::{TcpListener, UdpSocket};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
use tracing::instrument;
|
||||||
use trust_dns_server::authority::MessageResponseBuilder;
|
use trust_dns_server::authority::MessageResponseBuilder;
|
||||||
use trust_dns_server::client::op::{Header, ResponseCode};
|
use trust_dns_server::client::op::{Header, ResponseCode};
|
||||||
use trust_dns_server::client::rr::{Name, Record, RecordType};
|
use trust_dns_server::client::rr::{Name, Record, RecordType};
|
||||||
@@ -147,6 +148,7 @@ impl RequestHandler for Resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DnsController {
|
impl DnsController {
|
||||||
|
#[instrument(skip_all)]
|
||||||
pub async fn init(bind: &[SocketAddr]) -> Result<Self, Error> {
|
pub async fn init(bind: &[SocketAddr]) -> Result<Self, Error> {
|
||||||
let services = Arc::new(RwLock::new(BTreeMap::new()));
|
let services = Arc::new(RwLock::new(BTreeMap::new()));
|
||||||
|
|
||||||
@@ -161,10 +163,16 @@ impl DnsController {
|
|||||||
);
|
);
|
||||||
server.register_socket(UdpSocket::bind(bind).await.with_kind(ErrorKind::Network)?);
|
server.register_socket(UdpSocket::bind(bind).await.with_kind(ErrorKind::Network)?);
|
||||||
|
|
||||||
Command::new("systemd-resolve")
|
Command::new("resolvectl")
|
||||||
.arg("--set-dns=127.0.0.1")
|
.arg("dns")
|
||||||
.arg("--interface=br-start9")
|
.arg("br-start9")
|
||||||
.arg("--set-domain=embassy")
|
.arg("127.0.0.1")
|
||||||
|
.invoke(ErrorKind::Network)
|
||||||
|
.await?;
|
||||||
|
Command::new("resolvectl")
|
||||||
|
.arg("domain")
|
||||||
|
.arg("br-start9")
|
||||||
|
.arg("embassy")
|
||||||
.invoke(ErrorKind::Network)
|
.invoke(ErrorKind::Network)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use std::sync::{Arc, Weak};
|
|||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use tokio::process::{Child, Command};
|
use tokio::process::{Child, Command};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::util::Invoke;
|
use crate::util::Invoke;
|
||||||
use crate::{Error, ResultExt};
|
use crate::{Error, ResultExt};
|
||||||
@@ -51,6 +52,7 @@ pub struct MdnsControllerInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MdnsControllerInner {
|
impl MdnsControllerInner {
|
||||||
|
#[instrument(skip_all)]
|
||||||
async fn init() -> Result<Self, Error> {
|
async fn init() -> Result<Self, Error> {
|
||||||
let mut res = MdnsControllerInner {
|
let mut res = MdnsControllerInner {
|
||||||
alias_cmd: None,
|
alias_cmd: None,
|
||||||
@@ -59,6 +61,7 @@ impl MdnsControllerInner {
|
|||||||
res.sync().await?;
|
res.sync().await?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
#[instrument(skip_all)]
|
||||||
async fn sync(&mut self) -> Result<(), Error> {
|
async fn sync(&mut self) -> Result<(), Error> {
|
||||||
if let Some(mut cmd) = self.alias_cmd.take() {
|
if let Some(mut cmd) = self.alias_cmd.take() {
|
||||||
cmd.kill().await.with_kind(crate::ErrorKind::Network)?;
|
cmd.kill().await.with_kind(crate::ErrorKind::Network)?;
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ pub fn make_root_cert(root_key: &PKey<Private>, hostname: &Hostname) -> Result<X
|
|||||||
let mut subject_name_builder = X509NameBuilder::new()?;
|
let mut subject_name_builder = X509NameBuilder::new()?;
|
||||||
subject_name_builder.append_entry_by_text("CN", &format!("{} Local Root CA", &*hostname.0))?;
|
subject_name_builder.append_entry_by_text("CN", &format!("{} Local Root CA", &*hostname.0))?;
|
||||||
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
||||||
subject_name_builder.append_entry_by_text("OU", "Embassy")?;
|
subject_name_builder.append_entry_by_text("OU", "StartOS")?;
|
||||||
let subject_name = subject_name_builder.build();
|
let subject_name = subject_name_builder.build();
|
||||||
builder.set_subject_name(&subject_name)?;
|
builder.set_subject_name(&subject_name)?;
|
||||||
|
|
||||||
@@ -225,9 +225,9 @@ pub fn make_int_cert(
|
|||||||
builder.set_serial_number(&*rand_serial()?)?;
|
builder.set_serial_number(&*rand_serial()?)?;
|
||||||
|
|
||||||
let mut subject_name_builder = X509NameBuilder::new()?;
|
let mut subject_name_builder = X509NameBuilder::new()?;
|
||||||
subject_name_builder.append_entry_by_text("CN", "Embassy Local Intermediate CA")?;
|
subject_name_builder.append_entry_by_text("CN", "StartOS Local Intermediate CA")?;
|
||||||
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
||||||
subject_name_builder.append_entry_by_text("OU", "Embassy")?;
|
subject_name_builder.append_entry_by_text("OU", "StartOS")?;
|
||||||
let subject_name = subject_name_builder.build();
|
let subject_name = subject_name_builder.build();
|
||||||
builder.set_subject_name(&subject_name)?;
|
builder.set_subject_name(&subject_name)?;
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ pub fn make_leaf_cert(
|
|||||||
.unwrap_or("localhost"),
|
.unwrap_or("localhost"),
|
||||||
)?;
|
)?;
|
||||||
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
subject_name_builder.append_entry_by_text("O", "Start9")?;
|
||||||
subject_name_builder.append_entry_by_text("OU", "Embassy")?;
|
subject_name_builder.append_entry_by_text("OU", "StartOS")?;
|
||||||
let subject_name = subject_name_builder.build();
|
let subject_name = subject_name_builder.build();
|
||||||
builder.set_subject_name(&subject_name)?;
|
builder.set_subject_name(&subject_name)?;
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ pub async fn delete(#[context] ctx: RpcContext, #[arg] ssid: String) -> Result<(
|
|||||||
let is_current_removed_and_no_hardwire =
|
let is_current_removed_and_no_hardwire =
|
||||||
is_current_being_removed && !interface_connected(&ctx.ethernet_interface).await?;
|
is_current_being_removed && !interface_connected(&ctx.ethernet_interface).await?;
|
||||||
if is_current_removed_and_no_hardwire {
|
if is_current_removed_and_no_hardwire {
|
||||||
return Err(Error::new(color_eyre::eyre::eyre!("Forbidden: Deleting this Network would make your Embassy Unreachable. Either connect to ethernet or connect to a different WiFi network to remedy this."), ErrorKind::Wifi));
|
return Err(Error::new(color_eyre::eyre::eyre!("Forbidden: Deleting this network would make your server unreachable. Either connect to ethernet or connect to a different WiFi network to remedy this."), ErrorKind::Wifi));
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant
|
wpa_supplicant
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use gpt::disk::LogicalBlockSize;
|
use gpt::disk::LogicalBlockSize;
|
||||||
use gpt::GptConfig;
|
use gpt::GptConfig;
|
||||||
@@ -8,9 +10,10 @@ use crate::os_install::partition_for;
|
|||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
|
pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
|
||||||
{
|
let efi = {
|
||||||
let disk = disk.clone();
|
let disk = disk.clone();
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
|
let use_efi = Path::new("/sys/firmware/efi").exists();
|
||||||
let mut device = Box::new(
|
let mut device = Box::new(
|
||||||
std::fs::File::options()
|
std::fs::File::options()
|
||||||
.read(true)
|
.read(true)
|
||||||
@@ -44,17 +47,15 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionIn
|
|||||||
.map(|(idx, x)| (idx + 1, x))
|
.map(|(idx, x)| (idx + 1, x))
|
||||||
{
|
{
|
||||||
if let Some(entry) = gpt.partitions().get(&(idx as u32)) {
|
if let Some(entry) = gpt.partitions().get(&(idx as u32)) {
|
||||||
if entry.first_lba >= 33556480 {
|
|
||||||
if idx < 3 {
|
|
||||||
guid_part = Some(entry.clone())
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if part_info.guid.is_some() {
|
if part_info.guid.is_some() {
|
||||||
return Err(Error::new(
|
if entry.first_lba < if use_efi { 33759266 } else { 33570850 } {
|
||||||
eyre!("Not enough space before embassy data"),
|
return Err(Error::new(
|
||||||
crate::ErrorKind::InvalidRequest,
|
eyre!("Not enough space before embassy data"),
|
||||||
));
|
crate::ErrorKind::InvalidRequest,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
guid_part = Some(entry.clone());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,19 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionIn
|
|||||||
|
|
||||||
gpt.update_partitions(Default::default())?;
|
gpt.update_partitions(Default::default())?;
|
||||||
|
|
||||||
gpt.add_partition("efi", 100 * 1024 * 1024, gpt::partition_types::EFI, 0, None)?;
|
let efi = if use_efi {
|
||||||
|
gpt.add_partition("efi", 100 * 1024 * 1024, gpt::partition_types::EFI, 0, None)?;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
gpt.add_partition(
|
||||||
|
"bios-grub",
|
||||||
|
8 * 1024 * 1024,
|
||||||
|
gpt::partition_types::BIOS,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
false
|
||||||
|
};
|
||||||
gpt.add_partition(
|
gpt.add_partition(
|
||||||
"boot",
|
"boot",
|
||||||
1024 * 1024 * 1024,
|
1024 * 1024 * 1024,
|
||||||
@@ -108,14 +121,15 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionIn
|
|||||||
|
|
||||||
gpt.write()?;
|
gpt.write()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(efi)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap()?;
|
.unwrap()?
|
||||||
}
|
};
|
||||||
|
|
||||||
Ok(OsPartitionInfo {
|
Ok(OsPartitionInfo {
|
||||||
efi: Some(partition_for(&disk.logicalname, 1)),
|
efi: efi.then(|| partition_for(&disk.logicalname, 1)),
|
||||||
|
bios: (!efi).then(|| partition_for(&disk.logicalname, 1)),
|
||||||
boot: partition_for(&disk.logicalname, 2),
|
boot: partition_for(&disk.logicalname, 2),
|
||||||
root: partition_for(&disk.logicalname, 3),
|
root: partition_for(&disk.logicalname, 3),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,18 +27,14 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionIn
|
|||||||
.map(|(idx, x)| (idx + 1, x))
|
.map(|(idx, x)| (idx + 1, x))
|
||||||
{
|
{
|
||||||
if let Some(entry) = mbr.get_mut(idx) {
|
if let Some(entry) = mbr.get_mut(idx) {
|
||||||
if entry.starting_lba >= 33556480 {
|
|
||||||
if idx < 3 {
|
|
||||||
guid_part =
|
|
||||||
Some(std::mem::replace(entry, MBRPartitionEntry::empty()))
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if part_info.guid.is_some() {
|
if part_info.guid.is_some() {
|
||||||
return Err(Error::new(
|
if entry.starting_lba < 33556480 {
|
||||||
eyre!("Not enough space before embassy data"),
|
return Err(Error::new(
|
||||||
crate::ErrorKind::InvalidRequest,
|
eyre!("Not enough space before embassy data"),
|
||||||
));
|
crate::ErrorKind::InvalidRequest,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
guid_part = Some(std::mem::replace(entry, MBRPartitionEntry::empty()));
|
||||||
}
|
}
|
||||||
*entry = MBRPartitionEntry::empty();
|
*entry = MBRPartitionEntry::empty();
|
||||||
}
|
}
|
||||||
@@ -85,6 +81,7 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionIn
|
|||||||
|
|
||||||
Ok(OsPartitionInfo {
|
Ok(OsPartitionInfo {
|
||||||
efi: None,
|
efi: None,
|
||||||
|
bios: None,
|
||||||
boot: partition_for(&disk.logicalname, 1),
|
boot: partition_for(&disk.logicalname, 1),
|
||||||
root: partition_for(&disk.logicalname, 2),
|
root: partition_for(&disk.logicalname, 2),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ pub async fn list() -> Result<Vec<DiskInfo>, Error> {
|
|||||||
Command::new("grub-probe-default")
|
Command::new("grub-probe-default")
|
||||||
.arg("-t")
|
.arg("-t")
|
||||||
.arg("disk")
|
.arg("disk")
|
||||||
.arg("/cdrom")
|
.arg("/run/live/medium")
|
||||||
.invoke(crate::ErrorKind::Grub)
|
.invoke(crate::ErrorKind::Grub)
|
||||||
.await?,
|
.await?,
|
||||||
)?
|
)?
|
||||||
@@ -93,13 +93,7 @@ pub fn partition_for(disk: impl AsRef<Path>, idx: usize) -> PathBuf {
|
|||||||
|
|
||||||
async fn partition(disk: &mut DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
|
async fn partition(disk: &mut DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
|
||||||
let partition_type = match (overwrite, disk.partition_table) {
|
let partition_type = match (overwrite, disk.partition_table) {
|
||||||
(true, _) | (_, None) => {
|
(true, _) | (_, None) => PartitionTable::Gpt,
|
||||||
if tokio::fs::metadata("/sys/firmware/efi").await.is_ok() {
|
|
||||||
PartitionTable::Gpt
|
|
||||||
} else {
|
|
||||||
PartitionTable::Mbr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(_, Some(t)) => t,
|
(_, Some(t)) => t,
|
||||||
};
|
};
|
||||||
disk.partition_table = Some(partition_type);
|
disk.partition_table = Some(partition_type);
|
||||||
@@ -188,7 +182,7 @@ pub async fn execute(
|
|||||||
.arg("-f")
|
.arg("-f")
|
||||||
.arg("-d")
|
.arg("-d")
|
||||||
.arg(¤t)
|
.arg(¤t)
|
||||||
.arg("/cdrom/casper/filesystem.squashfs")
|
.arg("/run/live/medium/live/filesystem.squashfs")
|
||||||
.invoke(crate::ErrorKind::Filesystem)
|
.invoke(crate::ErrorKind::Filesystem)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -233,7 +227,7 @@ pub async fn execute(
|
|||||||
let dev = MountGuard::mount(&Bind::new("/dev"), current.join("dev"), ReadWrite).await?;
|
let dev = MountGuard::mount(&Bind::new("/dev"), current.join("dev"), ReadWrite).await?;
|
||||||
let proc = MountGuard::mount(&Bind::new("/proc"), current.join("proc"), ReadWrite).await?;
|
let proc = MountGuard::mount(&Bind::new("/proc"), current.join("proc"), ReadWrite).await?;
|
||||||
let sys = MountGuard::mount(&Bind::new("/sys"), current.join("sys"), ReadWrite).await?;
|
let sys = MountGuard::mount(&Bind::new("/sys"), current.join("sys"), ReadWrite).await?;
|
||||||
let efivarfs = if let Some(efi) = &part_info.efi {
|
let efivarfs = if tokio::fs::metadata("/sys/firmware/efi").await.is_ok() {
|
||||||
Some(
|
Some(
|
||||||
MountGuard::mount(
|
MountGuard::mount(
|
||||||
&EfiVarFs,
|
&EfiVarFs,
|
||||||
@@ -246,14 +240,9 @@ pub async fn execute(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Command::new("chroot")
|
|
||||||
.arg(¤t)
|
|
||||||
.arg("update-grub")
|
|
||||||
.invoke(crate::ErrorKind::Grub)
|
|
||||||
.await?;
|
|
||||||
let mut install = Command::new("chroot");
|
let mut install = Command::new("chroot");
|
||||||
install.arg(¤t).arg("grub-install");
|
install.arg(¤t).arg("grub-install");
|
||||||
if part_info.efi.is_none() {
|
if tokio::fs::metadata("/sys/firmware/efi").await.is_err() {
|
||||||
install.arg("--target=i386-pc");
|
install.arg("--target=i386-pc");
|
||||||
} else {
|
} else {
|
||||||
match *ARCH {
|
match *ARCH {
|
||||||
@@ -267,6 +256,12 @@ pub async fn execute(
|
|||||||
.invoke(crate::ErrorKind::Grub)
|
.invoke(crate::ErrorKind::Grub)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
Command::new("chroot")
|
||||||
|
.arg(¤t)
|
||||||
|
.arg("update-grub2")
|
||||||
|
.invoke(crate::ErrorKind::Grub)
|
||||||
|
.await?;
|
||||||
|
|
||||||
dev.unmount(false).await?;
|
dev.unmount(false).await?;
|
||||||
if let Some(efivarfs) = efivarfs {
|
if let Some(efivarfs) = efivarfs {
|
||||||
efivarfs.unmount(false).await?;
|
efivarfs.unmount(false).await?;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ pub async fn attach(
|
|||||||
crate::disk::main::export(&*guid, &ctx.datadir).await?;
|
crate::disk::main::export(&*guid, &ctx.datadir).await?;
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!(
|
eyre!(
|
||||||
"Errors were corrected with your disk, but the Embassy must be restarted in order to proceed"
|
"Errors were corrected with your disk, but the server must be restarted in order to proceed"
|
||||||
),
|
),
|
||||||
ErrorKind::DiskManagement,
|
ErrorKind::DiskManagement,
|
||||||
));
|
));
|
||||||
@@ -294,7 +294,7 @@ pub async fn execute(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Error Setting Up Embassy: {}", e);
|
tracing::error!("Error Setting Up Server: {}", e);
|
||||||
tracing::debug!("{:?}", e);
|
tracing::debug!("{:?}", e);
|
||||||
*ctx.setup_status.write().await = Some(Err(e.into()));
|
*ctx.setup_status.write().await = Some(Err(e.into()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::disk::main::export;
|
|||||||
use crate::init::{STANDBY_MODE_PATH, SYSTEM_REBUILD_PATH};
|
use crate::init::{STANDBY_MODE_PATH, SYSTEM_REBUILD_PATH};
|
||||||
use crate::sound::SHUTDOWN;
|
use crate::sound::SHUTDOWN;
|
||||||
use crate::util::{display_none, Invoke};
|
use crate::util::{display_none, Invoke};
|
||||||
use crate::{Error, ErrorKind, IS_RASPBERRY_PI};
|
use crate::{Error, ErrorKind, OS_ARCH};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Shutdown {
|
pub struct Shutdown {
|
||||||
@@ -58,7 +58,7 @@ impl Shutdown {
|
|||||||
tracing::debug!("{:?}", e);
|
tracing::debug!("{:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !*IS_RASPBERRY_PI || self.restart {
|
if OS_ARCH != "raspberrypi" || self.restart {
|
||||||
if let Err(e) = SHUTDOWN.play().await {
|
if let Err(e) = SHUTDOWN.play().await {
|
||||||
tracing::error!("Error Playing Shutdown Song: {}", e);
|
tracing::error!("Error Playing Shutdown Song: {}", e);
|
||||||
tracing::debug!("{:?}", e);
|
tracing::debug!("{:?}", e);
|
||||||
@@ -66,7 +66,7 @@ impl Shutdown {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
drop(rt);
|
drop(rt);
|
||||||
if *IS_RASPBERRY_PI {
|
if OS_ARCH == "raspberrypi" {
|
||||||
if !self.restart {
|
if !self.restart {
|
||||||
std::fs::write(STANDBY_MODE_PATH, "").unwrap();
|
std::fs::write(STANDBY_MODE_PATH, "").unwrap();
|
||||||
Command::new("sync").spawn().unwrap().wait().unwrap();
|
Command::new("sync").spawn().unwrap().wait().unwrap();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use futures::FutureExt;
|
|||||||
use rpc_toolkit::command;
|
use rpc_toolkit::command;
|
||||||
use rpc_toolkit::yajrc::RpcError;
|
use rpc_toolkit::yajrc::RpcError;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use tokio::process::Command;
|
||||||
use tokio::sync::broadcast::Receiver;
|
use tokio::sync::broadcast::Receiver;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
@@ -17,8 +18,8 @@ use crate::logs::{
|
|||||||
LogResponse, LogSource,
|
LogResponse, LogSource,
|
||||||
};
|
};
|
||||||
use crate::shutdown::Shutdown;
|
use crate::shutdown::Shutdown;
|
||||||
use crate::util::display_none;
|
|
||||||
use crate::util::serde::{display_serializable, IoFormat};
|
use crate::util::serde::{display_serializable, IoFormat};
|
||||||
|
use crate::util::{display_none, Invoke};
|
||||||
use crate::{Error, ErrorKind, ResultExt};
|
use crate::{Error, ErrorKind, ResultExt};
|
||||||
|
|
||||||
pub const SYSTEMD_UNIT: &'static str = "embassyd";
|
pub const SYSTEMD_UNIT: &'static str = "embassyd";
|
||||||
@@ -512,13 +513,30 @@ async fn launch_disk_task(
|
|||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn get_temp() -> Result<Celsius, Error> {
|
async fn get_temp() -> Result<Celsius, Error> {
|
||||||
let temp_file = "/sys/class/thermal/thermal_zone0/temp";
|
let temp = serde_json::from_slice::<serde_json::Value>(
|
||||||
let milli = tokio::fs::read_to_string(temp_file)
|
&Command::new("sensors")
|
||||||
.await
|
.arg("-j")
|
||||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, temp_file))?
|
.invoke(ErrorKind::Filesystem)
|
||||||
.trim()
|
.await?,
|
||||||
.parse::<f64>()?;
|
)
|
||||||
Ok(Celsius(milli / 1000.0))
|
.with_kind(ErrorKind::Deserialization)?
|
||||||
|
.as_object()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.flat_map(|(_, v)| v.as_object())
|
||||||
|
.flatten()
|
||||||
|
.flat_map(|(_, v)| v.as_object())
|
||||||
|
.flatten()
|
||||||
|
.filter_map(|(k, v)| {
|
||||||
|
if k.ends_with("_input") {
|
||||||
|
v.as_f64()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.reduce(f64::max)
|
||||||
|
.ok_or_else(|| Error::new(eyre!("No temperatures available"), ErrorKind::Filesystem))?;
|
||||||
|
Ok(Celsius(temp))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::sound::{
|
|||||||
use crate::update::latest_information::LatestInformation;
|
use crate::update::latest_information::LatestInformation;
|
||||||
use crate::util::Invoke;
|
use crate::util::Invoke;
|
||||||
use crate::version::{Current, VersionT};
|
use crate::version::{Current, VersionT};
|
||||||
use crate::{Error, ErrorKind, ResultExt, IS_RASPBERRY_PI};
|
use crate::{Error, ErrorKind, ResultExt, OS_ARCH};
|
||||||
|
|
||||||
mod latest_information;
|
mod latest_information;
|
||||||
|
|
||||||
@@ -81,16 +81,11 @@ async fn maybe_do_update(
|
|||||||
marketplace_url: Url,
|
marketplace_url: Url,
|
||||||
) -> Result<Option<Arc<Revision>>, Error> {
|
) -> Result<Option<Arc<Revision>>, Error> {
|
||||||
let mut db = ctx.db.handle();
|
let mut db = ctx.db.handle();
|
||||||
let arch = if *IS_RASPBERRY_PI {
|
|
||||||
"raspberrypi"
|
|
||||||
} else {
|
|
||||||
*crate::ARCH
|
|
||||||
};
|
|
||||||
let latest_version: Version = reqwest::get(format!(
|
let latest_version: Version = reqwest::get(format!(
|
||||||
"{}/eos/v0/latest?eos-version={}&arch={}",
|
"{}/eos/v0/latest?eos-version={}&arch={}",
|
||||||
marketplace_url,
|
marketplace_url,
|
||||||
Current::new().semver(),
|
Current::new().semver(),
|
||||||
arch,
|
OS_ARCH,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.with_kind(ErrorKind::Network)?
|
.with_kind(ErrorKind::Network)?
|
||||||
@@ -241,12 +236,7 @@ impl EosUrl {
|
|||||||
.host_str()
|
.host_str()
|
||||||
.ok_or_else(|| Error::new(eyre!("Could not get host of base"), ErrorKind::ParseUrl))?;
|
.ok_or_else(|| Error::new(eyre!("Could not get host of base"), ErrorKind::ParseUrl))?;
|
||||||
let version: &Version = &self.version;
|
let version: &Version = &self.version;
|
||||||
let arch = if *IS_RASPBERRY_PI {
|
Ok(format!("{host}::{version}/{OS_ARCH}/")
|
||||||
"raspberrypi"
|
|
||||||
} else {
|
|
||||||
*crate::ARCH
|
|
||||||
};
|
|
||||||
Ok(format!("{host}::{version}/{arch}/")
|
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| Error::new(eyre!("Could not parse path"), ErrorKind::ParseUrl))?)
|
.map_err(|_| Error::new(eyre!("Could not parse path"), ErrorKind::ParseUrl))?)
|
||||||
}
|
}
|
||||||
@@ -312,7 +302,7 @@ async fn sync_boot() -> Result<(), Error> {
|
|||||||
.await?
|
.await?
|
||||||
.wait()
|
.wait()
|
||||||
.await?;
|
.await?;
|
||||||
if !*IS_RASPBERRY_PI {
|
if OS_ARCH != "raspberrypi" {
|
||||||
let dev_mnt =
|
let dev_mnt =
|
||||||
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
||||||
let sys_mnt =
|
let sys_mnt =
|
||||||
@@ -323,7 +313,7 @@ async fn sync_boot() -> Result<(), Error> {
|
|||||||
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
||||||
Command::new("chroot")
|
Command::new("chroot")
|
||||||
.arg("/media/embassy/next")
|
.arg("/media/embassy/next")
|
||||||
.arg("update-grub")
|
.arg("update-grub2")
|
||||||
.invoke(ErrorKind::MigrationFailed)
|
.invoke(ErrorKind::MigrationFailed)
|
||||||
.await?;
|
.await?;
|
||||||
boot_mnt.unmount(false).await?;
|
boot_mnt.unmount(false).await?;
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ mod v0_3_2_1;
|
|||||||
mod v0_3_3;
|
mod v0_3_3;
|
||||||
mod v0_3_4;
|
mod v0_3_4;
|
||||||
mod v0_3_4_1;
|
mod v0_3_4_1;
|
||||||
|
mod v0_3_4_2;
|
||||||
|
|
||||||
pub type Current = v0_3_4_1::Version;
|
pub type Current = v0_3_4_2::Version;
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
@@ -39,6 +40,7 @@ enum Version {
|
|||||||
V0_3_3(Wrapper<v0_3_3::Version>),
|
V0_3_3(Wrapper<v0_3_3::Version>),
|
||||||
V0_3_4(Wrapper<v0_3_4::Version>),
|
V0_3_4(Wrapper<v0_3_4::Version>),
|
||||||
V0_3_4_1(Wrapper<v0_3_4_1::Version>),
|
V0_3_4_1(Wrapper<v0_3_4_1::Version>),
|
||||||
|
V0_3_4_2(Wrapper<v0_3_4_2::Version>),
|
||||||
Other(emver::Version),
|
Other(emver::Version),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ impl Version {
|
|||||||
Version::V0_3_3(Wrapper(x)) => x.semver(),
|
Version::V0_3_3(Wrapper(x)) => x.semver(),
|
||||||
Version::V0_3_4(Wrapper(x)) => x.semver(),
|
Version::V0_3_4(Wrapper(x)) => x.semver(),
|
||||||
Version::V0_3_4_1(Wrapper(x)) => x.semver(),
|
Version::V0_3_4_1(Wrapper(x)) => x.semver(),
|
||||||
|
Version::V0_3_4_2(Wrapper(x)) => x.semver(),
|
||||||
Version::Other(x) => x.clone(),
|
Version::Other(x) => x.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,6 +254,10 @@ pub async fn init<Db: DbHandle>(
|
|||||||
v.0.migrate_to(&Current::new(), db, secrets, receipts)
|
v.0.migrate_to(&Current::new(), db, secrets, receipts)
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
Version::V0_3_4_2(v) => {
|
||||||
|
v.0.migrate_to(&Current::new(), db, secrets, receipts)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
Version::Other(_) => {
|
Version::Other(_) => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("Cannot downgrade"),
|
eyre!("Cannot downgrade"),
|
||||||
@@ -295,6 +302,7 @@ mod tests {
|
|||||||
Just(Version::V0_3_3(Wrapper(v0_3_3::Version::new()))),
|
Just(Version::V0_3_3(Wrapper(v0_3_3::Version::new()))),
|
||||||
Just(Version::V0_3_4(Wrapper(v0_3_4::Version::new()))),
|
Just(Version::V0_3_4(Wrapper(v0_3_4::Version::new()))),
|
||||||
Just(Version::V0_3_4_1(Wrapper(v0_3_4_1::Version::new()))),
|
Just(Version::V0_3_4_1(Wrapper(v0_3_4_1::Version::new()))),
|
||||||
|
Just(Version::V0_3_4_2(Wrapper(v0_3_4_2::Version::new()))),
|
||||||
em_version().prop_map(Version::Other),
|
em_version().prop_map(Version::Other),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ impl VersionT for Version {
|
|||||||
.unwrap_or_else(generate_hostname);
|
.unwrap_or_else(generate_hostname);
|
||||||
account.server_id = server_info.id;
|
account.server_id = server_info.id;
|
||||||
account.save(secrets).await?;
|
account.save(secrets).await?;
|
||||||
sync_hostname(&account).await?;
|
sync_hostname(&account.hostname).await?;
|
||||||
|
|
||||||
let parsed_url = Some(COMMUNITY_URL.parse().unwrap());
|
let parsed_url = Some(COMMUNITY_URL.parse().unwrap());
|
||||||
let mut ui = crate::db::DatabaseModel::new().ui().get_mut(db).await?;
|
let mut ui = crate::db::DatabaseModel::new().ui().get_mut(db).await?;
|
||||||
|
|||||||
30
backend/src/version/v0_3_4_2.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use emver::VersionRange;
|
||||||
|
|
||||||
|
use super::v0_3_0::V0_3_0_COMPAT;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const V0_3_4_2: emver::Version = emver::Version::new(0, 3, 4, 2);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Version;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl VersionT for Version {
|
||||||
|
type Previous = v0_3_4_1::Version;
|
||||||
|
fn new() -> Self {
|
||||||
|
Version
|
||||||
|
}
|
||||||
|
fn semver(&self) -> emver::Version {
|
||||||
|
V0_3_4_2
|
||||||
|
}
|
||||||
|
fn compat(&self) -> &'static VersionRange {
|
||||||
|
&*V0_3_0_COMPAT
|
||||||
|
}
|
||||||
|
async fn up<Db: DbHandle>(&self, _db: &mut Db, _secrets: &PgPool) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn down<Db: DbHandle>(&self, _db: &mut Db, _secrets: &PgPool) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Building Embassy OS
|
# Building StartOS
|
||||||
|
|
||||||
⚠️ The commands given assume a Debian or Ubuntu-based environment. _Building in
|
⚠️ The commands given assume a Debian or Ubuntu-based environment. _Building in
|
||||||
a VM is NOT yet supported_ ⚠️
|
a VM is NOT yet supported_ ⚠️
|
||||||
@@ -42,15 +42,15 @@ a VM is NOT yet supported_ ⚠️
|
|||||||
|
|
||||||
2. Clone the latest repo with required submodules
|
2. Clone the latest repo with required submodules
|
||||||
> :information_source: You chan check latest available version
|
> :information_source: You chan check latest available version
|
||||||
> [here](https://github.com/Start9Labs/embassy-os/releases)
|
> [here](https://github.com/Start9Labs/start-os/releases)
|
||||||
```
|
```
|
||||||
git clone --recursive https://github.com/Start9Labs/embassy-os.git --branch latest
|
git clone --recursive https://github.com/Start9Labs/start-os.git --branch latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build Raspberry Pi Image
|
## Build Raspberry Pi Image
|
||||||
|
|
||||||
```
|
```
|
||||||
cd embassy-os
|
cd start-os
|
||||||
make embassyos-raspi.img ARCH=aarch64
|
make embassyos-raspi.img ARCH=aarch64
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ We recommend [Balena Etcher](https://www.balena.io/etcher/)
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Visit http://embassy.local from any web browser - We recommend
|
Visit http://start.local from any web browser - We recommend
|
||||||
[Firefox](https://www.mozilla.org/firefox/browsers)
|
[Firefox](https://www.mozilla.org/firefox/browsers)
|
||||||
|
|
||||||
Enter your product key. This is generated during the build process and can be
|
Enter your product key. This is generated during the build process and can be
|
||||||
@@ -70,11 +70,11 @@ found in `product_key.txt`, located in the root directory.
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
1. I just flashed my SD card, fired up my Embassy, bootup sounds and all, but my
|
1. I just flashed my SD card, fired up StartOS, bootup sounds and all, but my
|
||||||
browser is saying "Unable to connect" with embassy.local.
|
browser is saying "Unable to connect" with start.local.
|
||||||
|
|
||||||
- Try doing a hard refresh on your browser, or opening the url in a
|
- Try doing a hard refresh on your browser, or opening the url in a
|
||||||
private/incognito window. If you've ran an instance of Embassy before,
|
private/incognito window. If you've ran an instance of StartOS before,
|
||||||
sometimes you can have a stale cache that will block you from navigating to
|
sometimes you can have a stale cache that will block you from navigating to
|
||||||
the page.
|
the page.
|
||||||
|
|
||||||
@@ -91,14 +91,14 @@ found in `product_key.txt`, located in the root directory.
|
|||||||
- Find the IP of your device
|
- Find the IP of your device
|
||||||
- Run `nc <ip> 8080` and it will print the logs
|
- Run `nc <ip> 8080` and it will print the logs
|
||||||
|
|
||||||
4. I need to ssh into my Embassy to fix something, but I cannot get to the
|
4. I need to ssh into my server to fix something, but I cannot get to the
|
||||||
console to add ssh keys normally.
|
console to add ssh keys normally.
|
||||||
|
|
||||||
- During the Build step, instead of running just
|
- During the Build step, instead of running just
|
||||||
`make embassyos-raspi.img ARCH=aarch64` run
|
`make embassyos-raspi.img ARCH=aarch64` run
|
||||||
`ENVIRONMENT=dev make embassyos-raspi.img ARCH=aarch64`. Flash like normal,
|
`ENVIRONMENT=dev make embassyos-raspi.img ARCH=aarch64`. Flash like normal,
|
||||||
and insert into your Embassy. Boot up your Embassy, and on another computer on
|
and insert into your server. Boot up StartOS, then on another computer on
|
||||||
the same network, ssh into the Embassy with the username `start9` password
|
the same network, ssh into the the server with the username `start9` password
|
||||||
`embassy`.
|
`embassy`.
|
||||||
|
|
||||||
4. I need to reset my password, how can I do that?
|
4. I need to reset my password, how can I do that?
|
||||||
|
|||||||
@@ -1,35 +1,46 @@
|
|||||||
tor
|
|
||||||
avahi-daemon
|
avahi-daemon
|
||||||
avahi-utils
|
avahi-utils
|
||||||
iotop
|
bash-completion
|
||||||
|
beep
|
||||||
bmon
|
bmon
|
||||||
lvm2
|
ca-certificates
|
||||||
htop
|
|
||||||
cryptsetup
|
|
||||||
exfat-utils
|
|
||||||
sqlite3
|
|
||||||
wireless-tools
|
|
||||||
net-tools
|
|
||||||
ecryptfs-utils
|
|
||||||
cifs-utils
|
cifs-utils
|
||||||
samba-common-bin
|
containerd.io
|
||||||
network-manager
|
curl
|
||||||
vim
|
crda
|
||||||
jq
|
cryptsetup
|
||||||
ncdu
|
|
||||||
postgresql
|
|
||||||
pgloader
|
|
||||||
openssh-server
|
|
||||||
docker-ce
|
docker-ce
|
||||||
docker-ce-cli
|
docker-ce-cli
|
||||||
containerd.io
|
|
||||||
docker-compose-plugin
|
docker-compose-plugin
|
||||||
beep
|
dosfstools
|
||||||
|
e2fsprogs
|
||||||
|
ecryptfs-utils
|
||||||
|
exfat-utils
|
||||||
|
htop
|
||||||
httpdirfs
|
httpdirfs
|
||||||
|
iotop
|
||||||
iw
|
iw
|
||||||
squashfs-tools
|
jq
|
||||||
rsync
|
libavahi-client3
|
||||||
systemd-timesyncd
|
lm-sensors
|
||||||
|
lvm2
|
||||||
magic-wormhole
|
magic-wormhole
|
||||||
|
ncdu
|
||||||
|
net-tools
|
||||||
|
network-manager
|
||||||
nyx
|
nyx
|
||||||
bash-completion
|
openssh-server
|
||||||
|
pgloader
|
||||||
|
postgresql
|
||||||
|
psmisc
|
||||||
|
rsync
|
||||||
|
samba-common-bin
|
||||||
|
sqlite3
|
||||||
|
squashfs-tools
|
||||||
|
systemd
|
||||||
|
systemd-resolved
|
||||||
|
systemd-sysv
|
||||||
|
systemd-timesyncd
|
||||||
|
tor
|
||||||
|
vim
|
||||||
|
wireless-tools
|
||||||
|
|||||||
@@ -2,14 +2,20 @@
|
|||||||
printf "\n"
|
printf "\n"
|
||||||
printf "Welcome to\n"
|
printf "Welcome to\n"
|
||||||
cat << "ASCII"
|
cat << "ASCII"
|
||||||
| ,---.,---.
|
╭ ━ ━ ━ ╮ ╭ ╮ ╱ ╱ ╱ ╱ ╱ ╭ ╮ ╭ ━ ━ ━ ┳ ━ ━ ━ ╮
|
||||||
,---.,-.-.|---.,---.,---.,---., .| |`---.
|
┃ ╭ ━ ╮ ┣ ╯ ╰ ╮ ╱ ╱ ╱ ╭ ╯ ╰ ┫ ╭ ━ ╮ ┃ ╭ ━ ╮ ┃
|
||||||
|---'| | || |,---|`---.`---.| || | |
|
┃ ╰ ━ ━ ╋ ╮ ╭ ╋ ━ ━ ┳ ┻ ╮ ╭ ┫ ┃ ╱ ┃ ┃ ╰ ━ ━ ╮
|
||||||
`---'` ' '`---'`---^`---'`---'`---|`---'`---'
|
╰ ━ ━ ╮ ┃ ┃ ┃ ┃ ╭ ╮ ┃ ╭ ┫ ┃ ┃ ┃ ╱ ┃ ┣ ━ ━ ╮ ┃
|
||||||
`---'
|
┃ ╰ ━ ╯ ┃ ┃ ╰ ┫ ╭ ╮ ┃ ┃ ┃ ╰ ┫ ╰ ━ ╯ ┃ ╰ ━ ╯ ┃
|
||||||
|
╰ ━ ━ ━ ╯ ╰ ━ ┻ ╯ ╰ ┻ ╯ ╰ ━ ┻ ━ ━ ━ ┻ ━ ━ ━ ╯
|
||||||
ASCII
|
ASCII
|
||||||
printf " %s (%s %s)\n" "$(uname -o)" "$(uname -r)" "$(uname -m)"
|
printf " %s (%s %s)\n" "$(uname -o)" "$(uname -r)" "$(uname -m)"
|
||||||
printf " $(embassy-cli --version | sed 's/Embassy CLI /embassyOS v/g') - $(embassy-cli git-info)\n"
|
printf " $(embassy-cli --version | sed 's/Embassy CLI /StartOS v/g') - $(embassy-cli git-info)"
|
||||||
|
if [ -n "$(cat /usr/lib/embassy/ENVIRONMENT.txt)" ]; then
|
||||||
|
printf " ~ $(cat /usr/lib/embassy/ENVIRONMENT.txt)\n"
|
||||||
|
else
|
||||||
|
printf "\n"
|
||||||
|
fi
|
||||||
|
|
||||||
printf "\n"
|
printf "\n"
|
||||||
printf " * Documentation: https://start9.com\n"
|
printf " * Documentation: https://start9.com\n"
|
||||||
|
|||||||
@@ -20,16 +20,8 @@ mount --bind /sys /media/embassy/next/sys
|
|||||||
mount --bind /proc /media/embassy/next/proc
|
mount --bind /proc /media/embassy/next/proc
|
||||||
mount --bind /boot /media/embassy/next/boot
|
mount --bind /boot /media/embassy/next/boot
|
||||||
|
|
||||||
rm /media/embassy/next/usr/local/bin/apt
|
|
||||||
rm /media/embassy/next/usr/local/bin/apt-get
|
|
||||||
rm /media/embassy/next/usr/local/bin/aptitude
|
|
||||||
|
|
||||||
chroot /media/embassy/next $@
|
chroot /media/embassy/next $@
|
||||||
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/apt
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/apt-get
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/aptitude
|
|
||||||
|
|
||||||
umount /media/embassy/next/run
|
umount /media/embassy/next/run
|
||||||
umount /media/embassy/next/dev
|
umount /media/embassy/next/dev
|
||||||
umount /media/embassy/next/sys
|
umount /media/embassy/next/sys
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ set -e
|
|||||||
cat > /home/start9/kiosk.sh << 'EOF'
|
cat > /home/start9/kiosk.sh << 'EOF'
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
PROFILE=$(mktemp -d)
|
PROFILE=$(mktemp -d)
|
||||||
if [ -f /usr/local/share/ca-certificates/embassy-root-ca.crt ]; then
|
if [ -f /usr/local/share/ca-certificates/startos-root-ca.crt ]; then
|
||||||
certutil -A -n "Embassy Local Root CA" -t "TCu,Cuw,Tuw" -i /usr/local/share/ca-certificates/embassy-root-ca.crt -d $PROFILE
|
certutil -A -n "StartOS Local Root CA" -t "TCu,Cuw,Tuw" -i /usr/local/share/ca-certificates/startos-root-ca.crt -d $PROFILE
|
||||||
fi
|
fi
|
||||||
cat >> $PROFILE/prefs.js << EOT
|
cat >> $PROFILE/prefs.js << EOT
|
||||||
user_pref("network.proxy.autoconfig_url", "file:///usr/lib/embassy/proxy.pac");
|
user_pref("network.proxy.autoconfig_url", "file:///usr/lib/embassy/proxy.pac");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
>&2 echo 'THIS IS NOT A STANDARD DEBIAN SYSTEM'
|
>&2 echo 'THIS IS NOT A STANDARD DEBIAN SYSTEM'
|
||||||
>&2 echo 'USING apt COULD CAUSE IRREPARABLE DAMAGE TO YOUR EMBASSY'
|
>&2 echo 'USING apt COULD CAUSE IRREPARABLE DAMAGE TO YOUR START9 SERVER'
|
||||||
>&2 echo 'PLEASE TURN BACK NOW!!!'
|
>&2 echo 'PLEASE TURN BACK NOW!!!'
|
||||||
if [ "$1" == "upgrade" ] && [ "$(whoami)" == "root" ]; then
|
if [ "$1" == "upgrade" ] && [ "$(whoami)" == "root" ]; then
|
||||||
>&2 echo 'IF YOU THINK RUNNING "sudo apt upgrade" IS A REASONABLE THING TO DO ON THIS SYSTEM, YOU PROBABLY SHOULDN'"'"'T BE ON THE COMMAND LINE.'
|
>&2 echo 'IF YOU THINK RUNNING "sudo apt upgrade" IS A REASONABLE THING TO DO ON THIS SYSTEM, YOU PROBABLY SHOULDN'"'"'T BE ON THE COMMAND LINE.'
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
for mozilladir in $(find /home -name ".mozilla"); do
|
for mozilladir in $(find /home -name ".mozilla"); do
|
||||||
for certDB in $(find ${mozilladir} -name "cert9.db"); do
|
for certDB in $(find ${mozilladir} -name "cert9.db"); do
|
||||||
certDir=$(dirname ${certDB});
|
certDir=$(dirname ${certDB});
|
||||||
certutil -A -n "Embassy Local Root CA" -t "TCu,Cuw,Tuw" -i /usr/local/share/ca-certificates/embassy-root-ca.crt -d ${certDir}
|
certutil -A -n "StartOS Local Root CA" -t "TCu,Cuw,Tuw" -i /usr/local/share/ca-certificates/startos-root-ca.crt -d ${certDir}
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
function partition_for () {
|
|
||||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
|
||||||
echo "$1p$2"
|
|
||||||
else
|
|
||||||
echo "$1$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
OSDISK=$1
|
|
||||||
if [ -z "$OSDISK" ]; then
|
|
||||||
>&2 echo "usage: $0 <TARGET DISK>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
WIFI_IFACE=
|
|
||||||
for IFACE in $(ls /sys/class/net); do
|
|
||||||
if [ -d /sys/class/net/$IFACE/wireless ]; then
|
|
||||||
WIFI_IFACE=$IFACE
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
ETH_IFACE=
|
|
||||||
for IFACE in $(ls /sys/class/net); do
|
|
||||||
if ! [ -d /sys/class/net/$IFACE/wireless ] && [ -d /sys/class/net/$IFACE/device ]; then
|
|
||||||
ETH_IFACE=$IFACE
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ -z "$ETH_IFACE" ]; then
|
|
||||||
>&2 echo 'Could not detect ethernet interface'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
(
|
|
||||||
echo o # MBR
|
|
||||||
echo n # New Partition
|
|
||||||
echo p # Primary
|
|
||||||
echo 1 # Index #1
|
|
||||||
echo # Default Starting Position
|
|
||||||
echo '+1G' # 1GB
|
|
||||||
echo t # Change Type
|
|
||||||
echo 0b # W95 FAT32
|
|
||||||
echo a # Set Bootable
|
|
||||||
echo n # New Partition
|
|
||||||
echo p # Primary
|
|
||||||
echo 2 # Index #2
|
|
||||||
echo # Default Starting Position
|
|
||||||
echo '+15G' # 15GB
|
|
||||||
echo n # New Partition
|
|
||||||
echo p # Primary
|
|
||||||
echo 3 # Index #3
|
|
||||||
echo # Default Starting Position
|
|
||||||
echo # Use Full Remaining
|
|
||||||
echo t # Change Type
|
|
||||||
echo 3 # (Still Index #3)
|
|
||||||
echo 8e # Linux LVM
|
|
||||||
echo w # Write Changes
|
|
||||||
) | fdisk $OSDISK
|
|
||||||
|
|
||||||
BOOTPART=`partition_for $OSDISK 1`
|
|
||||||
ROOTPART=`partition_for $OSDISK 2`
|
|
||||||
|
|
||||||
mkfs.vfat $BOOTPART
|
|
||||||
fatlabel $BOOTPART boot
|
|
||||||
|
|
||||||
mkfs.ext4 $ROOTPART
|
|
||||||
e2label $ROOTPART rootfs
|
|
||||||
|
|
||||||
mount $ROOTPART /mnt
|
|
||||||
mkdir /mnt/config
|
|
||||||
mkdir /mnt/current
|
|
||||||
mkdir /mnt/next
|
|
||||||
|
|
||||||
mkdir /mnt/current/boot
|
|
||||||
mount $BOOTPART /mnt/current/boot
|
|
||||||
|
|
||||||
unsquashfs -f -d /mnt/current /cdrom/casper/filesystem.squashfs
|
|
||||||
|
|
||||||
cat > /mnt/config/config.yaml << EOF
|
|
||||||
os-partitions:
|
|
||||||
boot: $BOOTPART
|
|
||||||
root: $ROOTPART
|
|
||||||
ethernet-interface: $ETH_IFACE
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if [ -n "$WIFI_IFACE" ]; then
|
|
||||||
echo "wifi-interface: $WIFI_IFACE" >> /mnt/config/config.yaml
|
|
||||||
fi
|
|
||||||
|
|
||||||
# gen fstab
|
|
||||||
cat > /mnt/current/etc/fstab << EOF
|
|
||||||
$BOOTPART /boot vfat defaults 0 2
|
|
||||||
$ROOTPART / ext4 defaults 0 1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# gen machine-id
|
|
||||||
chroot /mnt/current systemd-machine-id-setup
|
|
||||||
|
|
||||||
# gen ssh host keys
|
|
||||||
chroot /mnt/current ssh-keygen -A
|
|
||||||
|
|
||||||
mount --bind /dev /mnt/current/dev
|
|
||||||
mount --bind /sys /mnt/current/sys
|
|
||||||
mount --bind /proc /mnt/current/proc
|
|
||||||
|
|
||||||
chroot /mnt/current update-grub
|
|
||||||
chroot /mnt/current grub-install $OSDISK
|
|
||||||
|
|
||||||
umount /mnt/current/dev
|
|
||||||
umount /mnt/current/sys
|
|
||||||
umount /mnt/current/proc
|
|
||||||
|
|
||||||
umount /mnt/current/boot
|
|
||||||
|
|
||||||
umount /mnt
|
|
||||||
@@ -29,11 +29,15 @@ ln -s /usr/share/zoneinfo/Etc/UTC /etc/localtime
|
|||||||
|
|
||||||
# switch to systemd-resolved & network-manager
|
# switch to systemd-resolved & network-manager
|
||||||
echo "#" > /etc/network/interfaces
|
echo "#" > /etc/network/interfaces
|
||||||
|
if ! [ -f /etc/resolv.conf ]; then
|
||||||
|
rm -f /etc/resolv.conf
|
||||||
|
echo "nameserver 8.8.8.8" > /etc/resolv.conf # Google DNS Fallback
|
||||||
|
fi
|
||||||
if ! [ -f /run/systemd/resolve/stub-resolv.conf ]; then
|
if ! [ -f /run/systemd/resolve/stub-resolv.conf ]; then
|
||||||
mkdir -p /run/systemd/resolve
|
mkdir -p /run/systemd/resolve
|
||||||
cp /etc/resolv.conf /run/systemd/resolve/stub-resolv.conf
|
cp /etc/resolv.conf /run/systemd/resolve/stub-resolv.conf
|
||||||
fi
|
fi
|
||||||
ln -rsf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
|
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
|
||||||
cat << EOF > /etc/NetworkManager/NetworkManager.conf
|
cat << EOF > /etc/NetworkManager/NetworkManager.conf
|
||||||
[main]
|
[main]
|
||||||
plugins=ifupdown,keyfile
|
plugins=ifupdown,keyfile
|
||||||
@@ -44,6 +48,7 @@ managed=true
|
|||||||
EOF
|
EOF
|
||||||
$SYSTEMCTL enable systemd-resolved.service
|
$SYSTEMCTL enable systemd-resolved.service
|
||||||
$SYSTEMCTL enable systemd-networkd-wait-online.service
|
$SYSTEMCTL enable systemd-networkd-wait-online.service
|
||||||
|
$SYSTEMCTL enable ssh.service
|
||||||
$SYSTEMCTL disable wpa_supplicant.service
|
$SYSTEMCTL disable wpa_supplicant.service
|
||||||
|
|
||||||
$SYSTEMCTL disable docker.service
|
$SYSTEMCTL disable docker.service
|
||||||
@@ -63,6 +68,7 @@ if which gsettings > /dev/null; then
|
|||||||
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout '0'
|
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout '0'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
|
||||||
sed -i 's/Restart=on-failure/Restart=always/g' /lib/systemd/system/tor@default.service
|
sed -i 's/Restart=on-failure/Restart=always/g' /lib/systemd/system/tor@default.service
|
||||||
sed -i 's/ExecStart=\/usr\/bin\/dockerd/ExecStart=\/usr\/bin\/dockerd --exec-opt native.cgroupdriver=systemd/g' /lib/systemd/system/docker.service
|
sed -i 's/ExecStart=\/usr\/bin\/dockerd/ExecStart=\/usr\/bin\/dockerd --exec-opt native.cgroupdriver=systemd/g' /lib/systemd/system/docker.service
|
||||||
sed -i '/\(^\|#\)entries-per-entry-group-max=/c\entries-per-entry-group-max=128' /etc/avahi/avahi-daemon.conf
|
sed -i '/\(^\|#\)entries-per-entry-group-max=/c\entries-per-entry-group-max=128' /etc/avahi/avahi-daemon.conf
|
||||||
@@ -112,7 +118,3 @@ rm -f /etc/motd
|
|||||||
ln -sf /usr/lib/embassy/motd /etc/update-motd.d/00-embassy
|
ln -sf /usr/lib/embassy/motd /etc/update-motd.d/00-embassy
|
||||||
chmod -x /etc/update-motd.d/*
|
chmod -x /etc/update-motd.d/*
|
||||||
chmod +x /etc/update-motd.d/00-embassy
|
chmod +x /etc/update-motd.d/00-embassy
|
||||||
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/apt
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/apt-get
|
|
||||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/aptitude
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Boot process for system initialization.
|
|
||||||
After=network-online.target systemd-time-wait-sync.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/local/bin/033-upgrade.sh
|
|
||||||
RemainAfterExit=true
|
|
||||||
StandardOutput=append:/var/log/initialization.log
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
(
|
|
||||||
while true; do
|
|
||||||
beep -r 2 -l 80 -d 20
|
|
||||||
sleep 60
|
|
||||||
done
|
|
||||||
) &
|
|
||||||
|
|
||||||
if grep 'cb15ae4d-03' /boot/cmdline.txt; then
|
|
||||||
echo Transfer files across
|
|
||||||
e2fsck -f -y /dev/mmcblk0p4
|
|
||||||
while ! resize2fs /dev/mmcblk0p4; do
|
|
||||||
e2fsck -f -y /dev/mmcblk0p4
|
|
||||||
done
|
|
||||||
mkdir -p /media/origin
|
|
||||||
mkdir -p /media/dest
|
|
||||||
mount -r /dev/mmcblk0p3 /media/origin
|
|
||||||
mount -w /dev/mmcblk0p4 /media/dest
|
|
||||||
rsync -acvAXUH --info=progress2 --delete --force /media/origin/ /media/dest/
|
|
||||||
umount /media/origin
|
|
||||||
umount /media/dest
|
|
||||||
rm -rf /media/origin
|
|
||||||
rm -rf /media/dest
|
|
||||||
|
|
||||||
echo Setting up boot to use other partition
|
|
||||||
sed -i 's/PARTUUID=cb15ae4d-03/PARTUUID=cb15ae4d-04/g' /boot/cmdline.txt
|
|
||||||
sync
|
|
||||||
reboot
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p /media/root-rw
|
|
||||||
mkfs.ext4 /dev/mmcblk0p3
|
|
||||||
mount /dev/mmcblk0p3 /media/root-rw
|
|
||||||
|
|
||||||
mkdir -p /embassy-os
|
|
||||||
mount /dev/mmcblk0p2 /embassy-os
|
|
||||||
|
|
||||||
mkdir -p /media/root-rw/config
|
|
||||||
mkdir -p /media/root-rw/current
|
|
||||||
mkdir -p /media/root-rw/next
|
|
||||||
rsync -acvAXUH --info=progress2 /embassy-os/ /media/root-rw/config/
|
|
||||||
rsync -acvAXUH --info=progress2 /update/ /media/root-rw/current/
|
|
||||||
rsync -acvAXUH --info=progress2 /media/root-rw/current/boot/ /boot/
|
|
||||||
cp /etc/machine-id /media/root-rw/current/etc/machine-id
|
|
||||||
cp /etc/ssh/ssh_host_rsa_key /media/root-rw/current/etc/ssh/ssh_host_rsa_key
|
|
||||||
cp /etc/ssh/ssh_host_rsa_key.pub /media/root-rw/current/etc/ssh/ssh_host_rsa_key.pub
|
|
||||||
cp /etc/ssh/ssh_host_ecdsa_key /media/root-rw/current/etc/ssh/ssh_host_ecdsa_key
|
|
||||||
cp /etc/ssh/ssh_host_ecdsa_key.pub /media/root-rw/current/etc/ssh/ssh_host_ecdsa_key.pub
|
|
||||||
cp /etc/ssh/ssh_host_ed25519_key /media/root-rw/current/etc/ssh/ssh_host_ed25519_key
|
|
||||||
cp /etc/ssh/ssh_host_ed25519_key.pub /media/root-rw/current/etc/ssh/ssh_host_ed25519_key.pub
|
|
||||||
|
|
||||||
sync
|
|
||||||
|
|
||||||
umount /embassy-os
|
|
||||||
umount /media/root-rw
|
|
||||||
|
|
||||||
fatlabel /dev/mmcblk0p1 boot
|
|
||||||
e2label /dev/mmcblk0p3 rootfs
|
|
||||||
|
|
||||||
(
|
|
||||||
echo d
|
|
||||||
echo 1
|
|
||||||
echo d
|
|
||||||
echo 2
|
|
||||||
echo n
|
|
||||||
echo p
|
|
||||||
echo 1
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo d
|
|
||||||
echo 3
|
|
||||||
echo d
|
|
||||||
echo 4
|
|
||||||
echo n
|
|
||||||
echo p
|
|
||||||
echo 2
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo t
|
|
||||||
echo 1
|
|
||||||
echo c
|
|
||||||
echo w
|
|
||||||
) | fdisk /dev/mmcblk0
|
|
||||||
|
|
||||||
reboot
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
function flatline {
|
|
||||||
echo -n "0" > /sys/class/pwm/pwmchip0/export
|
|
||||||
sleep 0.5
|
|
||||||
echo -n "2272727" > /sys/class/pwm/pwmchip0/pwm0/period
|
|
||||||
echo -n "1136364" > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
|
|
||||||
echo -n "1" > /sys/class/pwm/pwmchip0/pwm0/enable
|
|
||||||
sleep 30
|
|
||||||
echo -n "0" > /sys/class/pwm/pwmchip0/pwm0/enable
|
|
||||||
}
|
|
||||||
|
|
||||||
initialization.sh
|
|
||||||
STATUS=$?
|
|
||||||
if [ $STATUS -ne 0 ]; then
|
|
||||||
flatline
|
|
||||||
exit $STATUS
|
|
||||||
fi
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Boot process for system initialization.
|
|
||||||
After=network-online.target systemd-time-wait-sync.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/local/bin/init-with-sound.sh
|
|
||||||
RemainAfterExit=true
|
|
||||||
StandardOutput=append:/var/log/initialization.log
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# introduce start9 username and embassy as default password
|
|
||||||
if ! awk -F: '{ print $1 }' /etc/passwd | grep start9
|
|
||||||
then
|
|
||||||
usermod -l start9 -d /home/start9 -m pi
|
|
||||||
groupmod --new-name start9 pi
|
|
||||||
echo start9:embassy | chpasswd
|
|
||||||
fi
|
|
||||||
|
|
||||||
START=$(date +%s)
|
|
||||||
while ! ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null; do
|
|
||||||
>&2 echo "Waiting for internet connection..."
|
|
||||||
sleep 1
|
|
||||||
if [ "$[$START + 60]" -lt $(date +%s) ]; then
|
|
||||||
>&2 echo "Timed out waiting for internet connection..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo "Connected to network"
|
|
||||||
|
|
||||||
# Convert all repos to use https:// before apt update
|
|
||||||
sed -i "s/http:/https:/g" /etc/apt/sources.list /etc/apt/sources.list.d/*.list
|
|
||||||
|
|
||||||
. /usr/lib/embassy/scripts/add-apt-sources
|
|
||||||
|
|
||||||
KERN=$(dpkg -s raspberrypi-kernel | grep Version | awk '{print $2}')
|
|
||||||
apt-get update
|
|
||||||
|
|
||||||
# TODO remove in 0.4.0
|
|
||||||
if [ "$KERN" != "1:1.20221104-1" ]; then
|
|
||||||
wget https://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20221104-1_arm64.deb
|
|
||||||
sha256sum raspberrypi-kernel_1.20221104-1_arm64.deb | grep 9de9fe61e17eab351b6d4c8ee42d836c16b066f3593a4a9626283df6df718e42
|
|
||||||
apt-get install -y --allow-change-held-packages --allow-downgrades ./raspberrypi-kernel_1.20221104-1_arm64.deb
|
|
||||||
rm ./raspberrypi-kernel_1.20221104-1_arm64.deb
|
|
||||||
fi
|
|
||||||
apt-mark hold raspberrypi-bootloader
|
|
||||||
apt-mark hold raspberrypi-kernel
|
|
||||||
|
|
||||||
apt-get upgrade -y
|
|
||||||
if [ "$KERN" != "$(dpkg -s raspberrypi-kernel | grep Version | awk '{print $2}')" ]; then
|
|
||||||
echo "Kernel updated, restarting..."
|
|
||||||
sync
|
|
||||||
reboot
|
|
||||||
fi
|
|
||||||
|
|
||||||
apt-get install -y $(cat /usr/lib/embassy/depends)
|
|
||||||
apt-get remove --purge -y $(cat /usr/lib/embassy/conflicts) beep
|
|
||||||
apt-get autoremove -y
|
|
||||||
|
|
||||||
systemctl stop tor
|
|
||||||
|
|
||||||
. /usr/lib/embassy/scripts/postinst
|
|
||||||
|
|
||||||
usermod -aG embassy start9
|
|
||||||
|
|
||||||
systemctl enable embassyd.service embassy-init.service
|
|
||||||
|
|
||||||
# . /usr/lib/embassy/scripts/enable-kiosk
|
|
||||||
|
|
||||||
sed -i 's/^/usb-storage.quirks=152d:0562:u,14cd:121c:u,0781:cfcb:u /g' /boot/cmdline.txt
|
|
||||||
|
|
||||||
# making that *sudo docker stats* command fulfil its purpose by displaying all metrics
|
|
||||||
sed -i 's/rootwait quiet.*/rootwait cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory quiet/g' /boot/cmdline.txt
|
|
||||||
|
|
||||||
systemctl disable nc-broadcast.service
|
|
||||||
systemctl disable initialization.service
|
|
||||||
|
|
||||||
update-initramfs -c -k "$(uname -r)"
|
|
||||||
|
|
||||||
sed -i /boot/config.txt -e "/initramfs.*/d"
|
|
||||||
echo initramfs "initrd.img-$(uname -r)" >> /boot/config.txt
|
|
||||||
|
|
||||||
sed -i /boot/cmdline.txt -e "s/^/boot=embassy /"
|
|
||||||
|
|
||||||
passwd -l start9
|
|
||||||
|
|
||||||
sync
|
|
||||||
|
|
||||||
reboot
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
function partition_for () {
|
|
||||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
|
||||||
echo "$1p$2"
|
|
||||||
else
|
|
||||||
echo "$1$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
TARGET_NAME=eos_raspberrypi-uninit.img
|
|
||||||
TARGET_SIZE=2400000000
|
|
||||||
|
|
||||||
cp raspios.img $TARGET_NAME
|
|
||||||
truncate -s $TARGET_SIZE $TARGET_NAME
|
|
||||||
(
|
|
||||||
echo d
|
|
||||||
echo 2
|
|
||||||
echo n
|
|
||||||
echo p
|
|
||||||
echo 2
|
|
||||||
echo 532480
|
|
||||||
echo
|
|
||||||
echo w
|
|
||||||
) | sudo fdisk $TARGET_NAME
|
|
||||||
export OUTPUT_DEVICE=$(sudo losetup --show -fP $TARGET_NAME)
|
|
||||||
sudo e2fsck -f -y `partition_for ${OUTPUT_DEVICE} 2`
|
|
||||||
sudo resize2fs `partition_for ${OUTPUT_DEVICE} 2`
|
|
||||||
./build/raspberry-pi/write-image.sh
|
|
||||||
sudo e2fsck -f -y `partition_for ${OUTPUT_DEVICE} 2`
|
|
||||||
sudo resize2fs -M `partition_for ${OUTPUT_DEVICE} 2`
|
|
||||||
sudo losetup -d $OUTPUT_DEVICE
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
function partition_for () {
|
|
||||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
|
||||||
echo "$1p$2"
|
|
||||||
else
|
|
||||||
echo "$1$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
VERSION=$(cat VERSION.txt)
|
|
||||||
ENVIRONMENT=$(cat ENVIRONMENT.txt)
|
|
||||||
GIT_HASH=$(cat GIT_HASH.txt | head -c 7)
|
|
||||||
DATE=$(date +%Y%m%d)
|
|
||||||
|
|
||||||
VERSION_FULL="$VERSION-$GIT_HASH"
|
|
||||||
|
|
||||||
if [ -n "$ENVIRONMENT" ]; then
|
|
||||||
VERSION_FULL="$VERSION_FULL~$ENVIRONMENT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
TARGET_NAME=eos-${VERSION_FULL}-${DATE}_raspberrypi.img
|
|
||||||
TARGET_SIZE=$[(31116287+1)*512]
|
|
||||||
|
|
||||||
rm -f $TARGET_NAME
|
|
||||||
truncate -s $TARGET_SIZE $TARGET_NAME
|
|
||||||
(
|
|
||||||
echo o
|
|
||||||
echo x
|
|
||||||
echo i
|
|
||||||
echo "0xcb15ae4d"
|
|
||||||
echo r
|
|
||||||
echo n
|
|
||||||
echo p
|
|
||||||
echo 1
|
|
||||||
echo 2048
|
|
||||||
echo 526335
|
|
||||||
echo 1050623
|
|
||||||
echo t
|
|
||||||
echo c
|
|
||||||
echo n
|
|
||||||
echo p
|
|
||||||
echo 2
|
|
||||||
echo 1050624
|
|
||||||
echo 31116287
|
|
||||||
echo a
|
|
||||||
echo 1
|
|
||||||
echo w
|
|
||||||
) | fdisk $TARGET_NAME
|
|
||||||
OUTPUT_DEVICE=$(sudo losetup --show -fP $TARGET_NAME)
|
|
||||||
sudo mkfs.ext4 `partition_for ${OUTPUT_DEVICE} 2`
|
|
||||||
sudo mkfs.vfat `partition_for ${OUTPUT_DEVICE} 1`
|
|
||||||
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
|
|
||||||
sudo mount `partition_for ${OUTPUT_DEVICE} 2` $TMPDIR
|
|
||||||
sudo mkdir -p $TMPDIR/config
|
|
||||||
sudo mkdir -p $TMPDIR/next
|
|
||||||
sudo mkdir -p $TMPDIR/current/boot
|
|
||||||
sudo mount `partition_for ${OUTPUT_DEVICE} 1` $TMPDIR/current/boot
|
|
||||||
sudo unsquashfs -f -d $TMPDIR/current eos.raspberrypi.squashfs
|
|
||||||
sudo umount $TMPDIR/current/boot
|
|
||||||
sudo umount $TMPDIR
|
|
||||||
sudo losetup -d $OUTPUT_DEVICE
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
function partition_for () {
|
|
||||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
|
||||||
echo "$1p$2"
|
|
||||||
else
|
|
||||||
echo "$1$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
TARGET_NAME=lite-upgrade.img
|
|
||||||
TARGET_SIZE=7000000000
|
|
||||||
|
|
||||||
LOOPDEV=$(sudo losetup --show -fP raspios.img)
|
|
||||||
sudo cat `partition_for ${LOOPDEV} 2` > $TARGET_NAME
|
|
||||||
sudo losetup -d $LOOPDEV
|
|
||||||
truncate -s $TARGET_SIZE $TARGET_NAME
|
|
||||||
sudo e2fsck -f -y $TARGET_NAME
|
|
||||||
sudo resize2fs $TARGET_NAME
|
|
||||||
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
|
|
||||||
sudo mount $TARGET_NAME $TMPDIR/
|
|
||||||
|
|
||||||
sudo mkdir -p $TMPDIR/update
|
|
||||||
sudo unsquashfs -f -d $TMPDIR/update eos.raspberrypi.squashfs
|
|
||||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
|
|
||||||
sudo cp ./build/raspberry-pi/033-upgrade.sh $TMPDIR/usr/local/bin/033-upgrade.sh
|
|
||||||
sudo cp ./build/raspberry-pi/033-upgrade.service $TMPDIR/etc/systemd/system/033-upgrade.service
|
|
||||||
sudo ln -s /etc/systemd/system/033-upgrade.service $TMPDIR/etc/systemd/system/multi-user.target.wants/033-upgrade.service
|
|
||||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
|
|
||||||
sudo cp ./build/raspberry-pi/nc-broadcast.service $TMPDIR/etc/systemd/system/nc-broadcast.service
|
|
||||||
sudo ln -s /etc/systemd/system/nc-broadcast.service $TMPDIR/etc/systemd/system/multi-user.target.wants/nc-broadcast.service
|
|
||||||
|
|
||||||
sudo umount $TMPDIR/
|
|
||||||
|
|
||||||
sudo e2fsck -f -y $TARGET_NAME
|
|
||||||
sudo resize2fs -M $TARGET_NAME
|
|
||||||
BLOCK_INFO=$(sudo dumpe2fs $TARGET_NAME)
|
|
||||||
BLOCK_COUNT=$(echo "$BLOCK_INFO" | grep "Block count:" | sed 's/Block count:\s\+//g')
|
|
||||||
BLOCK_SIZE=$(echo "$BLOCK_INFO" | grep "Block size:" | sed 's/Block size:\s\+//g')
|
|
||||||
FS_SIZE=$[$BLOCK_COUNT*$BLOCK_SIZE]
|
|
||||||
truncate -s $FS_SIZE $TARGET_NAME
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Writes initialization logs to network
|
|
||||||
Requires=initialization.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5s
|
|
||||||
ExecStart=/usr/local/bin/nc-broadcast --input=/var/log/initialization.log --tee 0.0.0.0:8080
|
|
||||||
RemainAfterExit=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
|
|
||||||
ROOT_PARTITION=$(readlink -f /dev/disk/by-label/rootfs)
|
|
||||||
BOOT_PARTITION=$(readlink -f /dev/disk/by-label/boot)
|
|
||||||
|
|
||||||
if [[ "$ROOT_PARTITION" =~ ^/dev/loop ]] || [[ "$BOOT_PARTITION" =~ ^/dev/loop ]]; then
|
|
||||||
>&2 echo 'You are currently ripping from a loop device.'
|
|
||||||
>&2 echo 'This is probably a mistake, and usually means you failed to detach a .img file.'
|
|
||||||
read -p "Continue anyway? [y/N]" -n 1 -r
|
|
||||||
echo
|
|
||||||
if ! [[ "$REPLY" =~ ^[Yy]$ ]]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
sudo mount $ROOT_PARTITION $TMPDIR/
|
|
||||||
sudo mount $BOOT_PARTITION $TMPDIR/current/boot/
|
|
||||||
sudo sed -i 's/PARTUUID=[a-f0-9]\+/PARTUUID=cb15ae4d/g' $TMPDIR/current/etc/fstab
|
|
||||||
sudo sed -i 's/PARTUUID=[a-f0-9]\+/PARTUUID=cb15ae4d/g' $TMPDIR/current/boot/cmdline.txt
|
|
||||||
rm -f eos.raspberrypi.squashfs
|
|
||||||
sudo mksquashfs $TMPDIR/current/ eos.raspberrypi.squashfs
|
|
||||||
|
|
||||||
sudo umount $TMPDIR/current/boot/
|
|
||||||
sudo umount $TMPDIR/
|
|
||||||
|
|
||||||
rm -rf $TMPDIR
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
function partition_for () {
|
|
||||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
|
||||||
echo "$1p$2"
|
|
||||||
else
|
|
||||||
echo "$1$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Mount the boot partition and config
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
sudo mount `partition_for ${OUTPUT_DEVICE} 1` $TMPDIR
|
|
||||||
|
|
||||||
cat $TMPDIR/config.txt | grep -v "dtoverlay=" | sudo tee $TMPDIR/config.txt.tmp > /dev/null
|
|
||||||
echo "dtoverlay=pwm-2chan,disable-bt" | sudo tee -a $TMPDIR/config.txt.tmp > /dev/null
|
|
||||||
echo "gpu_mem=16" | sudo tee -a $TMPDIR/config.txt.tmp > /dev/null
|
|
||||||
sudo mv $TMPDIR/config.txt.tmp $TMPDIR/config.txt
|
|
||||||
sudo touch $TMPDIR/ssh
|
|
||||||
|
|
||||||
sudo umount $TMPDIR
|
|
||||||
|
|
||||||
sudo mount `partition_for ${OUTPUT_DEVICE} 2` $TMPDIR
|
|
||||||
|
|
||||||
sudo mkdir $TMPDIR/media/embassy/
|
|
||||||
sudo ENVIRONMENT=$ENVIRONMENT make V=1 install ARCH=aarch64 OS_ARCH=raspberrypi DESTDIR=$TMPDIR --debug
|
|
||||||
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hostname
|
|
||||||
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hosts
|
|
||||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
|
|
||||||
sudo cp cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
|
|
||||||
sudo cp backend/*.service $TMPDIR/etc/systemd/system/
|
|
||||||
sudo mkdir -p $TMPDIR/etc/embassy
|
|
||||||
sudo cp build/raspberry-pi/config.yaml $TMPDIR/etc/embassy/config.yaml
|
|
||||||
|
|
||||||
# Make the .ssh directory for UID 1000 user
|
|
||||||
sudo mkdir -p $TMPDIR/home/$(awk -v val=1000 -F ":" '$3==val{print $1}' $TMPDIR/etc/passwd)/.ssh
|
|
||||||
sudo mv $TMPDIR/etc/sudoers.d/010_pi-nopasswd $TMPDIR/etc/sudoers.d/010_start9-nopasswd
|
|
||||||
sudo sed -i 's/pi/start9/g' $TMPDIR/etc/sudoers.d/010_start9-nopasswd
|
|
||||||
sudo sed -i 's/ pi / start9 /g' $TMPDIR/etc/systemd/system/autologin@.service
|
|
||||||
|
|
||||||
if [[ "$ENVIRONMENT" =~ (^|-)dev($|-) ]]; then
|
|
||||||
cat ./build/raspberry-pi/initialization.sh | grep -v "passwd -l start9" | sudo tee $TMPDIR/usr/local/bin/initialization.sh > /dev/null
|
|
||||||
sudo chmod +x $TMPDIR/usr/local/bin/initialization.sh
|
|
||||||
else
|
|
||||||
sudo cp ./build/raspberry-pi/initialization.sh $TMPDIR/usr/local/bin
|
|
||||||
fi
|
|
||||||
sudo cp ./build/raspberry-pi/init-with-sound.sh $TMPDIR/usr/local/bin
|
|
||||||
|
|
||||||
sudo cp ./build/raspberry-pi/initialization.service $TMPDIR/etc/systemd/system/initialization.service
|
|
||||||
sudo ln -s /etc/systemd/system/initialization.service $TMPDIR/etc/systemd/system/multi-user.target.wants/initialization.service
|
|
||||||
sudo cp ./build/raspberry-pi/nc-broadcast.service $TMPDIR/etc/systemd/system/nc-broadcast.service
|
|
||||||
sudo ln -s /etc/systemd/system/nc-broadcast.service $TMPDIR/etc/systemd/system/multi-user.target.wants/nc-broadcast.service
|
|
||||||
|
|
||||||
sudo umount $TMPDIR
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
os-partitions:
|
os-partitions:
|
||||||
boot: /dev/mmcblk0p1
|
boot: /dev/mmcblk0p1
|
||||||
root: /dev/mmcblk0p2
|
root: /dev/mmcblk0p2
|
||||||
ethernet-interface: eth0
|
ethernet-interface: end0
|
||||||
wifi-interface: wlan0
|
wifi-interface: wlan0
|
||||||
2
build/raspberrypi/fstab
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/dev/mmcblk0p1 /boot vfat umask=0077 0 2
|
||||||
|
/dev/mmcblk0p2 / ext4 defaults 0 1
|
||||||
129
build/raspberrypi/init_resize.sh
Executable file
@@ -0,0 +1,129 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
get_variables () {
|
||||||
|
ROOT_PART_DEV=$(findmnt / -o source -n)
|
||||||
|
ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
|
||||||
|
ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
|
||||||
|
ROOT_DEV="/dev/${ROOT_DEV_NAME}"
|
||||||
|
ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition")
|
||||||
|
|
||||||
|
BOOT_PART_DEV=$(findmnt /boot -o source -n)
|
||||||
|
BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3)
|
||||||
|
BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
|
||||||
|
BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")
|
||||||
|
|
||||||
|
OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')
|
||||||
|
|
||||||
|
ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
|
||||||
|
if [ "$ROOT_DEV_SIZE" -le 67108864 ]; then
|
||||||
|
TARGET_END=$((ROOT_DEV_SIZE - 1))
|
||||||
|
else
|
||||||
|
TARGET_END=$((33554432 - 1))
|
||||||
|
DATA_PART_START=33554432
|
||||||
|
DATA_PART_END=$((ROOT_DEV_SIZE - 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')
|
||||||
|
|
||||||
|
LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1)
|
||||||
|
|
||||||
|
ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:")
|
||||||
|
ROOT_PART_START=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 2)
|
||||||
|
ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
check_variables () {
|
||||||
|
if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then
|
||||||
|
FAIL_REASON="Boot and root partitions are on different devices"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then
|
||||||
|
FAIL_REASON="Root partition should be last partition"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then
|
||||||
|
FAIL_REASON="Root partition runs past the end of device"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then
|
||||||
|
FAIL_REASON="Could not determine partitions"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main () {
|
||||||
|
get_variables
|
||||||
|
|
||||||
|
if ! check_variables; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
|
||||||
|
# reboot_pi
|
||||||
|
# fi
|
||||||
|
|
||||||
|
if ! echo Yes | parted -m --align=optimal "$ROOT_DEV" ---pretend-input-tty u s resizepart "$ROOT_PART_NUM" "$TARGET_END" ; then
|
||||||
|
FAIL_REASON="Root partition resize failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$DATA_PART_START" ]; then
|
||||||
|
if ! parted -ms --align=optimal "$ROOT_DEV" u s mkpart primary "$DATA_PART_START" "$DATA_PART_END"; then
|
||||||
|
FAIL_REASON="Data partition creation failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
echo x
|
||||||
|
echo i
|
||||||
|
echo "0xcb15ae4d"
|
||||||
|
echo r
|
||||||
|
echo w
|
||||||
|
) | fdisk $ROOT_DEV
|
||||||
|
|
||||||
|
mount / -o remount,rw
|
||||||
|
|
||||||
|
resize2fs $ROOT_PART_DEV
|
||||||
|
|
||||||
|
if ! systemd-machine-id-setup; then
|
||||||
|
FAIL_REASON="systemd-machine-id-setup failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ssh-keygen -A; then
|
||||||
|
FAIL_REASON="ssh host key generation failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo start > /etc/hostname
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mount -t proc proc /proc
|
||||||
|
mount -t sysfs sys /sys
|
||||||
|
mount -t tmpfs tmp /run
|
||||||
|
mkdir -p /run/systemd
|
||||||
|
mount /boot
|
||||||
|
mount / -o remount,ro
|
||||||
|
|
||||||
|
beep
|
||||||
|
|
||||||
|
if main; then
|
||||||
|
sed -i 's| init=/usr/lib/embassy/scripts/init_resize\.sh| boot=embassy|' /boot/cmdline.txt
|
||||||
|
echo "Resized root filesystem. Rebooting in 5 seconds..."
|
||||||
|
sleep 5
|
||||||
|
else
|
||||||
|
echo -e "Could not expand filesystem.\n${FAIL_REASON}"
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
sync
|
||||||
|
|
||||||
|
umount /boot
|
||||||
|
|
||||||
|
reboot -f
|
||||||
84
build/raspberrypi/make-image.sh
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
function partition_for () {
|
||||||
|
if [[ "$1" =~ [0-9]+$ ]]; then
|
||||||
|
echo "$1p$2"
|
||||||
|
else
|
||||||
|
echo "$1$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
VERSION=$(cat VERSION.txt)
|
||||||
|
ENVIRONMENT=$(cat ENVIRONMENT.txt)
|
||||||
|
GIT_HASH=$(cat GIT_HASH.txt | head -c 7)
|
||||||
|
DATE=$(date +%Y%m%d)
|
||||||
|
|
||||||
|
VERSION_FULL="$VERSION-$GIT_HASH"
|
||||||
|
|
||||||
|
if [ -n "$ENVIRONMENT" ]; then
|
||||||
|
VERSION_FULL="$VERSION_FULL~$ENVIRONMENT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_NAME=startos-${VERSION_FULL}-${DATE}_raspberrypi.img
|
||||||
|
TARGET_SIZE=$[(6817791+1)*512]
|
||||||
|
|
||||||
|
rm -f $TARGET_NAME
|
||||||
|
truncate -s $TARGET_SIZE $TARGET_NAME
|
||||||
|
(
|
||||||
|
echo o
|
||||||
|
echo x
|
||||||
|
echo i
|
||||||
|
echo "0xcb15ae4d"
|
||||||
|
echo r
|
||||||
|
echo n
|
||||||
|
echo p
|
||||||
|
echo 1
|
||||||
|
echo 2048
|
||||||
|
echo 526335
|
||||||
|
echo t
|
||||||
|
echo c
|
||||||
|
echo n
|
||||||
|
echo p
|
||||||
|
echo 2
|
||||||
|
echo 526336
|
||||||
|
echo 6817791
|
||||||
|
echo a
|
||||||
|
echo 1
|
||||||
|
echo w
|
||||||
|
) | fdisk $TARGET_NAME
|
||||||
|
OUTPUT_DEVICE=$(sudo losetup --show -fP $TARGET_NAME)
|
||||||
|
sudo mkfs.ext4 `partition_for ${OUTPUT_DEVICE} 2`
|
||||||
|
sudo mkfs.vfat `partition_for ${OUTPUT_DEVICE} 1`
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d)
|
||||||
|
|
||||||
|
sudo mount `partition_for ${OUTPUT_DEVICE} 2` $TMPDIR
|
||||||
|
sudo mkdir $TMPDIR/boot
|
||||||
|
sudo mount `partition_for ${OUTPUT_DEVICE} 1` $TMPDIR/boot
|
||||||
|
sudo unsquashfs -f -d $TMPDIR startos.raspberrypi.squashfs
|
||||||
|
REAL_GIT_HASH=$(cat $TMPDIR/usr/lib/embassy/GIT_HASH.txt)
|
||||||
|
REAL_VERSION=$(cat $TMPDIR/usr/lib/embassy/VERSION.txt)
|
||||||
|
REAL_ENVIRONMENT=$(cat $TMPDIR/usr/lib/embassy/ENVIRONMENT.txt)
|
||||||
|
sudo sed -i 's| boot=embassy| init=/usr/lib/embassy/scripts/init_resize\.sh|' $TMPDIR/boot/cmdline.txt
|
||||||
|
sudo cp ./build/raspberrypi/fstab $TMPDIR/etc/
|
||||||
|
sudo cp ./build/raspberrypi/init_resize.sh $TMPDIR/usr/lib/embassy/scripts/init_resize.sh
|
||||||
|
sudo umount $TMPDIR/boot
|
||||||
|
sudo umount $TMPDIR
|
||||||
|
sudo losetup -d $OUTPUT_DEVICE
|
||||||
|
|
||||||
|
if [ "$ALLOW_VERSION_MISMATCH" != 1 ]; then
|
||||||
|
if [ "$(cat GIT_HASH.txt)" != "$REAL_GIT_HASH" ]; then
|
||||||
|
>&2 echo "startos.raspberrypi.squashfs GIT_HASH.txt mismatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat VERSION.txt)" != "$REAL_VERSION" ]; then
|
||||||
|
>&2 echo "startos.raspberrypi.squashfs VERSION.txt mismatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat ENVIRONMENT.txt)" != "$REAL_ENVIRONMENT" ]; then
|
||||||
|
>&2 echo "startos.raspberrypi.squashfs ENVIRONMENT.txt mismatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if ! [ -f ./ENVIRONMENT.txt ] || [ "$(cat ./ENVIRONMENT.txt)" != "$ENVIRONMENT" ]; then
|
if ! [ -f ./ENVIRONMENT.txt ] || [ "$(cat ./ENVIRONMENT.txt)" != "$ENVIRONMENT" ]; then
|
||||||
>&2 echo "Updating ENVIRONMENT.txt to $ENVIRONMENT"
|
>&2 echo "Updating ENVIRONMENT.txt to \"$ENVIRONMENT\""
|
||||||
echo -n "$ENVIRONMENT" > ./ENVIRONMENT.txt
|
echo -n "$ENVIRONMENT" > ./ENVIRONMENT.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# embassyOS Frontend
|
# StartOS Frontend
|
||||||
|
|
||||||
embassyOS has three user interfaces and a shared library, all written in Ionic/Angular/Typescript using an Angular workspace environment:
|
StartOS has three user interfaces and a shared library, all written in Ionic/Angular/Typescript using an Angular workspace environment:
|
||||||
|
|
||||||
1. **ui**: the main user interface
|
1. **ui**: the main user interface
|
||||||
1. **install-wizard**: used to install embassyOS
|
1. **install-wizard**: used to install StartOS
|
||||||
1. **setup-wizard**: used to facilitate initial setup
|
1. **setup-wizard**: used to facilitate initial setup
|
||||||
1. **diagnostic-ui**: used to display certain diagnostic information in the event embassyOS fails to initialize
|
1. **diagnostic-ui**: used to display certain diagnostic information in the event StartOS fails to initialize
|
||||||
1. **marketplace**: abstracted ui elements to search for, list and display details for packages and their dependencies
|
1. **marketplace**: abstracted ui elements to search for, list and display details for packages and their dependencies
|
||||||
1. **shared**: contains components, types, and functions shared amongst all of the UIs.
|
1. **shared**: contains components, types, and functions shared amongst all of the UIs.
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ v8.0.0
|
|||||||
1. Clone the repository
|
1. Clone the repository
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/Start9Labs/embassy-os.git
|
git clone https://github.com/Start9Labs/start-os.git
|
||||||
cd embassy-os
|
cd start-os
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
cd frontend
|
cd frontend
|
||||||
npm ci
|
npm ci
|
||||||
@@ -58,7 +58,7 @@ npm run start:diagnostic-ui
|
|||||||
|
|
||||||
## Running locally with proxied backend
|
## Running locally with proxied backend
|
||||||
|
|
||||||
This section enables you to run a local frontend with a remote backend (eg. hosted on a live Embassy). It assumes you have completed Step 1 and Step 2 in the [section above](#running-locally-with-mocks)
|
This section enables you to run a local frontend with a remote backend (eg. hosted on a live Start9 server). It assumes you have completed Step 1 and Step 2 in the [section above](#running-locally-with-mocks)
|
||||||
|
|
||||||
1. Set `useMocks: false` in `config.json`
|
1. Set `useMocks: false` in `config.json`
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,12 @@
|
|||||||
"glob": "**/*",
|
"glob": "**/*",
|
||||||
"input": "node_modules/monaco-editor",
|
"input": "node_modules/monaco-editor",
|
||||||
"output": "assets/monaco-editor/"
|
"output": "assets/monaco-editor/"
|
||||||
|
},
|
||||||
|
"projects/ui/src/manifest.webmanifest",
|
||||||
|
{
|
||||||
|
"glob": "ngsw.json",
|
||||||
|
"input": "dist/ui",
|
||||||
|
"output": "projects/ui/src"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
@@ -43,10 +49,12 @@
|
|||||||
"projects/shared/styles/shared.scss",
|
"projects/shared/styles/shared.scss",
|
||||||
"projects/ui/src/styles.scss"
|
"projects/ui/src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": [],
|
||||||
|
"ngswConfigPath": "projects/ui/ngsw-config.json"
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
"serviceWorker": true,
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
|
|||||||
983
frontend/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-os",
|
"name": "startos-ui",
|
||||||
"version": "0.3.4.1",
|
"version": "0.3.4.2",
|
||||||
"author": "Start9 Labs, Inc",
|
"author": "Start9 Labs, Inc",
|
||||||
"homepage": "https://start9.com/",
|
"homepage": "https://start9.com/",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"build:install-wiz": "ng run install-wizard:build",
|
"build:install-wiz": "ng run install-wizard:build",
|
||||||
"build:setup": "ng run setup-wizard:build",
|
"build:setup": "ng run setup-wizard:build",
|
||||||
"build:ui": "ng run ui:build",
|
"build:ui": "ng run ui:build",
|
||||||
|
"build:ui:dev": "ng run ui:build:development",
|
||||||
"build:ui:stats": "ng run ui:build --stats-json",
|
"build:ui:stats": "ng run ui:build --stats-json",
|
||||||
"build:all": "npm run build:deps && npm run build:dui && npm run build:setup && npm run build:ui && npm run build:install-wiz",
|
"build:all": "npm run build:deps && npm run build:dui && npm run build:setup && npm run build:ui && npm run build:install-wiz",
|
||||||
"build:shared": "ng build shared",
|
"build:shared": "ng build shared",
|
||||||
@@ -39,7 +40,9 @@
|
|||||||
"@angular/forms": "^14.1.0",
|
"@angular/forms": "^14.1.0",
|
||||||
"@angular/platform-browser": "^14.1.0",
|
"@angular/platform-browser": "^14.1.0",
|
||||||
"@angular/platform-browser-dynamic": "^14.1.0",
|
"@angular/platform-browser-dynamic": "^14.1.0",
|
||||||
|
"@angular/pwa": "^14.1.0",
|
||||||
"@angular/router": "^14.1.0",
|
"@angular/router": "^14.1.0",
|
||||||
|
"@angular/service-worker": "^14.2.2",
|
||||||
"@ionic/angular": "^6.1.15",
|
"@ionic/angular": "^6.1.15",
|
||||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||||
"@ng-web-apis/common": "^2.0.0",
|
"@ng-web-apis/common": "^2.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": null,
|
"name": null,
|
||||||
"ack-welcome": "0.3.4.1",
|
"ack-welcome": "0.3.4.2",
|
||||||
"marketplace": {
|
"marketplace": {
|
||||||
"selected-url": "https://registry.start9.com/",
|
"selected-url": "https://registry.start9.com/",
|
||||||
"known-hosts": {
|
"known-hosts": {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
class="ion-text-center"
|
class="ion-text-center"
|
||||||
style="padding-bottom: 36px; font-size: calc(2vw + 14px)"
|
style="padding-bottom: 36px; font-size: calc(2vw + 14px)"
|
||||||
>
|
>
|
||||||
embassyOS - Diagnostic Mode
|
StartOS - Diagnostic Mode
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<ng-container *ngIf="error">
|
<ng-container *ngIf="error">
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
embassyOS launch error:
|
StartOS launch error:
|
||||||
</h2>
|
</h2>
|
||||||
<div class="code-block">
|
<div class="code-block">
|
||||||
<code>
|
<code>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<ion-button routerLink="logs"> View Logs </ion-button>
|
<ion-button routerLink="logs">View Logs</ion-button>
|
||||||
<h2
|
<h2
|
||||||
style="
|
style="
|
||||||
padding: 32px 0 16px 0;
|
padding: 32px 0 16px 0;
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div class="code-block">
|
<div class="code-block">
|
||||||
<code><ion-text color="success">{{ error.solution }}</ion-text></code>
|
<code><ion-text color="success">{{ error.solution }}</ion-text></code>
|
||||||
</div>
|
</div>
|
||||||
<ion-button (click)="restart()"> Restart Embassy </ion-button>
|
<ion-button (click)="restart()">Restart Server</ion-button>
|
||||||
<ion-button
|
<ion-button
|
||||||
class="ion-padding-start"
|
class="ion-padding-start"
|
||||||
*ngIf="error.code === 15 || error.code === 25"
|
*ngIf="error.code === 15 || error.code === 25"
|
||||||
@@ -52,15 +52,15 @@
|
|||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
||||||
<div class="ion-padding-top">
|
<div class="ion-padding-top">
|
||||||
<ion-button (click)="presentAlertSystemRebuild()" color="warning"
|
<ion-button (click)="presentAlertSystemRebuild()" color="warning">
|
||||||
>System Rebuild</ion-button
|
System Rebuild
|
||||||
>
|
</ion-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ion-padding-top">
|
<div class="ion-padding-top">
|
||||||
<ion-button (click)="presentAlertRepairDisk()" color="danger"
|
<ion-button (click)="presentAlertRepairDisk()" color="danger">
|
||||||
>Repair Drive</ion-button
|
Repair Drive
|
||||||
>
|
</ion-button>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -70,12 +70,12 @@
|
|||||||
class="ion-text-center"
|
class="ion-text-center"
|
||||||
style="padding-bottom: 36px; font-size: calc(2vw + 12px)"
|
style="padding-bottom: 36px; font-size: calc(2vw + 12px)"
|
||||||
>
|
>
|
||||||
Embassy is restarting
|
Server is restarting
|
||||||
</h1>
|
</h1>
|
||||||
<h2 style="padding-bottom: 16px; font-size: calc(1vw + 12px)">
|
<h2 style="padding-bottom: 16px; font-size: calc(1vw + 12px)">
|
||||||
Wait for Embassy restart, then refresh this page or click REFRESH below.
|
Wait for the server to restart, then refresh this page.
|
||||||
</h2>
|
</h2>
|
||||||
<ion-button (click)="refreshPage()"> Refresh </ion-button>
|
<ion-button (click)="refreshPage()">Refresh</ion-button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class HomePage {
|
|||||||
code: 15,
|
code: 15,
|
||||||
problem: 'Unknown storage drive detected',
|
problem: 'Unknown storage drive detected',
|
||||||
solution:
|
solution:
|
||||||
'To use a different storage drive, replace the current one and click RESTART EMBASSY below. To use the current storage drive, click USE CURRENT DRIVE below, then follow instructions. No data will be erased during this process.',
|
'To use a different storage drive, replace the current one and click RESTART SERVER below. To use the current storage drive, click USE CURRENT DRIVE below, then follow instructions. No data will be erased during this process.',
|
||||||
details: error.data?.details,
|
details: error.data?.details,
|
||||||
}
|
}
|
||||||
// no drive
|
// no drive
|
||||||
@@ -41,7 +41,7 @@ export class HomePage {
|
|||||||
code: 20,
|
code: 20,
|
||||||
problem: 'Storage drive not found',
|
problem: 'Storage drive not found',
|
||||||
solution:
|
solution:
|
||||||
'Insert your embassyOS storage drive and click RESTART EMBASSY below.',
|
'Insert your StartOS storage drive and click RESTART SERVER below.',
|
||||||
details: error.data?.details,
|
details: error.data?.details,
|
||||||
}
|
}
|
||||||
// drive corrupted
|
// drive corrupted
|
||||||
@@ -60,7 +60,7 @@ export class HomePage {
|
|||||||
code: 2,
|
code: 2,
|
||||||
problem: 'Filesystem I/O error.',
|
problem: 'Filesystem I/O error.',
|
||||||
solution:
|
solution:
|
||||||
'Repairing the disk could help resolve this issue. Please DO NOT unplug the drive or Embassy during this time or the situation will become worse.',
|
'Repairing the disk could help resolve this issue. Please DO NOT unplug the drive or server during this time or the situation will become worse.',
|
||||||
details: error.data?.details,
|
details: error.data?.details,
|
||||||
}
|
}
|
||||||
// disk management error - disk needs repair
|
// disk management error - disk needs repair
|
||||||
@@ -69,7 +69,7 @@ export class HomePage {
|
|||||||
code: 48,
|
code: 48,
|
||||||
problem: 'Disk management error.',
|
problem: 'Disk management error.',
|
||||||
solution:
|
solution:
|
||||||
'Repairing the disk could help resolve this issue. Please DO NOT unplug the drive or Embassy during this time or the situation will become worse.',
|
'Repairing the disk could help resolve this issue. Please DO NOT unplug the drive or server during this time or the situation will become worse.',
|
||||||
details: error.data?.details,
|
details: error.data?.details,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -122,7 +122,7 @@ export class HomePage {
|
|||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
header: 'Warning',
|
header: 'Warning',
|
||||||
message:
|
message:
|
||||||
'<p>This action will tear down all service containers and rebuild them from scratch. No data will be deleted.</p><p>A system rebuild can be useful if your system gets into a bad state, and it should only be performed if you are experiencing general performance or reliability issues.</p><p>It may take up to an hour to complete. During this time, you will lose all connectivity to your Embassy.</p>',
|
'<p>This action will tear down all service containers and rebuild them from scratch. No data will be deleted.</p><p>A system rebuild can be useful if your system gets into a bad state, and it should only be performed if you are experiencing general performance or reliability issues.</p><p>It may take up to an hour to complete. During this time, you will lose all connectivity to your Start9 server.</p>',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: 'Cancel',
|
text: 'Cancel',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export class MockApiService implements ApiService {
|
|||||||
await pauseFor(1000)
|
await pauseFor(1000)
|
||||||
return {
|
return {
|
||||||
code: 15,
|
code: 15,
|
||||||
message: 'Unknown Embassy',
|
message: 'Unknown server',
|
||||||
data: { details: 'Some details about the error here' },
|
data: { details: 'Some details about the error here' },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>StartOS Diagnostic UI</title>
|
||||||
|
|
||||||
<head>
|
<base href="/" />
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>embassyOS Diagnostic UI</title>
|
|
||||||
|
|
||||||
<base href="/" />
|
<meta name="color-scheme" content="light dark" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
|
<meta name="format-detection" content="telephone=no" />
|
||||||
|
<meta name="msapplication-tap-highlight" content="no" />
|
||||||
|
|
||||||
<meta name="color-scheme" content="light dark" />
|
<link rel="icon" type="image/png" href="assets/icon/favicon.ico" />
|
||||||
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
</head>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
|
||||||
<meta name="msapplication-tap-highlight" content="no" />
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="assets/icon/favicon.ico" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<app-root></app-root>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -70,11 +70,9 @@
|
|||||||
></ion-icon>
|
></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h1>
|
<h1>
|
||||||
<ion-text color="success"
|
<ion-text color="success">Re-Install StartOS</ion-text>
|
||||||
>Re-Install embassyOS</ion-text
|
|
||||||
>
|
|
||||||
</h1>
|
</h1>
|
||||||
<h2>Will preserve existing embassyOS data</h2>
|
<h2>Will preserve existing StartOS data</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
@@ -92,7 +90,7 @@
|
|||||||
[color]="(selectedDisk | guid) ? 'danger' : 'success'"
|
[color]="(selectedDisk | guid) ? 'danger' : 'success'"
|
||||||
>
|
>
|
||||||
{{ (selectedDisk | guid) ? 'Factory Reset' : 'Install
|
{{ (selectedDisk | guid) ? 'Factory Reset' : 'Install
|
||||||
embassyOS' }}
|
StartOS' }}
|
||||||
</ion-text>
|
</ion-text>
|
||||||
</h1>
|
</h1>
|
||||||
<h2>Will delete existing data on disk</h2>
|
<h2>Will delete existing data on disk</h2>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class HomePage {
|
|||||||
|
|
||||||
private async install(overwrite: boolean) {
|
private async install(overwrite: boolean) {
|
||||||
const loader = await this.loadingCtrl.create({
|
const loader = await this.loadingCtrl.create({
|
||||||
message: 'Installing embassyOS...',
|
message: 'Installing StartOS...',
|
||||||
})
|
})
|
||||||
await loader.present()
|
await loader.present()
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ export class HomePage {
|
|||||||
header: 'Warning',
|
header: 'Warning',
|
||||||
message: `This action will COMPLETELY erase the disk ${
|
message: `This action will COMPLETELY erase the disk ${
|
||||||
vendor || 'Unknown Vendor'
|
vendor || 'Unknown Vendor'
|
||||||
} - ${model || 'Unknown Model'} and install embassyOS in its place`,
|
} - ${model || 'Unknown Model'} and install StartOS in its place`,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: 'Cancel',
|
text: 'Cancel',
|
||||||
@@ -102,7 +102,7 @@ export class HomePage {
|
|||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
header: 'Install Success',
|
header: 'Install Success',
|
||||||
message:
|
message:
|
||||||
'Remove the USB stick and reboot your device to begin using your new Embassy',
|
'Remove the USB stick and reboot your device to begin using your new Start9 server',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: 'Reboot',
|
text: 'Reboot',
|
||||||
@@ -133,7 +133,7 @@ export class HomePage {
|
|||||||
private async presentAlertComplete() {
|
private async presentAlertComplete() {
|
||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
header: 'Rebooting',
|
header: 'Rebooting',
|
||||||
message: 'Please wait for embassyOS to restart, then refresh this page',
|
message: 'Please wait for StartOS to restart, then refresh this page',
|
||||||
buttons: ['OK'],
|
buttons: ['OK'],
|
||||||
})
|
})
|
||||||
await alert.present()
|
await alert.present()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>embassyOS Install Wizard</title>
|
<title>StartOS Install Wizard</title>
|
||||||
|
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<ion-item class="service-card" [routerLink]="['/marketplace', pkg.manifest.id]">
|
<ion-item class="service-card" [routerLink]="['/marketplace', pkg.manifest.id]">
|
||||||
<ion-thumbnail slot="start">
|
<ion-thumbnail slot="start">
|
||||||
<img alt="" [src]="'data:image/png;base64,' + pkg.icon | trustUrl" />
|
<img alt="" [src]="pkg | mimeType | trustUrl" />
|
||||||
</ion-thumbnail>
|
</ion-thumbnail>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2 class="montserrat">
|
<h2 class="montserrat">
|
||||||
|
|||||||
@@ -3,12 +3,18 @@ import { NgModule } from '@angular/core'
|
|||||||
import { IonicModule } from '@ionic/angular'
|
import { IonicModule } from '@ionic/angular'
|
||||||
import { RouterModule } from '@angular/router'
|
import { RouterModule } from '@angular/router'
|
||||||
import { SharedPipesModule } from '@start9labs/shared'
|
import { SharedPipesModule } from '@start9labs/shared'
|
||||||
|
|
||||||
import { ItemComponent } from './item.component'
|
import { ItemComponent } from './item.component'
|
||||||
|
import { MimeTypePipeModule } from '../../../pipes/mime-type.pipe'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule, IonicModule, RouterModule, SharedPipesModule],
|
|
||||||
declarations: [ItemComponent],
|
declarations: [ItemComponent],
|
||||||
exports: [ItemComponent],
|
exports: [ItemComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
IonicModule,
|
||||||
|
RouterModule,
|
||||||
|
SharedPipesModule,
|
||||||
|
MimeTypePipeModule,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class ItemModule {}
|
export class ItemModule {}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export class DependenciesComponent {
|
|||||||
pkg!: MarketplacePkg
|
pkg!: MarketplacePkg
|
||||||
|
|
||||||
getImg(key: string): string {
|
getImg(key: string): string {
|
||||||
|
// @TODO fix when registry api is updated to include mimetype in icon url
|
||||||
return 'data:image/png;base64,' + this.pkg['dependency-metadata'][key].icon
|
return 'data:image/png;base64,' + this.pkg['dependency-metadata'][key].icon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<div class="header montserrat">
|
<div class="header montserrat">
|
||||||
<img
|
<img class="logo" alt="" [src]="pkg | mimeType | trustUrl" />
|
||||||
class="logo"
|
|
||||||
alt=""
|
|
||||||
[src]="'data:image/png;base64,' + pkg.icon | trustUrl"
|
|
||||||
/>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<h1 ticker class="title">{{ pkg.manifest.title }}</h1>
|
<h1 ticker class="title">{{ pkg.manifest.title }}</h1>
|
||||||
<p class="version">{{ pkg.manifest.version | displayEmver }}</p>
|
<p class="version">{{ pkg.manifest.version | displayEmver }}</p>
|
||||||
|
|||||||
@@ -8,16 +8,18 @@ import {
|
|||||||
} from '@start9labs/shared'
|
} from '@start9labs/shared'
|
||||||
|
|
||||||
import { PackageComponent } from './package.component'
|
import { PackageComponent } from './package.component'
|
||||||
|
import { MimeTypePipeModule } from '../../../pipes/mime-type.pipe'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
declarations: [PackageComponent],
|
||||||
|
exports: [PackageComponent],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
IonicModule,
|
IonicModule,
|
||||||
SharedPipesModule,
|
SharedPipesModule,
|
||||||
EmverPipesModule,
|
EmverPipesModule,
|
||||||
TickerModule,
|
TickerModule,
|
||||||
|
MimeTypePipeModule,
|
||||||
],
|
],
|
||||||
declarations: [PackageComponent],
|
|
||||||
exports: [PackageComponent],
|
|
||||||
})
|
})
|
||||||
export class PackageModule {}
|
export class PackageModule {}
|
||||||
|
|||||||
32
frontend/projects/marketplace/src/pipes/mime-type.pipe.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { NgModule, Pipe, PipeTransform } from '@angular/core'
|
||||||
|
import { MarketplacePkg } from '../types'
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'mimeType',
|
||||||
|
})
|
||||||
|
export class MimeTypePipe implements PipeTransform {
|
||||||
|
transform(pkg: MarketplacePkg): string {
|
||||||
|
if (pkg.manifest.assets.icon) {
|
||||||
|
switch (pkg.manifest.assets.icon.split('.').pop()) {
|
||||||
|
case 'png':
|
||||||
|
return `data:image/png;base64,${pkg.icon}`
|
||||||
|
case 'jpeg':
|
||||||
|
case 'jpg':
|
||||||
|
return `data:image/jpeg;base64,${pkg.icon}`
|
||||||
|
case 'gif':
|
||||||
|
return `data:image/gif;base64,${pkg.icon}`
|
||||||
|
case 'svg':
|
||||||
|
return `data:image/svg+xml;base64,${pkg.icon}`
|
||||||
|
default:
|
||||||
|
return `data:image/png;base64,${pkg.icon}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `data:image/png;base64,${pkg.icon}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [MimeTypePipe],
|
||||||
|
exports: [MimeTypePipe],
|
||||||
|
})
|
||||||
|
export class MimeTypePipeModule {}
|
||||||
@@ -22,6 +22,7 @@ export * from './pages/show/package/package.component'
|
|||||||
export * from './pages/show/package/package.module'
|
export * from './pages/show/package/package.module'
|
||||||
|
|
||||||
export * from './pipes/filter-packages.pipe'
|
export * from './pipes/filter-packages.pipe'
|
||||||
|
export * from './pipes/mime-type.pipe'
|
||||||
|
|
||||||
export * from './services/marketplace.service'
|
export * from './services/marketplace.service'
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ export interface MarketplaceManifest<T = unknown> {
|
|||||||
short: string
|
short: string
|
||||||
long: string
|
long: string
|
||||||
}
|
}
|
||||||
|
assets: {
|
||||||
|
icon: string // ie. icon.png
|
||||||
|
}
|
||||||
replaces?: string[]
|
replaces?: string[]
|
||||||
'release-notes': string
|
'release-notes': string
|
||||||
license: string // type of license
|
license: string // type of license
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const routes: Routes = [
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'embassy',
|
path: 'storage',
|
||||||
loadChildren: () =>
|
loadChildren: () =>
|
||||||
import('./pages/embassy/embassy.module').then(m => m.EmbassyPageModule),
|
import('./pages/embassy/embassy.module').then(m => m.EmbassyPageModule),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
ModalController,
|
ModalController,
|
||||||
} from '@ionic/angular'
|
} from '@ionic/angular'
|
||||||
import { ApiService, CifsBackupTarget } from 'src/app/services/api/api.service'
|
import { ApiService, CifsBackupTarget } from 'src/app/services/api/api.service'
|
||||||
import { EmbassyOSDiskInfo } from '@start9labs/shared'
|
import { StartOSDiskInfo } from '@start9labs/shared'
|
||||||
import { PasswordPage } from '../password/password.page'
|
import { PasswordPage } from '../password/password.page'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -41,7 +41,7 @@ export class CifsModal {
|
|||||||
await loader.present()
|
await loader.present()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const embassyOS = await this.api.verifyCifs({
|
const diskInfo = await this.api.verifyCifs({
|
||||||
...this.cifs,
|
...this.cifs,
|
||||||
password: this.cifs.password
|
password: this.cifs.password
|
||||||
? await this.api.encrypt(this.cifs.password)
|
? await this.api.encrypt(this.cifs.password)
|
||||||
@@ -50,20 +50,18 @@ export class CifsModal {
|
|||||||
|
|
||||||
await loader.dismiss()
|
await loader.dismiss()
|
||||||
|
|
||||||
this.presentModalPassword(embassyOS)
|
this.presentModalPassword(diskInfo)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await loader.dismiss()
|
await loader.dismiss()
|
||||||
this.presentAlertFailed()
|
this.presentAlertFailed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async presentModalPassword(
|
private async presentModalPassword(diskInfo: StartOSDiskInfo): Promise<void> {
|
||||||
embassyOS: EmbassyOSDiskInfo,
|
|
||||||
): Promise<void> {
|
|
||||||
const target: CifsBackupTarget = {
|
const target: CifsBackupTarget = {
|
||||||
...this.cifs,
|
...this.cifs,
|
||||||
mountable: true,
|
mountable: true,
|
||||||
'embassy-os': embassyOS,
|
'embassy-os': diskInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
const modal = await this.modalController.create({
|
const modal = await this.modalController.create({
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title>
|
<ion-title>{{ storageDrive ? 'Set Password' : 'Unlock Drive' }}</ion-title>
|
||||||
{{ storageDrive ? 'Set Password' : 'Unlock Drive' }}
|
|
||||||
</ion-title>
|
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
@@ -13,7 +11,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<ng-template #choose>
|
<ng-template #choose>
|
||||||
<p>
|
<p>
|
||||||
Choose a password for your Embassy.
|
Choose a password for your server.
|
||||||
<i>Make it good. Write it down.</i>
|
<i>Make it good. Write it down.</i>
|
||||||
</p>
|
</p>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@@ -6,10 +6,9 @@
|
|||||||
<ion-card-header class="ion-text-center">
|
<ion-card-header class="ion-text-center">
|
||||||
<ion-card-title>Use existing drive</ion-card-title>
|
<ion-card-title>Use existing drive</ion-card-title>
|
||||||
<div class="center-wrapper">
|
<div class="center-wrapper">
|
||||||
<ion-card-subtitle
|
<ion-card-subtitle>
|
||||||
>Select the physical drive containing your Embassy
|
Select the physical drive containing your StartOS data
|
||||||
data</ion-card-subtitle
|
</ion-card-subtitle>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
|
|
||||||
@@ -24,8 +23,8 @@
|
|||||||
<ion-item-group *ngIf="!loading" class="ion-text-center">
|
<ion-item-group *ngIf="!loading" class="ion-text-center">
|
||||||
<!-- drives -->
|
<!-- drives -->
|
||||||
<p *ngIf="!drives.length">
|
<p *ngIf="!drives.length">
|
||||||
No valid Embassy data drives found. Please make sure the drive
|
No valid StartOS data drives found. Please make sure the drive
|
||||||
is a valid Embassy data drive (not a backup) and is firmly
|
is a valid StartOS data drive (not a backup) and is firmly
|
||||||
connected, then refresh the page.
|
connected, then refresh the page.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<ion-card-title>Select storage drive</ion-card-title>
|
<ion-card-title>Select storage drive</ion-card-title>
|
||||||
<div class="center-wrapper">
|
<div class="center-wrapper">
|
||||||
<ion-card-subtitle>
|
<ion-card-subtitle>
|
||||||
This is the drive where your Embassy data will be stored.
|
This is the drive where your StartOS data will be stored.
|
||||||
</ion-card-subtitle>
|
</ion-card-subtitle>
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
@@ -23,8 +23,8 @@
|
|||||||
<ion-card-title>No drives found</ion-card-title>
|
<ion-card-title>No drives found</ion-card-title>
|
||||||
<div class="center-wrapper">
|
<div class="center-wrapper">
|
||||||
<ion-card-subtitle>
|
<ion-card-subtitle>
|
||||||
Please connect an external storage drive to your Embassy, if
|
Please connect a storage drive to your server. Then click
|
||||||
applicable. Next, click "Refresh".
|
"Refresh".
|
||||||
</ion-card-subtitle>
|
</ion-card-subtitle>
|
||||||
</div>
|
</div>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
<ion-icon slot="icon-only" name="arrow-back"></ion-icon>
|
<ion-icon slot="icon-only" name="arrow-back"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-card-title>
|
<ion-card-title>
|
||||||
{{ swiper?.activeIndex === 0 ? 'embassyOS Setup' : 'Recover
|
{{ swiper?.activeIndex === 0 ? 'StartOS Setup' : 'Recover Options'
|
||||||
Options' }}
|
}}
|
||||||
</ion-card-title>
|
</ion-card-title>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-card-content class="ion-margin-bottom">
|
<ion-card-content class="ion-margin-bottom">
|
||||||
@@ -39,12 +39,12 @@
|
|||||||
[disabled]="error"
|
[disabled]="error"
|
||||||
detail="false"
|
detail="false"
|
||||||
lines="none"
|
lines="none"
|
||||||
routerLink="/embassy"
|
routerLink="/storage"
|
||||||
>
|
>
|
||||||
<ion-icon slot="start" name="add"></ion-icon>
|
<ion-icon slot="start" name="add"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><ion-text color="success">Start Fresh</ion-text></h2>
|
<h2><ion-text color="success">Start Fresh</ion-text></h2>
|
||||||
<p>Get started with a brand new Embassy</p>
|
<p>Get started with a brand new Start9 server</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
<ion-icon slot="start" name="reload"></ion-icon>
|
<ion-icon slot="start" name="reload"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2><ion-text color="danger">Recover</ion-text></h2>
|
<h2><ion-text color="danger">Recover</ion-text></h2>
|
||||||
<p>Recover, restore, or transfer Embassy data</p>
|
<p>Recover, restore, or transfer StartOS data</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<h2>
|
<h2>
|
||||||
<ion-text color="success">Use Existing Drive</ion-text>
|
<ion-text color="success">Use Existing Drive</ion-text>
|
||||||
</h2>
|
</h2>
|
||||||
<p>Attach an existing embassyOS data drive (<b>not</b> a backup)</p>
|
<p>Attach an existing StartOS data drive (not a backup)</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
<ion-text color="primary">Transfer</ion-text>
|
<ion-text color="primary">Transfer</ion-text>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Transfer data from an existing embassyOS data drive (not a
|
Transfer data from an existing StartOS data drive (not a
|
||||||
backup) to a new, preferred drive
|
backup) to a new, preferred drive
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
Restore From Backup (Disaster Recovery)
|
Restore From Backup (Disaster Recovery)
|
||||||
</ion-text>
|
</ion-text>
|
||||||
</h2>
|
</h2>
|
||||||
<p>Restore embassyOS data from an encrypted backup</p>
|
<p>Restore StartOS data from an encrypted backup</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
color="dark"
|
color="dark"
|
||||||
>
|
>
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<ion-card-title>Initializing Embassy</ion-card-title>
|
<ion-card-title>Initializing StartOS</ion-card-title>
|
||||||
<div class="center-wrapper">
|
<div class="center-wrapper">
|
||||||
<ion-card-subtitle *ngIf="progress.decimal as decimal">
|
<ion-card-subtitle *ngIf="progress.decimal as decimal">
|
||||||
Progress: {{ (decimal * 100).toFixed(0)}}%
|
Progress: {{ (decimal * 100).toFixed(0)}}%
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export class ToMessagePipe implements PipeTransform {
|
|||||||
|
|
||||||
transform(progress: number | null): string {
|
transform(progress: number | null): string {
|
||||||
if (['fresh', 'attach'].includes(this.stateService.setupType || '')) {
|
if (['fresh', 'attach'].includes(this.stateService.setupType || '')) {
|
||||||
return 'Setting up your Embassy'
|
return 'Setting up your server'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!progress) {
|
if (!progress) {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
<!-- has backup -->
|
<!-- has backup -->
|
||||||
<h2 *ngIf="hasValidBackup; else noBackup">
|
<h2 *ngIf="hasValidBackup; else noBackup">
|
||||||
<ion-icon name="cloud-done" color="success"></ion-icon>
|
<ion-icon name="cloud-done" color="success"></ion-icon>
|
||||||
Embassy backup detected
|
StartOS backup detected
|
||||||
</h2>
|
</h2>
|
||||||
<!-- no backup -->
|
<!-- no backup -->
|
||||||
<ng-template #noBackup>
|
<ng-template #noBackup>
|
||||||
<h2>
|
<h2>
|
||||||
<ion-icon name="cloud-offline" color="danger"></ion-icon>
|
<ion-icon name="cloud-offline" color="danger"></ion-icon>
|
||||||
No Embassy backup
|
No StartOS backup
|
||||||
</h2>
|
</h2>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
<!-- cifs -->
|
<!-- cifs -->
|
||||||
<h2 class="target-label">Network Folder</h2>
|
<h2 class="target-label">Network Folder</h2>
|
||||||
<p class="ion-padding-bottom ion-text-left">
|
<p class="ion-padding-bottom ion-text-left">
|
||||||
Restore your Embassy from a folder on another computer that is
|
Restore StartOS data from a folder on another computer that is
|
||||||
connected to the same network as your Embassy.
|
connected to the same network as your server.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- connect -->
|
<!-- connect -->
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
<h2 class="target-label">Physical Drive</h2>
|
<h2 class="target-label">Physical Drive</h2>
|
||||||
<div class="ion-text-left ion-padding-bottom">
|
<div class="ion-text-left ion-padding-bottom">
|
||||||
<p>
|
<p>
|
||||||
Restore your Embassy from a physical drive that is plugged
|
Restore StartOS data from a physical drive that is plugged
|
||||||
directly into your Embassy.
|
directly into your server.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<b>
|
<b>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export class RecoverPage {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.stateService.recoveryPassword = res.data.recoveryPassword
|
this.stateService.recoveryPassword = res.data.recoveryPassword
|
||||||
this.navCtrl.navigateForward('/embassy')
|
this.navCtrl.navigateForward('/storage')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await modal.present()
|
await modal.present()
|
||||||
@@ -119,7 +119,7 @@ export class RecoverPage {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.stateService.recoveryPassword = password
|
this.stateService.recoveryPassword = password
|
||||||
this.navCtrl.navigateForward(`/embassy`)
|
this.navCtrl.navigateForward(`/storage`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Embassy Address Info</title>
|
<title>StartOS Address Info</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div
|
<div
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
Embassy Address Info
|
StartOS Address Info
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Visit the address below when you are connected to the same WiFi or
|
Visit the address below when you are connected to the same WiFi or
|
||||||
Local Area Network (LAN) as your Embassy:
|
Local Area Network (LAN) as your server:
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
style="
|
style="
|
||||||
@@ -60,15 +60,15 @@
|
|||||||
>
|
>
|
||||||
follow the instructions
|
follow the instructions
|
||||||
</a>
|
</a>
|
||||||
to establish a secure connection by installing your Embassy's
|
to establish a secure connection by installing your server's root
|
||||||
certificate.
|
certificate authority.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="padding: 2rem; text-align: center">
|
<div style="padding: 2rem; text-align: center">
|
||||||
<a
|
<a
|
||||||
id="cert"
|
id="cert"
|
||||||
download="embassy.crt"
|
[download]="crtName"
|
||||||
style="
|
style="
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1em 1.2em;
|
padding: 1em 1.2em;
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'download-doc',
|
selector: 'download-doc',
|
||||||
templateUrl: 'download-doc.component.html',
|
templateUrl: 'download-doc.component.html',
|
||||||
})
|
})
|
||||||
export class DownloadDocComponent {}
|
export class DownloadDocComponent {
|
||||||
|
@Input() lanAddress!: string
|
||||||
|
|
||||||
|
get crtName(): string {
|
||||||
|
const hostname = new URL(this.lanAddress).hostname
|
||||||
|
return `${hostname}.crt`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||