mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
🛠️ Adding BuildGuide branch for the ease of use (#252)
* Create BuildGuide.md * bug fixes * Update BuildGuide.md * Update make_image.sh * Update BuildGuide.md * Update make_image.sh additional improvements and "done" message added. Thanks @k0gen! * Update BuildGuide.md Added intro notes and made minor adjustments to the guide. * Update setup.sh Required adjustments to prevent reboot when following BuildGuide.md * Update BuildGuide.md Improvements to final setup steps * bug fix additional improvements and "done" message added. Thanks @k0gen! * Update Makefile Changes to facilitate building process when using the BuildGuide * Update BuildGuide.md Avoiding manual changes to Makefile and cleaning up step 7 * Update BuildGuide.md Switching from sftp to cp for one line command simplification * Update BuildGuide.md Simplified method of transferring .img to desktop. Thanks @k0gen! * Update BuildGuide.md update to latest openssl https://www.openssl.org/news/openssl-1.1.1-notes.html * Update BuildGuide.md Simplified step 6 and added new required dependency * Update BuildGuide.md Added hint on how to check `agent` log * Update setup.sh Added missing dependency * Update BuildGuide.md Simplified step 6 * Simplifying Rust installation One line install, reboot is no longer needed. * make_image.sh +x Make it executable before running * Step no longer needed chmod +x done by Makefile * Update BuildGuide.md Added dependency for Rust setup * Adding BuildGuide branch for the ease of use * Forgot about the guide file :) * Update BuildGuide.md apt -y by default and some environment add-ons Co-authored-by: Tommy Smith <63304263+t0mmysm1th@users.noreply.github.com>
This commit is contained in:
175
BuildGuide.md
Normal file
175
BuildGuide.md
Normal file
@@ -0,0 +1,175 @@
|
||||
##### Initial Notes & Recommendations
|
||||
* Due to issues to cross-compile the image from a desktop, this guide will take you step-by-step through the process of compiling EmbassyOS directly on a Raspberry Pi 4 (4GB or 8GB)
|
||||
* This process will go faster if you have an SSD/NVMe USB drive available.
|
||||
* This build guide does **not** require a large microSD card, especially if your final build wil be used on an SSD/NVMe USB drive.
|
||||
* Basic know-how of linux commands and terminal use is recommended.
|
||||
* Follow the guide carefully and do not skip any steps.
|
||||
|
||||
# :hammer_and_wrench: Build Guide
|
||||
1. Flash [Raspberry Pi OS Lite](https://www.raspberrypi.org/software/operating-systems/) to a microSD and configure your raspi to boot from SSD/NVMe USB drive
|
||||
1. After flashing, create an empty text file called `ssh` in the `boot` partition of the microSD, then proceed with booting the raspi with the flashed microSD (check your router for the IP assigned to your raspi)
|
||||
1. Do the usual initial update/config
|
||||
```
|
||||
sudo apt update
|
||||
sudo raspi-config
|
||||
```
|
||||
1. Change `Advanced Options->Boot Order`
|
||||
1. Select `USB Boot` *(it will try to boot from microSD first if it's available)*
|
||||
1. Select `Finish`, then `Yes` to reboot
|
||||
1. After reboot, `sudo shutdown now` to power off the raspi and remove the microSD
|
||||
|
||||
2. Flash the *Raspi OS Lite* (from step 1) to your SSD/NVMe drive
|
||||
> :information_source: Don't worry about rootfs partition size (raspi will increase it for you on initial boot)
|
||||
|
||||
> :information_source: Every time you re-flash your SSD/NVMe you need to first boot with a microSD and set *Boot Order* again
|
||||
|
||||
1. Don't forget to create the empty `ssh` file
|
||||
1. Connect the drive (remember to remove the microSD) to the raspi and start it up
|
||||
1. Use `sudo raspi-config` to change the default password
|
||||
1. Optional: `sudo apt upgrade -y`
|
||||
1. Optional: `sudo nano /etc/apt/sources.list.d/vscode.list` comment the last line which contains `packages.microsoft.com`
|
||||
|
||||
3. Install GHC
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install -y ghc
|
||||
|
||||
#test:
|
||||
ghc --version
|
||||
|
||||
#example of output:
|
||||
The Glorious Glasgow Haskell Compilation System, version 8.4.4
|
||||
```
|
||||
|
||||
4. Compile Stack:
|
||||
1. Install Stack v2.1.3
|
||||
```
|
||||
cd ~/
|
||||
wget -qO- https://raw.githubusercontent.com/commercialhaskell/stack/v2.1.3/etc/scripts/get-stack.sh | sh
|
||||
|
||||
#test with
|
||||
stack --version
|
||||
|
||||
#example output:
|
||||
Version 2.1.3, Git revision 636e3a759d51127df2b62f90772def126cdf6d1f (7735 commits) arm hpack-0.31.2
|
||||
```
|
||||
|
||||
1. Use current Stack to compile Stack v2.5.1:
|
||||
```
|
||||
git clone --depth 1 --branch v2.5.1 https://github.com/commercialhaskell/stack.git
|
||||
cd stack
|
||||
sudo apt install -y screen
|
||||
screen
|
||||
```
|
||||
> :information_source: Build (>=3.5h total... We are using `screen` in case of session timeout issues)
|
||||
|
||||
> :memo: If you get disconected you can reattach last sesion again by executing `screen -r`
|
||||
```
|
||||
stack build --stack-yaml=stack-ghc-84.yaml --system-ghc
|
||||
|
||||
#Install
|
||||
stack install --stack-yaml=stack-ghc-84.yaml --system-ghc
|
||||
export PATH=~/.local/bin:$PATH
|
||||
```
|
||||
|
||||
5. Clone EmbassyOS & try to *make* the `agent`:
|
||||
1. First attempt
|
||||
> :information_source: The first time you run **make** you'll get an error
|
||||
|
||||
```
|
||||
sudo apt install -y llvm-9 libgmp-dev
|
||||
export PATH=/usr/lib/llvm-9/bin:$PATH
|
||||
cd ~/
|
||||
git clone https://github.com/Start9Labs/embassy-os.git
|
||||
cd embassy-os/
|
||||
make agent
|
||||
```
|
||||
> :memo: This will install ghc-8.10.2, then attempt to build but will give errors (in next steps we deal with errors)
|
||||
1. Confirm your cpu info
|
||||
```
|
||||
cat /proc/cpuinfo | grep Hardware
|
||||
```
|
||||
1. If your "Hardware" is [BCM2711](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md) then:
|
||||
1. Change `C compiler flags` to `-marm -mcpu=cortex-a72` in the GHC settings:
|
||||
```
|
||||
nano ~/.stack/programs/arm-linux/ghc-8.10.2/lib/ghc-8.10.2/settings
|
||||
```
|
||||
1. To prevent gcc errors we delete the `setup-exe-src` folder
|
||||
```
|
||||
rm -rf ~/.stack/setup-exe-src/
|
||||
```
|
||||
|
||||
6. Install requirements for step 7
|
||||
1. Install NVM
|
||||
```
|
||||
cd ~/ && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||
nvm --version
|
||||
```
|
||||
1. Install Node.js & NPM
|
||||
```
|
||||
nvm install node
|
||||
```
|
||||
1. Install Ionic CLI
|
||||
```
|
||||
npm install -g @ionic/cli
|
||||
```
|
||||
1. Install Dependencies
|
||||
```
|
||||
sudo apt-get install -y build-essential openssl libssl-dev libc6-dev clang libclang-dev libavahi-client-dev upx ca-certificates
|
||||
```
|
||||
1. Install Rust
|
||||
```
|
||||
cd ~/ && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o- | bash
|
||||
|
||||
#Choose option 1
|
||||
source $HOME/.cargo/env
|
||||
|
||||
#Check rust & cargo versions
|
||||
rustc --version
|
||||
cargo --version
|
||||
```
|
||||
|
||||
7. Finally, getting to build the **.img**
|
||||
1. At this stage you hava a working development environment to build your **embassy.img**.
|
||||
Before you do that you can choose to enable SSH login for user `pi` in case something will go wrong or just skip to the next step.
|
||||
```
|
||||
cd ~/embassy-os
|
||||
sed -e '/passwd -l pi/ s/^#*/#/' -i setup.sh
|
||||
```
|
||||
> :warning: Default password for user `pi` is `raspberry`, change it the next you login.
|
||||
1. Build the `embassy.img`
|
||||
```
|
||||
cd ~/embassy-os
|
||||
make
|
||||
|
||||
#Depending from your hadware this can take 1-2h+
|
||||
#Wait for the "DONE!" message and take note of your product_key
|
||||
exit
|
||||
```
|
||||
8. Flash the `embassy.img` to a microSD
|
||||
1. Copy `embassy.img` from the raspi to your PC with scp
|
||||
```
|
||||
scp pi@raspi_IP:~/embassy-os/embassy.img .
|
||||
```
|
||||
1. Connect to raspi again to do `sudo shutdown now`, after a complete shutdown disconnect SSD/NVMe drive
|
||||
1. Flash `embassy.img` to a microSD (do this before flashing to the SSD/NVMe, to be sure it works)
|
||||
|
||||
9. Prepare for initial setup
|
||||
1. Boot raspi using flashed microSD
|
||||
1. After a few minutes, the raspi should reboot itself and make it's first [sounds](#embassy-sounds-explained).
|
||||
> :information_source: If needed, you can check the `agent` log with: `journalctl -u agent -ef`
|
||||
1. Proceed with the [initial setup process of EmbassyOS](https://docs.start9labs.com/user-manual/initial-setup.html)
|
||||
1. If all went well you can safely flash `embassy.img` to an SSD/NVMe and repeat step 9
|
||||
|
||||
### Embassy sounds explained
|
||||
Sound :notes: | Indicating
|
||||
------- | --------
|
||||
Bep | Device is powering on
|
||||
Chime | Device is ready for setup
|
||||
Mario "Coin" | EmbassyOS has started
|
||||
Mario "Death" | Device is about to Shutdown/Reboot
|
||||
Mario "Power Up" | EmbassyOS update sequence
|
||||
Beethoven | Update failed :(
|
||||
34
Makefile
34
Makefile
@@ -1,3 +1,15 @@
|
||||
UNAME := $(shell uname -m)
|
||||
|
||||
EMBASSY_SRC := buster.img product_key appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr ui/www agent/dist/agent agent/config/agent.service lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline lifeline/lifeline.service setup.sh setup.service docker-daemon.json
|
||||
APPMGR_RELEASE_SRC := appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr
|
||||
LIFELINE_RELEASE_SRC := lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline
|
||||
|
||||
ifeq ($(UNAME), armv7l)
|
||||
EMBASSY_SRC := buster.img product_key appmgr/target/release/appmgr ui/www agent/dist/agent agent/config/agent.service lifeline/target/release/lifeline lifeline/lifeline.service setup.sh setup.service docker-daemon.json
|
||||
APPMGR_RELEASE_SRC := appmgr/target/release/appmgr
|
||||
LIFELINE_RELEASE_SRC := lifeline/target/release/lifeline
|
||||
endif
|
||||
|
||||
APPMGR_SRC := $(shell find appmgr/src) appmgr/Cargo.toml appmgr/Cargo.lock
|
||||
LIFELINE_SRC := $(shell find lifeline/src) lifeline/Cargo.toml lifeline/Cargo.lock
|
||||
AGENT_SRC := $(shell find agent/src) $(shell find agent/config) agent/stack.yaml agent/package.yaml agent/build.sh
|
||||
@@ -13,7 +25,8 @@ UI_SRC := $(shell find ui/src) \
|
||||
|
||||
all: embassy.img
|
||||
|
||||
embassy.img: buster.img product_key appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr ui/www agent/dist/agent agent/config/agent.service lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline lifeline/lifeline.service setup.sh setup.service docker-daemon.json
|
||||
embassy.img: $(EMBASSY_SRC)
|
||||
chmod +x make_image.sh
|
||||
sudo ./make_image.sh
|
||||
|
||||
buster.img:
|
||||
@@ -26,11 +39,16 @@ product_key:
|
||||
echo "X\c" > product_key
|
||||
cat /dev/random | base32 | head -c11 | tr '[:upper:]' '[:lower:]' >> product_key
|
||||
|
||||
appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr: $(APPMGR_SRC)
|
||||
$(APPMGR_RELEASE_SRC): $(APPMGR_SRC)
|
||||
ifeq ($(UNAME), armv7l)
|
||||
cd appmgr && cargo update && cargo build --release --features=production
|
||||
arm-linux-gnueabihf-strip appmgr/target/release/appmgr
|
||||
else
|
||||
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)":/home/rust/src start9/rust-arm-cross:latest sh -c "(cd appmgr && cargo build --release --features=production)"
|
||||
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)":/home/rust/src start9/rust-arm-cross:latest arm-linux-gnueabi-strip appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr
|
||||
endif
|
||||
|
||||
appmgr: appmgr/target/armv7-unknown-linux-gnueabihf/release/appmgr
|
||||
appmgr: $(APPMGR_RELEASE_SRC)
|
||||
|
||||
agent/dist/agent: $(AGENT_SRC)
|
||||
(cd agent && ./build.sh)
|
||||
@@ -45,9 +63,13 @@ ui/www: $(UI_SRC) ui/node_modules
|
||||
|
||||
ui: ui/www
|
||||
|
||||
lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline: $(LIFELINE_SRC)
|
||||
$(LIFELINE_RELEASE_SRC): $(LIFELINE_SRC)
|
||||
ifeq ($(UNAME), armv7l)
|
||||
cd lifeline && cargo build --release
|
||||
arm-linux-gnueabihf-strip lifeline/target/release/lifeline
|
||||
else
|
||||
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)":/home/rust/src start9/rust-arm-cross:latest sh -c "(cd lifeline && cargo build --release)"
|
||||
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)":/home/rust/src start9/rust-arm-cross:latest arm-linux-gnueabi-strip lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline
|
||||
endif
|
||||
|
||||
lifeline: lifeline/target/armv7-unknown-linux-gnueabihf/release/lifeline
|
||||
|
||||
lifeline: $(LIFELINE_RELEASE_SRC)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
arch=$(uname -m)
|
||||
if [[ $arch == armv7l ]]; then
|
||||
dev_target="target"
|
||||
else
|
||||
dev_target="target/armv7-unknown-linux-musleabihf"
|
||||
fi
|
||||
mv buster.img embassy.img
|
||||
product_key=$(cat product_key)
|
||||
loopdev=$(losetup -f -P embassy.img --show)
|
||||
@@ -9,6 +14,12 @@ mkdir -p "${root_mountpoint}"
|
||||
mkdir -p "${boot_mountpoint}"
|
||||
mount "${loopdev}p2" "${root_mountpoint}"
|
||||
mount "${loopdev}p1" "${boot_mountpoint}"
|
||||
mkdir -p "${root_mountpoint}/root/agent"
|
||||
mkdir -p "${root_mountpoint}/etc/docker"
|
||||
mkdir -p "${root_mountpoint}/home/pi/.ssh"
|
||||
echo -n "" > "${root_mountpoint}/home/pi/.ssh/authorized_keys"
|
||||
chown -R pi:pi "${root_mountpoint}/home/pi/.ssh"
|
||||
echo -n "" > "${boot_mountpoint}/ssh"
|
||||
echo "${product_key}" > "${root_mountpoint}/root/agent/product_key"
|
||||
echo -n "start9-" > "${root_mountpoint}/etc/hostname"
|
||||
echo -n "${product_key}" | shasum -t -a 256 | cut -c1-8 >> "${root_mountpoint}/etc/hostname"
|
||||
@@ -18,20 +29,23 @@ echo -n "${product_key}" | shasum -t -a 256 | cut -c1-8 >> "${root_mountpoint}/e
|
||||
mv "${root_mountpoint}/etc/hosts.tmp" "${root_mountpoint}/etc/hosts"
|
||||
cp agent/dist/agent "${root_mountpoint}/usr/local/bin/agent"
|
||||
chmod 700 "${root_mountpoint}/usr/local/bin/agent"
|
||||
cp appmgr/target/armv7-unknown-linux-musleabihf/release/appmgr "${root_mountpoint}/usr/local/bin/appmgr"
|
||||
cp "appmgr/${dev_target}/release/appmgr" "${root_mountpoint}/usr/local/bin/appmgr"
|
||||
chmod 700 "${root_mountpoint}/usr/local/bin/appmgr"
|
||||
cp lifeline/target/armv7-unknown-linux-musleabihf/release/lifeline "${root_mountpoint}/usr/local/bin/lifeline"
|
||||
cp "lifeline/${dev_target}/release/lifeline" "${root_mountpoint}/usr/local/bin/lifeline"
|
||||
chmod 700 "${root_mountpoint}/usr/local/bin/lifeline"
|
||||
cp docker-daemon.json "${root_mountpoint}/etc/docker/daemon.json"
|
||||
cp setup.sh "${root_mountpoint}/root/setup.sh"
|
||||
chmod 700 "${root_mountpoint}/root/setup.sh"
|
||||
cp setup.service /etc/systemd/system/setup.service
|
||||
cp lifeline/lifeline.service /etc/systemd/system/lifeline.service
|
||||
cp agent/config/agent.service /etc/systemd/system/agent.service
|
||||
cat "${boot_mountpoint}/config.txt" | grep -v "dtoverlay=pwm-2chan" > "${boot_mountpoint}/config.txt.tmp"
|
||||
cp setup.service "${root_mountpoint}/etc/systemd/system/setup.service"
|
||||
ln -s /etc/systemd/system/setup.service "${root_mountpoint}/etc/systemd/system/getty.target.wants/setup.service"
|
||||
cp lifeline/lifeline.service "${root_mountpoint}/etc/systemd/system/lifeline.service"
|
||||
cp agent/config/agent.service "${root_mountpoint}/etc/systemd/system/agent.service"
|
||||
cat "${boot_mountpoint}/config.txt" | grep -v "dtoverlay=" > "${boot_mountpoint}/config.txt.tmp"
|
||||
echo "dtoverlay=pwm-2chan" >> "${boot_mountpoint}/config.txt.tmp"
|
||||
mv "${boot_mountpoint}/config.txt.tmp" "${boot_mountpoint}/config.txt"
|
||||
umount "${root_mountpoint}"
|
||||
rm -r "${root_mountpoint}"
|
||||
umount "${boot_mountpoint}"
|
||||
rm -r "${boot_mountpoint}"
|
||||
losetup -d ${loopdev}
|
||||
losetup -d ${loopdev}
|
||||
echo "DONE! Here is your EmbassyOS key: ${product_key}"
|
||||
@@ -1,10 +1,15 @@
|
||||
[Unit]
|
||||
Description=Boot process for system setup.
|
||||
After=rc-local.service
|
||||
Before=getty.target
|
||||
ConditionFileNotEmpty=/root/setup.sh
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/root/setup.sh
|
||||
ExecStartPost=/root/setup-s2.sh
|
||||
RemainAfterExit=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=basic.target
|
||||
|
||||
|
||||
32
setup.sh
32
setup.sh
@@ -1,15 +1,26 @@
|
||||
#!/bin/bash
|
||||
apt update
|
||||
apt install -y libsecp256k1-0
|
||||
apt install -y tor
|
||||
apt install -y docker.io
|
||||
apt install -y iotop
|
||||
apt install -y bmon
|
||||
apt autoremove -y
|
||||
mkdir -p /root/volumes
|
||||
mkdir -p /root/tmp/appmgr
|
||||
mkdir -p /root/agent
|
||||
mkdir -p /root/appmgr/tor
|
||||
apt-get update -y
|
||||
apt-get install -y tor
|
||||
apt-get install -y iotop
|
||||
apt-get install -y bmon
|
||||
apt-get install -y libavahi-client3
|
||||
apt-get install -y libsecp256k1-0
|
||||
apt-get install -y docker.io needrestart-
|
||||
mv /root/setup.sh /root/setup-s1.sh.done
|
||||
cat <<EOT >> /root/setup-s2.sh
|
||||
#!/bin/bash
|
||||
apt-get update -y
|
||||
apt-get install -y tor
|
||||
apt-get install -y iotop
|
||||
apt-get install -y bmon
|
||||
apt-get install -y libavahi-client3
|
||||
apt-get install -y libsecp256k1-0
|
||||
apt-get install -y docker.io needrestart-
|
||||
apt-get autoremove -y
|
||||
systemctl enable lifeline
|
||||
systemctl enable agent
|
||||
systemctl enable ssh
|
||||
@@ -17,5 +28,8 @@ systemctl enable avahi-daemon
|
||||
passwd -l root
|
||||
passwd -l pi
|
||||
sync
|
||||
systemctl disable setup.service
|
||||
reboot
|
||||
systemctl disable setup
|
||||
mv /root/setup-s2.sh /root/setup-s2.sh.done
|
||||
reboot
|
||||
EOT
|
||||
chmod +x /root/setup-s2.sh
|
||||
Reference in New Issue
Block a user