mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Feature/debian runtime (#2600)
* wip * fix build * run debian update in systemd-nspawn * bugfix * fix build * free up space before image build
This commit is contained in:
8
.github/workflows/startos-iso.yaml
vendored
8
.github/workflows/startos-iso.yaml
vendored
@@ -82,8 +82,8 @@ jobs:
|
|||||||
- name: Set up docker QEMU
|
- name: Set up docker QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up system QEMU
|
- name: Set up system dependencies
|
||||||
run: sudo apt-get update && sudo apt-get install -y qemu-user-static
|
run: sudo apt-get update && sudo apt-get install -y qemu-user-static systemd-container
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
@@ -140,6 +140,10 @@ jobs:
|
|||||||
}')[matrix.platform]
|
}')[matrix.platform]
|
||||||
}}
|
}}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Free space
|
||||||
|
run: rm -rf /opt/hostedtoolcache*
|
||||||
|
if: ${{ github.event.inputs.runner != 'fast' }}
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -26,7 +26,7 @@ PATCH_DB_CLIENT_SRC := $(shell git ls-files --recurse-submodules patch-db/client
|
|||||||
GZIP_BIN := $(shell which pigz || which gzip)
|
GZIP_BIN := $(shell which pigz || which gzip)
|
||||||
TAR_BIN := $(shell which gtar || which tar)
|
TAR_BIN := $(shell which gtar || which tar)
|
||||||
COMPILED_TARGETS := $(BINS) system-images/compat/docker-images/$(ARCH).tar system-images/utils/docker-images/$(ARCH).tar system-images/binfmt/docker-images/$(ARCH).tar container-runtime/rootfs.$(ARCH).squashfs
|
COMPILED_TARGETS := $(BINS) system-images/compat/docker-images/$(ARCH).tar system-images/utils/docker-images/$(ARCH).tar system-images/binfmt/docker-images/$(ARCH).tar container-runtime/rootfs.$(ARCH).squashfs
|
||||||
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; fi) $(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; fi') $(PLATFORM_FILE) sdk/lib/test
|
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; fi) $(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; fi') $(PLATFORM_FILE)
|
||||||
|
|
||||||
ifeq ($(REMOTE),)
|
ifeq ($(REMOTE),)
|
||||||
mkdir = mkdir -p $1
|
mkdir = mkdir -p $1
|
||||||
@@ -103,7 +103,7 @@ deb: results/$(BASENAME).deb
|
|||||||
debian/control: build/lib/depends build/lib/conflicts
|
debian/control: build/lib/depends build/lib/conflicts
|
||||||
./debuild/control.sh
|
./debuild/control.sh
|
||||||
|
|
||||||
results/$(BASENAME).deb: dpkg-build.sh $(DEBIAN_SRC) $(VERSION_FILE) $(PLATFORM_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE)
|
results/$(BASENAME).deb: dpkg-build.sh $(DEBIAN_SRC) $(ALL_TARGETS)
|
||||||
PLATFORM=$(PLATFORM) ./dpkg-build.sh
|
PLATFORM=$(PLATFORM) ./dpkg-build.sh
|
||||||
|
|
||||||
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)
|
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)
|
||||||
@@ -173,7 +173,7 @@ emulate-reflash: $(ALL_TARGETS)
|
|||||||
upload-ota: results/$(BASENAME).squashfs
|
upload-ota: results/$(BASENAME).squashfs
|
||||||
TARGET=$(TARGET) KEY=$(KEY) ./upload-ota.sh
|
TARGET=$(TARGET) KEY=$(KEY) ./upload-ota.sh
|
||||||
|
|
||||||
container-runtime/alpine.$(ARCH).squashfs:
|
container-runtime/debian.$(ARCH).squashfs:
|
||||||
ARCH=$(ARCH) ./container-runtime/download-base-image.sh
|
ARCH=$(ARCH) ./container-runtime/download-base-image.sh
|
||||||
|
|
||||||
container-runtime/node_modules: container-runtime/package.json container-runtime/package-lock.json sdk/dist
|
container-runtime/node_modules: container-runtime/package.json container-runtime/package-lock.json sdk/dist
|
||||||
@@ -197,7 +197,7 @@ container-runtime/dist/node_modules container-runtime/dist/package.json containe
|
|||||||
./container-runtime/install-dist-deps.sh
|
./container-runtime/install-dist-deps.sh
|
||||||
touch container-runtime/dist/node_modules
|
touch container-runtime/dist/node_modules
|
||||||
|
|
||||||
container-runtime/rootfs.$(ARCH).squashfs: container-runtime/alpine.$(ARCH).squashfs container-runtime/containerRuntime.rc container-runtime/update-image.sh container-runtime/dist/index.js container-runtime/dist/node_modules core/target/$(ARCH)-unknown-linux-musl/release/containerbox | sudo
|
container-runtime/rootfs.$(ARCH).squashfs: container-runtime/debian.$(ARCH).squashfs container-runtime/container-runtime.service container-runtime/update-image.sh container-runtime/deb-install.sh container-runtime/dist/index.js container-runtime/dist/node_modules core/target/$(ARCH)-unknown-linux-musl/release/containerbox | sudo
|
||||||
ARCH=$(ARCH) ./container-runtime/update-image.sh
|
ARCH=$(ARCH) ./container-runtime/update-image.sh
|
||||||
|
|
||||||
build/lib/depends build/lib/conflicts: build/dpkg-deps/*
|
build/lib/depends build/lib/conflicts: build/dpkg-deps/*
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
FROM node:18-alpine
|
|
||||||
|
|
||||||
ADD ./startInit.js /usr/local/lib/startInit.js
|
|
||||||
ADD ./entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
||||||
9
container-runtime/container-runtime.service
Normal file
9
container-runtime/container-runtime.service
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=StartOS Container Runtime
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/bin/node --experimental-detect-module --unhandled-rejections=warn /usr/lib/startos/init/index.js
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#!/sbin/openrc-run
|
|
||||||
|
|
||||||
name=containerRuntime
|
|
||||||
#cfgfile="/etc/containerRuntime/containerRuntime.conf"
|
|
||||||
command="/usr/bin/node"
|
|
||||||
command_args="--experimental-detect-module --unhandled-rejections=warn /usr/lib/startos/init/index.js"
|
|
||||||
pidfile="/run/containerRuntime.pid"
|
|
||||||
command_background="yes"
|
|
||||||
output_log="/var/log/containerRuntime.log"
|
|
||||||
error_log="/var/log/containerRuntime.err"
|
|
||||||
19
container-runtime/deb-install.sh
Normal file
19
container-runtime/deb-install.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p /run/systemd/resolve
|
||||||
|
echo "nameserver 8.8.8.8" > /run/systemd/resolve/stub-resolv.conf
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl rsync
|
||||||
|
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||||
|
source ~/.bashrc
|
||||||
|
nvm install 20
|
||||||
|
|
||||||
|
ln -s $(which node) /usr/bin/node
|
||||||
|
|
||||||
|
systemctl enable container-runtime.service
|
||||||
|
|
||||||
|
rm -rf /run/systemd
|
||||||
@@ -4,8 +4,8 @@ cd "$(dirname "${BASH_SOURCE[0]}")"
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
DISTRO=alpine
|
DISTRO=debian
|
||||||
VERSION=3.19
|
VERSION=bookworm
|
||||||
ARCH=${ARCH:-$(uname -m)}
|
ARCH=${ARCH:-$(uname -m)}
|
||||||
FLAVOR=default
|
FLAVOR=default
|
||||||
|
|
||||||
@@ -16,4 +16,4 @@ elif [ "$_ARCH" = "aarch64" ]; then
|
|||||||
_ARCH=arm64
|
_ARCH=arm64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
curl https://images.linuxcontainers.org/$(curl --silent https://images.linuxcontainers.org/meta/1.0/index-system | grep "^$DISTRO;$VERSION;$_ARCH;$FLAVOR;" | head -n1 | sed 's/^.*;//g')/rootfs.squashfs --output alpine.${ARCH}.squashfs
|
curl https://images.linuxcontainers.org/$(curl --silent https://images.linuxcontainers.org/meta/1.0/index-system | grep "^$DISTRO;$VERSION;$_ARCH;$FLAVOR;" | head -n1 | sed 's/^.*;//g')/rootfs.squashfs --output debian.${ARCH}.squashfs
|
||||||
@@ -40,6 +40,7 @@ export class MainLoop {
|
|||||||
...system.manifest.main.args,
|
...system.manifest.main.args,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
await this.setupInterfaces(effects)
|
||||||
await effects.setMainStatus({ status: "running" })
|
await effects.setMainStatus({ status: "running" })
|
||||||
const jsMain = (this.system.moduleCode as any)?.jsMain
|
const jsMain = (this.system.moduleCode as any)?.jsMain
|
||||||
const dockerProcedureContainer = await DockerProcedureContainer.of(
|
const dockerProcedureContainer = await DockerProcedureContainer.of(
|
||||||
@@ -69,6 +70,52 @@ export class MainLoop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async setupInterfaces(effects: HostSystemStartOs) {
|
||||||
|
for (const interfaceId in this.system.manifest.interfaces) {
|
||||||
|
const iface = this.system.manifest.interfaces[interfaceId]
|
||||||
|
const internalPorts = new Set<number>()
|
||||||
|
for (const port of Object.values(
|
||||||
|
iface["tor-config"]?.["port-mapping"] || {},
|
||||||
|
)) {
|
||||||
|
internalPorts.add(parseInt(port))
|
||||||
|
}
|
||||||
|
for (const port of Object.values(iface["lan-config"] || {})) {
|
||||||
|
internalPorts.add(port.internal)
|
||||||
|
}
|
||||||
|
for (const internalPort of internalPorts) {
|
||||||
|
const torConf = Object.entries(
|
||||||
|
iface["tor-config"]?.["port-mapping"] || {},
|
||||||
|
)
|
||||||
|
.map(([external, internal]) => ({
|
||||||
|
internal: parseInt(internal),
|
||||||
|
external: parseInt(external),
|
||||||
|
}))
|
||||||
|
.find((conf) => conf.internal == internalPort)
|
||||||
|
const lanConf = Object.entries(iface["lan-config"] || {})
|
||||||
|
.map(([external, conf]) => ({
|
||||||
|
external: parseInt(external),
|
||||||
|
...conf,
|
||||||
|
}))
|
||||||
|
.find((conf) => conf.internal == internalPort)
|
||||||
|
await effects.bind({
|
||||||
|
kind: "multi",
|
||||||
|
id: interfaceId,
|
||||||
|
internalPort,
|
||||||
|
preferredExternalPort: torConf?.external || internalPort,
|
||||||
|
scheme: "http",
|
||||||
|
secure: null,
|
||||||
|
addSsl: lanConf?.ssl
|
||||||
|
? {
|
||||||
|
scheme: "https",
|
||||||
|
preferredExternalPort: lanConf.external,
|
||||||
|
alpn: { specified: ["http/1.1"] },
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async clean(options?: { timeout?: number }) {
|
public async clean(options?: { timeout?: number }) {
|
||||||
const { mainEvent, healthLoops } = this
|
const { mainEvent, healthLoops } = this
|
||||||
const main = await mainEvent
|
const main = await mainEvent
|
||||||
|
|||||||
@@ -68,13 +68,24 @@ export const matchManifest = object(
|
|||||||
volumes: dictionary([string, matchVolume]),
|
volumes: dictionary([string, matchVolume]),
|
||||||
interfaces: dictionary([
|
interfaces: dictionary([
|
||||||
string,
|
string,
|
||||||
object({
|
object(
|
||||||
name: string,
|
{
|
||||||
"tor-config": object({}),
|
name: string,
|
||||||
"lan-config": object({}),
|
"tor-config": object({
|
||||||
ui: boolean,
|
"port-mapping": dictionary([string, string]),
|
||||||
protocols: array(string),
|
}),
|
||||||
}),
|
"lan-config": dictionary([
|
||||||
|
string,
|
||||||
|
object({
|
||||||
|
ssl: boolean,
|
||||||
|
internal: number,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
ui: boolean,
|
||||||
|
protocols: array(string),
|
||||||
|
},
|
||||||
|
["lan-config", "tor-config"],
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
backup: object({
|
backup: object({
|
||||||
create: matchProcedure,
|
create: matchProcedure,
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ cd "$(dirname "${BASH_SOURCE[0]}")"
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if mountpoint tmp/combined; then sudo umount -R tmp/combined; fi
|
||||||
|
|
||||||
if mountpoint tmp/combined; then sudo umount tmp/combined; fi
|
|
||||||
if mountpoint tmp/lower; then sudo umount tmp/lower; fi
|
if mountpoint tmp/lower; then sudo umount tmp/lower; fi
|
||||||
|
sudo rm -rf tmp
|
||||||
mkdir -p tmp/lower tmp/upper tmp/work tmp/combined
|
mkdir -p tmp/lower tmp/upper tmp/work tmp/combined
|
||||||
sudo mount alpine.${ARCH}.squashfs tmp/lower
|
sudo mount debian.${ARCH}.squashfs tmp/lower
|
||||||
sudo mount -t overlay -olowerdir=tmp/lower,upperdir=tmp/upper,workdir=tmp/work overlay tmp/combined
|
sudo mount -t overlay -olowerdir=tmp/lower,upperdir=tmp/upper,workdir=tmp/work overlay tmp/combined
|
||||||
|
|
||||||
QEMU=
|
QEMU=
|
||||||
@@ -18,21 +17,21 @@ if [ "$ARCH" != "$(uname -m)" ]; then
|
|||||||
sudo cp $(which qemu-$ARCH-static) tmp/combined${QEMU}
|
sudo cp $(which qemu-$ARCH-static) tmp/combined${QEMU}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "nameserver 8.8.8.8" | sudo tee tmp/combined/etc/resolv.conf # TODO - delegate to host resolver?
|
|
||||||
sudo chroot tmp/combined $QEMU /sbin/apk add nodejs rsync
|
|
||||||
sudo mkdir -p tmp/combined/usr/lib/startos/
|
sudo mkdir -p tmp/combined/usr/lib/startos/
|
||||||
sudo rsync -a --copy-unsafe-links dist/ tmp/combined/usr/lib/startos/init/
|
sudo rsync -a --copy-unsafe-links dist/ tmp/combined/usr/lib/startos/init/
|
||||||
sudo cp containerRuntime.rc tmp/combined/etc/init.d/containerRuntime
|
sudo chown -R 0:0 tmp/combined/usr/lib/startos/
|
||||||
|
sudo cp container-runtime.service tmp/combined/lib/systemd/system/container-runtime.service
|
||||||
|
sudo chown 0:0 tmp/combined/lib/systemd/system/container-runtime.service
|
||||||
sudo cp ../core/target/$ARCH-unknown-linux-musl/release/containerbox tmp/combined/usr/bin/start-cli
|
sudo cp ../core/target/$ARCH-unknown-linux-musl/release/containerbox tmp/combined/usr/bin/start-cli
|
||||||
sudo chmod +x tmp/combined/etc/init.d/containerRuntime
|
sudo chown 0:0 tmp/combined/usr/bin/start-cli
|
||||||
sudo chroot tmp/combined $QEMU /sbin/rc-update add containerRuntime default
|
echo container-runtime | sha256sum | head -c 32 | cat - <(echo) | sudo tee tmp/combined/etc/machine-id
|
||||||
|
cat deb-install.sh | sudo systemd-nspawn --console=pipe -D tmp/combined $QEMU /bin/bash
|
||||||
|
sudo truncate -s 0 tmp/combined/etc/machine-id
|
||||||
|
|
||||||
if [ -n "$QEMU" ]; then
|
if [ -n "$QEMU" ]; then
|
||||||
sudo rm tmp/combined${QEMU}
|
sudo rm tmp/combined${QEMU}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo truncate -s 0 tmp/combined/etc/resolv.conf
|
|
||||||
sudo chown -R 0:0 tmp/combined
|
|
||||||
rm -f rootfs.${ARCH}.squashfs
|
rm -f rootfs.${ARCH}.squashfs
|
||||||
mkdir -p ../build/lib/container-runtime
|
mkdir -p ../build/lib/container-runtime
|
||||||
sudo mksquashfs tmp/combined rootfs.${ARCH}.squashfs
|
sudo mksquashfs tmp/combined rootfs.${ARCH}.squashfs
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ async fn get_service_port_forward(
|
|||||||
data: GetServicePortForwardParams,
|
data: GetServicePortForwardParams,
|
||||||
) -> Result<u16, Error> {
|
) -> Result<u16, Error> {
|
||||||
let internal_port = data.internal_port as u16;
|
let internal_port = data.internal_port as u16;
|
||||||
|
|
||||||
let context = context.deref()?;
|
let context = context.deref()?;
|
||||||
let net_service = context.persistent_container.net_service.lock().await;
|
let net_service = context.persistent_container.net_service.lock().await;
|
||||||
net_service.get_ext_port(data.host_id, internal_port)
|
net_service.get_ext_port(data.host_id, internal_port)
|
||||||
@@ -446,8 +446,18 @@ struct BindParams {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
options: BindOptions,
|
options: BindOptions,
|
||||||
}
|
}
|
||||||
async fn bind(_: AnyContext, BindParams { .. }: BindParams) -> Result<Value, Error> {
|
async fn bind(
|
||||||
todo!()
|
context: EffectContext,
|
||||||
|
BindParams {
|
||||||
|
kind,
|
||||||
|
id,
|
||||||
|
internal_port,
|
||||||
|
options,
|
||||||
|
}: BindParams,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let ctx = context.deref()?;
|
||||||
|
let mut svc = ctx.persistent_container.net_service.lock().await;
|
||||||
|
svc.bind(kind, id, internal_port, options).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ fi
|
|||||||
rm -rf dpkg-workdir/$BASENAME
|
rm -rf dpkg-workdir/$BASENAME
|
||||||
mkdir -p dpkg-workdir/$BASENAME
|
mkdir -p dpkg-workdir/$BASENAME
|
||||||
|
|
||||||
|
make
|
||||||
make install DESTDIR=dpkg-workdir/$BASENAME
|
make install DESTDIR=dpkg-workdir/$BASENAME
|
||||||
|
|
||||||
DEPENDS=$(cat dpkg-workdir/$BASENAME/usr/lib/startos/depends | tr $'\n' ',' | sed 's/,,\+/,/g' | sed 's/,$//')
|
DEPENDS=$(cat dpkg-workdir/$BASENAME/usr/lib/startos/depends | tr $'\n' ',' | sed 's/,,\+/,/g' | sed 's/,$//')
|
||||||
|
|||||||
2
patch-db
2
patch-db
Submodule patch-db updated: 3dc11afd46...e4a3f7b577
Reference in New Issue
Block a user