mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
misc fixes (#2892)
* use docker for build steps that require linux when not on linux * use fuse for overlay * quiet mountpoint * node 22 * misc fixes * make shasum more compliant * optimize download-base-image.sh with cleaner url handling and checksum verification * fix script * fixes #2900 * bump node and npm versions in web readme * Minor pl.ts fixes * fixes in response to synapse issues * beta.8 * update ts-matches * beta.11 * pl.ts finetuning --------- Co-authored-by: Mariusz Kogen <k0gen@pm.me> Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
@@ -25,9 +25,9 @@ docker buildx create --use
|
|||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # proceed with default installation
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # proceed with default installation
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
|
||||||
source ~/.bashrc
|
source ~/.bashrc
|
||||||
nvm install 20
|
nvm install 22
|
||||||
nvm use 20
|
nvm use 22
|
||||||
nvm alias default 20 # this prevents your machine from reverting back to another version
|
nvm alias default 22 # this prevents your machine from reverting back to another version
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cloning the repository
|
## Cloning the repository
|
||||||
|
|||||||
15
Makefile
15
Makefile
@@ -49,7 +49,7 @@ endif
|
|||||||
|
|
||||||
.DELETE_ON_ERROR:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
.PHONY: all metadata install clean format cli uis ui reflash deb $(IMAGE_TYPE) squashfs sudo wormhole wormhole-deb test test-core test-sdk test-container-runtime registry
|
.PHONY: all metadata install clean format cli uis ui reflash deb $(IMAGE_TYPE) squashfs wormhole wormhole-deb test test-core test-sdk test-container-runtime registry
|
||||||
|
|
||||||
all: $(ALL_TARGETS)
|
all: $(ALL_TARGETS)
|
||||||
|
|
||||||
@@ -58,9 +58,6 @@ touch:
|
|||||||
|
|
||||||
metadata: $(VERSION_FILE) $(PLATFORM_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE)
|
metadata: $(VERSION_FILE) $(PLATFORM_FILE) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE)
|
||||||
|
|
||||||
sudo:
|
|
||||||
sudo true
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f system-images/**/*.tar
|
rm -f system-images/**/*.tar
|
||||||
rm -rf system-images/compat/target
|
rm -rf system-images/compat/target
|
||||||
@@ -116,14 +113,14 @@ debian/control: build/lib/depends build/lib/conflicts
|
|||||||
./debuild/control.sh
|
./debuild/control.sh
|
||||||
|
|
||||||
results/$(BASENAME).deb: dpkg-build.sh $(DEBIAN_SRC) $(ALL_TARGETS)
|
results/$(BASENAME).deb: dpkg-build.sh $(DEBIAN_SRC) $(ALL_TARGETS)
|
||||||
PLATFORM=$(PLATFORM) ./dpkg-build.sh
|
PLATFORM=$(PLATFORM) REQUIRES=debian ./build/os-compat/run-compat.sh ./dpkg-build.sh
|
||||||
|
|
||||||
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)
|
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)
|
||||||
|
|
||||||
squashfs: results/$(BASENAME).squashfs
|
squashfs: results/$(BASENAME).squashfs
|
||||||
|
|
||||||
results/$(BASENAME).$(IMAGE_TYPE) results/$(BASENAME).squashfs: $(IMAGE_RECIPE_SRC) results/$(BASENAME).deb
|
results/$(BASENAME).$(IMAGE_TYPE) results/$(BASENAME).squashfs: $(IMAGE_RECIPE_SRC) results/$(BASENAME).deb
|
||||||
./image-recipe/run-local-build.sh "results/$(BASENAME).deb"
|
REQUIRES=debian ./build/os-compat/run-compat.sh ./image-recipe/run-local-build.sh "results/$(BASENAME).deb"
|
||||||
|
|
||||||
# For creating os images. DO NOT USE
|
# For creating os images. DO NOT USE
|
||||||
install: $(ALL_TARGETS)
|
install: $(ALL_TARGETS)
|
||||||
@@ -222,7 +219,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/debian.$(ARCH).squashfs:
|
container-runtime/debian.$(ARCH).squashfs: ./container-runtime/download-base-image.sh
|
||||||
ARCH=$(ARCH) ./container-runtime/download-base-image.sh
|
ARCH=$(ARCH) ./container-runtime/download-base-image.sh
|
||||||
|
|
||||||
container-runtime/node_modules/.package-lock.json: container-runtime/package.json container-runtime/package-lock.json sdk/dist/package.json
|
container-runtime/node_modules/.package-lock.json: container-runtime/package.json container-runtime/package-lock.json sdk/dist/package.json
|
||||||
@@ -254,8 +251,8 @@ container-runtime/dist/node_modules/.package-lock.json container-runtime/dist/pa
|
|||||||
./container-runtime/install-dist-deps.sh
|
./container-runtime/install-dist-deps.sh
|
||||||
touch container-runtime/dist/node_modules/.package-lock.json
|
touch container-runtime/dist/node_modules/.package-lock.json
|
||||||
|
|
||||||
container-runtime/rootfs.$(ARCH).squashfs: container-runtime/debian.$(ARCH).squashfs container-runtime/container-runtime.service container-runtime/update-image.sh container-runtime/deb-install.sh container-runtime/dist/index.js container-runtime/dist/node_modules/.package-lock.json core/target/$(ARCH)-unknown-linux-musl/release/containerbox | 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/.package-lock.json core/target/$(ARCH)-unknown-linux-musl/release/containerbox
|
||||||
ARCH=$(ARCH) ./container-runtime/update-image.sh
|
ARCH=$(ARCH) REQUIRES=linux ./build/os-compat/run-compat.sh ./container-runtime/update-image.sh
|
||||||
|
|
||||||
build/lib/depends build/lib/conflicts: build/dpkg-deps/*
|
build/lib/depends build/lib/conflicts: build/dpkg-deps/*
|
||||||
build/dpkg-deps/generate.sh
|
build/dpkg-deps/generate.sh
|
||||||
|
|||||||
56
build/os-compat/buildenv.Dockerfile
Normal file
56
build/os-compat/buildenv.Dockerfile
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
FROM debian:bookworm
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gpg \
|
||||||
|
build-essential \
|
||||||
|
sed \
|
||||||
|
grep \
|
||||||
|
gawk \
|
||||||
|
jq \
|
||||||
|
gzip \
|
||||||
|
brotli \
|
||||||
|
qemu-user-static \
|
||||||
|
binfmt-support \
|
||||||
|
squashfs-tools \
|
||||||
|
git \
|
||||||
|
debspawn \
|
||||||
|
rsync \
|
||||||
|
b3sum \
|
||||||
|
fuse-overlayfs \
|
||||||
|
sudo \
|
||||||
|
systemd \
|
||||||
|
systemd-container \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
dbus-user-session
|
||||||
|
|
||||||
|
RUN systemctl mask \
|
||||||
|
systemd-firstboot.service \
|
||||||
|
systemd-udevd.service \
|
||||||
|
getty@tty1.service \
|
||||||
|
console-getty.service
|
||||||
|
|
||||||
|
RUN git config --global --add safe.directory /root/start-os
|
||||||
|
|
||||||
|
RUN mkdir -p /etc/debspawn && \
|
||||||
|
echo "AllowUnsafePermissions=true" > /etc/debspawn/global.toml
|
||||||
|
|
||||||
|
ENV NVM_DIR=~/.nvm
|
||||||
|
ENV NODE_VERSION=22
|
||||||
|
RUN mkdir -p $NVM_DIR && \
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash && \
|
||||||
|
. $NVM_DIR/nvm.sh \
|
||||||
|
nvm install $NODE_VERSION && \
|
||||||
|
nvm use $NODE_VERSION && \
|
||||||
|
nvm alias default $NODE_VERSION && \
|
||||||
|
ln -s $(which node) /usr/bin/node && \
|
||||||
|
ln -s $(which npm) /usr/bin/npm
|
||||||
|
|
||||||
|
RUN mkdir -p /root/start-os
|
||||||
|
WORKDIR /root/start-os
|
||||||
|
|
||||||
|
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
|
ENTRYPOINT [ "/docker-entrypoint.sh" ]
|
||||||
3
build/os-compat/docker-entrypoint.sh
Executable file
3
build/os-compat/docker-entrypoint.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exec /lib/systemd/systemd --unit=multi-user.target --show-status=false --log-target=journal
|
||||||
27
build/os-compat/run-compat.sh
Executable file
27
build/os-compat/run-compat.sh
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$FORCE_COMPAT" = 1 ] || ( [ "$REQUIRES" = "linux" ] && [ "$(uname -s)" != "Linux" ] ) || ( [ "$REQUIRES" = "debian" ] && ! which dpkg > /dev/null ); then
|
||||||
|
project_pwd="$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd)/"
|
||||||
|
pwd="$(pwd)/"
|
||||||
|
if ! [[ "$pwd" = "$project_pwd"* ]]; then
|
||||||
|
>&2 echo "Must be run from start-os project dir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rel_pwd="${pwd#"$project_pwd"}"
|
||||||
|
|
||||||
|
SYSTEMD_TTY="-P"
|
||||||
|
USE_TTY=
|
||||||
|
if tty -s; then
|
||||||
|
USE_TTY="-it"
|
||||||
|
SYSTEMD_TTY="-t"
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker run -d --rm --name os-compat --privileged --security-opt apparmor=unconfined -v "${project_pwd}:/root/start-os" -v /lib/modules:/lib/modules:ro start9/build-env
|
||||||
|
while ! docker exec os-compat systemctl is-active --quiet multi-user.target 2> /dev/null; do sleep .5; done
|
||||||
|
docker exec -eARCH -eENVIRONMENT -ePLATFORM -eGIT_BRANCH_AS_HASH $USE_TTY -w "/root/start-os${rel_pwd}" os-compat $@
|
||||||
|
code=$?
|
||||||
|
docker stop os-compat
|
||||||
|
exit $code
|
||||||
|
else
|
||||||
|
exec $@
|
||||||
|
fi
|
||||||
@@ -7,6 +7,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ -f ./GIT_HASH.txt ] || [ "$(cat ./GIT_HASH.txt)" != "$GIT_HASH" ]; then
|
if ! [ -f ./GIT_HASH.txt ] || [ "$(cat ./GIT_HASH.txt)" != "$GIT_HASH" ]; then
|
||||||
|
>&2 echo Git hash changed from "$([ -f ./GIT_HASH.txt ] && cat ./GIT_HASH.txt)" to "$GIT_HASH"
|
||||||
echo -n "$GIT_HASH" > ./GIT_HASH.txt
|
echo -n "$GIT_HASH" > ./GIT_HASH.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
6
container-runtime/container-runtime-failure.service
Normal file
6
container-runtime/container-runtime-failure.service
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=StartOS Container Runtime Failure Handler
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/start-cli rebuild
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=StartOS Container Runtime
|
Description=StartOS Container Runtime
|
||||||
|
OnFailure=container-runtime-failure.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/node --experimental-detect-module --unhandled-rejections=warn /usr/lib/startos/init/index.js
|
ExecStart=/usr/bin/node --experimental-detect-module --trace-warnings --unhandled-rejections=warn /usr/lib/startos/init/index.js
|
||||||
Restart=always
|
Restart=no
|
||||||
RestartSec=3
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -10,7 +10,7 @@ apt-get install -y curl rsync qemu-user-static
|
|||||||
|
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||||
source ~/.bashrc
|
source ~/.bashrc
|
||||||
nvm install 20
|
nvm install 22
|
||||||
ln -s $(which node) /usr/bin/node
|
ln -s $(which node) /usr/bin/node
|
||||||
|
|
||||||
sed -i '/\(^\|#\)Storage=/c\Storage=persistent' /etc/systemd/journald.conf
|
sed -i '/\(^\|#\)Storage=/c\Storage=persistent' /etc/systemd/journald.conf
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
DISTRO=debian
|
DISTRO=debian
|
||||||
@@ -16,8 +14,9 @@ elif [ "$_ARCH" = "aarch64" ]; then
|
|||||||
_ARCH=arm64
|
_ARCH=arm64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
URL="https://images.linuxcontainers.org/$(curl -fsSL https://images.linuxcontainers.org/meta/1.0/index-system | grep "^$DISTRO;$VERSION;$_ARCH;$FLAVOR;" | head -n1 | sed 's/^.*;//g')/rootfs.squashfs"
|
BASE_URL="https://images.linuxcontainers.org$(curl -fsSL https://images.linuxcontainers.org/meta/1.0/index-system | grep "^$DISTRO;$VERSION;$_ARCH;$FLAVOR;" | head -n1 | sed 's/^.*;//g')"
|
||||||
|
OUTPUT_FILE="debian.${ARCH}.squashfs"
|
||||||
|
|
||||||
echo "Downloading $URL to debian.${ARCH}.squashfs"
|
echo "Downloading ${BASE_URL}/rootfs.squashfs to $OUTPUT_FILE"
|
||||||
|
curl -fsSL "${BASE_URL}/rootfs.squashfs" > "$OUTPUT_FILE"
|
||||||
curl -fsSL "$URL" > debian.${ARCH}.squashfs
|
curl -fsSL "$BASE_URL/SHA256SUMS" | grep 'rootfs\.squashfs' | awk '{print $1" '"$OUTPUT_FILE"'"}' | shasum -a 256 -c
|
||||||
4031
container-runtime/package-lock.json
generated
4031
container-runtime/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -324,14 +324,15 @@ export function makeEffects(context: EffectContext): Effects {
|
|||||||
>
|
>
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.onLeaveContext(() => {
|
if (context.callbacks?.onLeaveContext)
|
||||||
self.isInContext = false
|
self.onLeaveContext(() => {
|
||||||
self.onLeaveContext = () => {
|
self.isInContext = false
|
||||||
console.warn(
|
self.onLeaveContext = () => {
|
||||||
"this effects object is already out of context",
|
console.warn(
|
||||||
new Error().stack?.replace(/^Error/, ""),
|
"this effects object is already out of context",
|
||||||
)
|
new Error().stack?.replace(/^Error/, ""),
|
||||||
}
|
)
|
||||||
})
|
}
|
||||||
|
})
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ export class RpcListener {
|
|||||||
if (!fs.existsSync(SOCKET_PARENT)) {
|
if (!fs.existsSync(SOCKET_PARENT)) {
|
||||||
fs.mkdirSync(SOCKET_PARENT, { recursive: true })
|
fs.mkdirSync(SOCKET_PARENT, { recursive: true })
|
||||||
}
|
}
|
||||||
|
if (fs.existsSync(SOCKET_PATH)) fs.rmSync(SOCKET_PATH, { force: true })
|
||||||
|
|
||||||
this.unixSocketServer.listen(SOCKET_PATH)
|
this.unixSocketServer.listen(SOCKET_PATH)
|
||||||
|
|
||||||
this.unixSocketServer.on("connection", (s) => {
|
this.unixSocketServer.on("connection", (s) => {
|
||||||
|
|||||||
@@ -368,8 +368,14 @@ export class SystemForEmbassy implements System {
|
|||||||
reason: "This service must be configured before it can be run",
|
reason: "This service must be configured before it can be run",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const version = ExtendedVersion.parseEmver(this.manifest.version)
|
||||||
|
if (
|
||||||
|
this.manifest.id === "bitcoind" &&
|
||||||
|
this.manifest.title.toLowerCase().includes("knots")
|
||||||
|
)
|
||||||
|
version.flavor = "knots"
|
||||||
await effects.setDataVersion({
|
await effects.setDataVersion({
|
||||||
version: ExtendedVersion.parseEmver(this.manifest.version).toString(),
|
version: version.toString(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
async exportNetwork(effects: Effects) {
|
async exportNetwork(effects: Effects) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ cd "$(dirname "${BASH_SOURCE[0]}")"
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if mountpoint tmp/combined; then sudo umount -R tmp/combined; fi
|
if mountpoint -q tmp/combined; then sudo umount -R tmp/combined; fi
|
||||||
if mountpoint tmp/lower; then sudo umount tmp/lower; fi
|
if mountpoint -q tmp/lower; then sudo umount tmp/lower; fi
|
||||||
sudo rm -rf tmp
|
sudo rm -rf tmp
|
||||||
mkdir -p tmp/lower tmp/upper tmp/work tmp/combined
|
mkdir -p tmp/lower tmp/upper tmp/work tmp/combined
|
||||||
if which squashfuse > /dev/null; then
|
if which squashfuse > /dev/null; then
|
||||||
@@ -13,7 +13,11 @@ if which squashfuse > /dev/null; then
|
|||||||
else
|
else
|
||||||
sudo mount debian.${ARCH}.squashfs tmp/lower
|
sudo mount debian.${ARCH}.squashfs tmp/lower
|
||||||
fi
|
fi
|
||||||
sudo mount -t overlay -olowerdir=tmp/lower,upperdir=tmp/upper,workdir=tmp/work overlay tmp/combined
|
if which fuse-overlayfs > /dev/null; then
|
||||||
|
sudo fuse-overlayfs -olowerdir=tmp/lower,upperdir=tmp/upper,workdir=tmp/work overlay tmp/combined
|
||||||
|
else
|
||||||
|
sudo mount -t overlay -olowerdir=tmp/lower,upperdir=tmp/upper,workdir=tmp/work overlay tmp/combined
|
||||||
|
fi
|
||||||
|
|
||||||
QEMU=
|
QEMU=
|
||||||
if [ "$ARCH" != "$(uname -m)" ]; then
|
if [ "$ARCH" != "$(uname -m)" ]; then
|
||||||
@@ -33,6 +37,8 @@ sudo rsync -a --copy-unsafe-links dist/ tmp/combined/usr/lib/startos/init/
|
|||||||
sudo chown -R 0:0 tmp/combined/usr/lib/startos/
|
sudo chown -R 0:0 tmp/combined/usr/lib/startos/
|
||||||
sudo cp container-runtime.service tmp/combined/lib/systemd/system/container-runtime.service
|
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 chown 0:0 tmp/combined/lib/systemd/system/container-runtime.service
|
||||||
|
sudo cp container-runtime-failure.service tmp/combined/lib/systemd/system/container-runtime-failure.service
|
||||||
|
sudo chown 0:0 tmp/combined/lib/systemd/system/container-runtime-failure.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 chown 0:0 tmp/combined/usr/bin/start-cli
|
sudo chown 0:0 tmp/combined/usr/bin/start-cli
|
||||||
echo container-runtime | sha256sum | head -c 32 | cat - <(echo) | sudo tee tmp/combined/etc/machine-id
|
echo container-runtime | sha256sum | head -c 32 | cat - <(echo) | sudo tee tmp/combined/etc/machine-id
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ pub enum ErrorKind {
|
|||||||
Cancelled = 73,
|
Cancelled = 73,
|
||||||
Git = 74,
|
Git = 74,
|
||||||
DBus = 75,
|
DBus = 75,
|
||||||
|
InstallFailed = 76,
|
||||||
|
UpdateFailed = 77,
|
||||||
}
|
}
|
||||||
impl ErrorKind {
|
impl ErrorKind {
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
@@ -171,6 +173,8 @@ impl ErrorKind {
|
|||||||
Cancelled => "Cancelled",
|
Cancelled => "Cancelled",
|
||||||
Git => "Git Error",
|
Git => "Git Error",
|
||||||
DBus => "DBus Error",
|
DBus => "DBus Error",
|
||||||
|
InstallFailed => "Install Failed",
|
||||||
|
UpdateFailed => "Update Failed",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ impl TryFrom<ManifestV1> for Manifest {
|
|||||||
let default_url = value.upstream_repo.clone();
|
let default_url = value.upstream_repo.clone();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
id: value.id,
|
id: value.id,
|
||||||
title: value.title.into(),
|
title: format!("{} (Compatibility Mode)", value.title).into(),
|
||||||
version: ExtendedVersion::from(
|
version: ExtendedVersion::from(
|
||||||
exver::emver::Version::from_str(&value.version)
|
exver::emver::Version::from_str(&value.version)
|
||||||
.with_kind(ErrorKind::Deserialization)?,
|
.with_kind(ErrorKind::Deserialization)?,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ impl Context for ContainerCliContext {
|
|||||||
.runtime
|
.runtime
|
||||||
.get_or_init(|| {
|
.get_or_init(|| {
|
||||||
Arc::new(
|
Arc::new(
|
||||||
tokio::runtime::Builder::new_current_thread()
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|||||||
@@ -5,8 +5,22 @@ use models::{FromStrParser, PackageId};
|
|||||||
|
|
||||||
use crate::service::effects::prelude::*;
|
use crate::service::effects::prelude::*;
|
||||||
use crate::service::rpc::CallbackId;
|
use crate::service::rpc::CallbackId;
|
||||||
|
use crate::service::RebuildParams;
|
||||||
use crate::status::MainStatus;
|
use crate::status::MainStatus;
|
||||||
|
|
||||||
|
pub async fn rebuild(context: EffectContext) -> Result<(), Error> {
|
||||||
|
let seed = context.deref()?.seed.clone();
|
||||||
|
let ctx = seed.ctx.clone();
|
||||||
|
let id = seed.id.clone();
|
||||||
|
drop(seed);
|
||||||
|
tokio::spawn(async move {
|
||||||
|
super::super::rebuild(ctx, RebuildParams { id })
|
||||||
|
.await
|
||||||
|
.log_err()
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn restart(
|
pub async fn restart(
|
||||||
context: EffectContext,
|
context: EffectContext,
|
||||||
ProcedureId { procedure_id }: ProcedureId,
|
ProcedureId { procedure_id }: ProcedureId,
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
|
|||||||
from_fn(callbacks::clear_callbacks).no_cli(),
|
from_fn(callbacks::clear_callbacks).no_cli(),
|
||||||
)
|
)
|
||||||
// control
|
// control
|
||||||
|
.subcommand(
|
||||||
|
"rebuild",
|
||||||
|
from_fn_async(control::rebuild)
|
||||||
|
.no_display()
|
||||||
|
.with_call_remote::<ContainerCliContext>(),
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"restart",
|
"restart",
|
||||||
from_fn_async(control::restart)
|
from_fn_async(control::restart)
|
||||||
|
|||||||
@@ -209,7 +209,10 @@ impl ServiceRef {
|
|||||||
.request(rpc::Exit, Empty {})
|
.request(rpc::Exit, Empty {})
|
||||||
.await?;
|
.await?;
|
||||||
shutdown.shutdown();
|
shutdown.shutdown();
|
||||||
hdl.await.with_kind(ErrorKind::Cancelled)?;
|
tokio::time::timeout(Duration::from_secs(30), hdl)
|
||||||
|
.await
|
||||||
|
.with_kind(ErrorKind::Timeout)?
|
||||||
|
.with_kind(ErrorKind::Cancelled)?;
|
||||||
}
|
}
|
||||||
let service = Arc::try_unwrap(self.0).map_err(|_| {
|
let service = Arc::try_unwrap(self.0).map_err(|_| {
|
||||||
Error::new(
|
Error::new(
|
||||||
@@ -482,7 +485,11 @@ impl Service {
|
|||||||
None,
|
None,
|
||||||
) // TODO timeout
|
) // TODO timeout
|
||||||
.await
|
.await
|
||||||
.with_kind(ErrorKind::MigrationFailed)?; // TODO: handle cancellation
|
.with_kind(if src_version.is_some() {
|
||||||
|
ErrorKind::UpdateFailed
|
||||||
|
} else {
|
||||||
|
ErrorKind::InstallFailed
|
||||||
|
})?; // TODO: handle cancellation
|
||||||
|
|
||||||
if let Some(mut progress) = progress {
|
if let Some(mut progress) = progress {
|
||||||
progress.finalization_progress.complete();
|
progress.finalization_progress.complete();
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ impl Shutdown {
|
|||||||
Command::new("reboot").spawn().unwrap().wait().unwrap();
|
Command::new("reboot").spawn().unwrap().wait().unwrap();
|
||||||
} else {
|
} else {
|
||||||
Command::new("shutdown")
|
Command::new("shutdown")
|
||||||
.arg("-h")
|
|
||||||
.arg("now")
|
.arg("now")
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ 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/,$//')
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ export { AcmeSettings } from "./AcmeSettings"
|
|||||||
export { ActionId } from "./ActionId"
|
export { ActionId } from "./ActionId"
|
||||||
export { ActionInput } from "./ActionInput"
|
export { ActionInput } from "./ActionInput"
|
||||||
export { ActionMetadata } from "./ActionMetadata"
|
export { ActionMetadata } from "./ActionMetadata"
|
||||||
|
export { ActionRequest } from "./ActionRequest"
|
||||||
export { ActionRequestCondition } from "./ActionRequestCondition"
|
export { ActionRequestCondition } from "./ActionRequestCondition"
|
||||||
export { ActionRequestEntry } from "./ActionRequestEntry"
|
export { ActionRequestEntry } from "./ActionRequestEntry"
|
||||||
export { ActionRequestInput } from "./ActionRequestInput"
|
export { ActionRequestInput } from "./ActionRequestInput"
|
||||||
export { ActionRequestTrigger } from "./ActionRequestTrigger"
|
export { ActionRequestTrigger } from "./ActionRequestTrigger"
|
||||||
export { ActionRequest } from "./ActionRequest"
|
|
||||||
export { ActionResultMember } from "./ActionResultMember"
|
|
||||||
export { ActionResult } from "./ActionResult"
|
export { ActionResult } from "./ActionResult"
|
||||||
|
export { ActionResultMember } from "./ActionResultMember"
|
||||||
export { ActionResultV0 } from "./ActionResultV0"
|
export { ActionResultV0 } from "./ActionResultV0"
|
||||||
export { ActionResultV1 } from "./ActionResultV1"
|
export { ActionResultV1 } from "./ActionResultV1"
|
||||||
export { ActionResultValue } from "./ActionResultValue"
|
export { ActionResultValue } from "./ActionResultValue"
|
||||||
@@ -20,13 +20,13 @@ export { AddAdminParams } from "./AddAdminParams"
|
|||||||
export { AddAssetParams } from "./AddAssetParams"
|
export { AddAssetParams } from "./AddAssetParams"
|
||||||
export { AddCategoryParams } from "./AddCategoryParams"
|
export { AddCategoryParams } from "./AddCategoryParams"
|
||||||
export { AddPackageParams } from "./AddPackageParams"
|
export { AddPackageParams } from "./AddPackageParams"
|
||||||
export { AddressInfo } from "./AddressInfo"
|
|
||||||
export { AddSslOptions } from "./AddSslOptions"
|
export { AddSslOptions } from "./AddSslOptions"
|
||||||
export { AddVersionParams } from "./AddVersionParams"
|
export { AddVersionParams } from "./AddVersionParams"
|
||||||
|
export { AddressInfo } from "./AddressInfo"
|
||||||
export { Alerts } from "./Alerts"
|
export { Alerts } from "./Alerts"
|
||||||
export { Algorithm } from "./Algorithm"
|
export { Algorithm } from "./Algorithm"
|
||||||
export { AllowedStatuses } from "./AllowedStatuses"
|
|
||||||
export { AllPackageData } from "./AllPackageData"
|
export { AllPackageData } from "./AllPackageData"
|
||||||
|
export { AllowedStatuses } from "./AllowedStatuses"
|
||||||
export { AlpnInfo } from "./AlpnInfo"
|
export { AlpnInfo } from "./AlpnInfo"
|
||||||
export { AnySignature } from "./AnySignature"
|
export { AnySignature } from "./AnySignature"
|
||||||
export { AnySigningKey } from "./AnySigningKey"
|
export { AnySigningKey } from "./AnySigningKey"
|
||||||
@@ -38,9 +38,9 @@ export { BackupTargetFS } from "./BackupTargetFS"
|
|||||||
export { Base64 } from "./Base64"
|
export { Base64 } from "./Base64"
|
||||||
export { BindId } from "./BindId"
|
export { BindId } from "./BindId"
|
||||||
export { BindInfo } from "./BindInfo"
|
export { BindInfo } from "./BindInfo"
|
||||||
export { BindingSetPublicParams } from "./BindingSetPublicParams"
|
|
||||||
export { BindOptions } from "./BindOptions"
|
export { BindOptions } from "./BindOptions"
|
||||||
export { BindParams } from "./BindParams"
|
export { BindParams } from "./BindParams"
|
||||||
|
export { BindingSetPublicParams } from "./BindingSetPublicParams"
|
||||||
export { Blake3Commitment } from "./Blake3Commitment"
|
export { Blake3Commitment } from "./Blake3Commitment"
|
||||||
export { BlockDev } from "./BlockDev"
|
export { BlockDev } from "./BlockDev"
|
||||||
export { BuildArg } from "./BuildArg"
|
export { BuildArg } from "./BuildArg"
|
||||||
@@ -61,11 +61,11 @@ export { CreateSubcontainerFsParams } from "./CreateSubcontainerFsParams"
|
|||||||
export { CurrentDependencies } from "./CurrentDependencies"
|
export { CurrentDependencies } from "./CurrentDependencies"
|
||||||
export { CurrentDependencyInfo } from "./CurrentDependencyInfo"
|
export { CurrentDependencyInfo } from "./CurrentDependencyInfo"
|
||||||
export { DataUrl } from "./DataUrl"
|
export { DataUrl } from "./DataUrl"
|
||||||
|
export { DepInfo } from "./DepInfo"
|
||||||
export { Dependencies } from "./Dependencies"
|
export { Dependencies } from "./Dependencies"
|
||||||
export { DependencyKind } from "./DependencyKind"
|
export { DependencyKind } from "./DependencyKind"
|
||||||
export { DependencyMetadata } from "./DependencyMetadata"
|
export { DependencyMetadata } from "./DependencyMetadata"
|
||||||
export { DependencyRequirement } from "./DependencyRequirement"
|
export { DependencyRequirement } from "./DependencyRequirement"
|
||||||
export { DepInfo } from "./DepInfo"
|
|
||||||
export { Description } from "./Description"
|
export { Description } from "./Description"
|
||||||
export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams"
|
export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams"
|
||||||
export { DeviceFilter } from "./DeviceFilter"
|
export { DeviceFilter } from "./DeviceFilter"
|
||||||
@@ -86,8 +86,8 @@ export { GetHostInfoParams } from "./GetHostInfoParams"
|
|||||||
export { GetOsAssetParams } from "./GetOsAssetParams"
|
export { GetOsAssetParams } from "./GetOsAssetParams"
|
||||||
export { GetOsVersionParams } from "./GetOsVersionParams"
|
export { GetOsVersionParams } from "./GetOsVersionParams"
|
||||||
export { GetPackageParams } from "./GetPackageParams"
|
export { GetPackageParams } from "./GetPackageParams"
|
||||||
export { GetPackageResponseFull } from "./GetPackageResponseFull"
|
|
||||||
export { GetPackageResponse } from "./GetPackageResponse"
|
export { GetPackageResponse } from "./GetPackageResponse"
|
||||||
|
export { GetPackageResponseFull } from "./GetPackageResponseFull"
|
||||||
export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams"
|
export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams"
|
||||||
export { GetServicePortForwardParams } from "./GetServicePortForwardParams"
|
export { GetServicePortForwardParams } from "./GetServicePortForwardParams"
|
||||||
export { GetSslCertificateParams } from "./GetSslCertificateParams"
|
export { GetSslCertificateParams } from "./GetSslCertificateParams"
|
||||||
@@ -101,21 +101,21 @@ export { Governor } from "./Governor"
|
|||||||
export { Guid } from "./Guid"
|
export { Guid } from "./Guid"
|
||||||
export { HardwareRequirements } from "./HardwareRequirements"
|
export { HardwareRequirements } from "./HardwareRequirements"
|
||||||
export { HealthCheckId } from "./HealthCheckId"
|
export { HealthCheckId } from "./HealthCheckId"
|
||||||
|
export { Host } from "./Host"
|
||||||
export { HostAddress } from "./HostAddress"
|
export { HostAddress } from "./HostAddress"
|
||||||
export { HostId } from "./HostId"
|
export { HostId } from "./HostId"
|
||||||
export { HostnameInfo } from "./HostnameInfo"
|
export { HostnameInfo } from "./HostnameInfo"
|
||||||
export { Hosts } from "./Hosts"
|
export { Hosts } from "./Hosts"
|
||||||
export { Host } from "./Host"
|
|
||||||
export { ImageConfig } from "./ImageConfig"
|
export { ImageConfig } from "./ImageConfig"
|
||||||
export { ImageId } from "./ImageId"
|
export { ImageId } from "./ImageId"
|
||||||
export { ImageMetadata } from "./ImageMetadata"
|
export { ImageMetadata } from "./ImageMetadata"
|
||||||
export { ImageSource } from "./ImageSource"
|
export { ImageSource } from "./ImageSource"
|
||||||
export { InitProgressRes } from "./InitProgressRes"
|
export { InitProgressRes } from "./InitProgressRes"
|
||||||
|
export { InstallParams } from "./InstallParams"
|
||||||
export { InstalledState } from "./InstalledState"
|
export { InstalledState } from "./InstalledState"
|
||||||
export { InstalledVersionParams } from "./InstalledVersionParams"
|
export { InstalledVersionParams } from "./InstalledVersionParams"
|
||||||
export { InstallingInfo } from "./InstallingInfo"
|
export { InstallingInfo } from "./InstallingInfo"
|
||||||
export { InstallingState } from "./InstallingState"
|
export { InstallingState } from "./InstallingState"
|
||||||
export { InstallParams } from "./InstallParams"
|
|
||||||
export { IpHostname } from "./IpHostname"
|
export { IpHostname } from "./IpHostname"
|
||||||
export { IpInfo } from "./IpInfo"
|
export { IpInfo } from "./IpInfo"
|
||||||
export { ListPackageSignersParams } from "./ListPackageSignersParams"
|
export { ListPackageSignersParams } from "./ListPackageSignersParams"
|
||||||
@@ -130,11 +130,11 @@ export { Manifest } from "./Manifest"
|
|||||||
export { MaybeUtf8String } from "./MaybeUtf8String"
|
export { MaybeUtf8String } from "./MaybeUtf8String"
|
||||||
export { MebiBytes } from "./MebiBytes"
|
export { MebiBytes } from "./MebiBytes"
|
||||||
export { MerkleArchiveCommitment } from "./MerkleArchiveCommitment"
|
export { MerkleArchiveCommitment } from "./MerkleArchiveCommitment"
|
||||||
|
export { Metrics } from "./Metrics"
|
||||||
export { MetricsCpu } from "./MetricsCpu"
|
export { MetricsCpu } from "./MetricsCpu"
|
||||||
export { MetricsDisk } from "./MetricsDisk"
|
export { MetricsDisk } from "./MetricsDisk"
|
||||||
export { MetricsGeneral } from "./MetricsGeneral"
|
export { MetricsGeneral } from "./MetricsGeneral"
|
||||||
export { MetricsMemory } from "./MetricsMemory"
|
export { MetricsMemory } from "./MetricsMemory"
|
||||||
export { Metrics } from "./Metrics"
|
|
||||||
export { MountParams } from "./MountParams"
|
export { MountParams } from "./MountParams"
|
||||||
export { MountTarget } from "./MountTarget"
|
export { MountTarget } from "./MountTarget"
|
||||||
export { NamedHealthCheckResult } from "./NamedHealthCheckResult"
|
export { NamedHealthCheckResult } from "./NamedHealthCheckResult"
|
||||||
@@ -146,14 +146,14 @@ export { NetworkInterfaceSetInboundParams } from "./NetworkInterfaceSetInboundPa
|
|||||||
export { NetworkInterfaceType } from "./NetworkInterfaceType"
|
export { NetworkInterfaceType } from "./NetworkInterfaceType"
|
||||||
export { OnionHostname } from "./OnionHostname"
|
export { OnionHostname } from "./OnionHostname"
|
||||||
export { OsIndex } from "./OsIndex"
|
export { OsIndex } from "./OsIndex"
|
||||||
export { OsVersionInfoMap } from "./OsVersionInfoMap"
|
|
||||||
export { OsVersionInfo } from "./OsVersionInfo"
|
export { OsVersionInfo } from "./OsVersionInfo"
|
||||||
|
export { OsVersionInfoMap } from "./OsVersionInfoMap"
|
||||||
export { PackageDataEntry } from "./PackageDataEntry"
|
export { PackageDataEntry } from "./PackageDataEntry"
|
||||||
export { PackageDetailLevel } from "./PackageDetailLevel"
|
export { PackageDetailLevel } from "./PackageDetailLevel"
|
||||||
export { PackageId } from "./PackageId"
|
export { PackageId } from "./PackageId"
|
||||||
export { PackageIndex } from "./PackageIndex"
|
export { PackageIndex } from "./PackageIndex"
|
||||||
export { PackageInfoShort } from "./PackageInfoShort"
|
|
||||||
export { PackageInfo } from "./PackageInfo"
|
export { PackageInfo } from "./PackageInfo"
|
||||||
|
export { PackageInfoShort } from "./PackageInfoShort"
|
||||||
export { PackageSignerParams } from "./PackageSignerParams"
|
export { PackageSignerParams } from "./PackageSignerParams"
|
||||||
export { PackageState } from "./PackageState"
|
export { PackageState } from "./PackageState"
|
||||||
export { PackageVersionInfo } from "./PackageVersionInfo"
|
export { PackageVersionInfo } from "./PackageVersionInfo"
|
||||||
@@ -176,18 +176,18 @@ export { Security } from "./Security"
|
|||||||
export { ServerInfo } from "./ServerInfo"
|
export { ServerInfo } from "./ServerInfo"
|
||||||
export { ServerSpecs } from "./ServerSpecs"
|
export { ServerSpecs } from "./ServerSpecs"
|
||||||
export { ServerStatus } from "./ServerStatus"
|
export { ServerStatus } from "./ServerStatus"
|
||||||
export { ServiceInterfaceId } from "./ServiceInterfaceId"
|
|
||||||
export { ServiceInterface } from "./ServiceInterface"
|
export { ServiceInterface } from "./ServiceInterface"
|
||||||
|
export { ServiceInterfaceId } from "./ServiceInterfaceId"
|
||||||
export { ServiceInterfaceType } from "./ServiceInterfaceType"
|
export { ServiceInterfaceType } from "./ServiceInterfaceType"
|
||||||
|
export { Session } from "./Session"
|
||||||
export { SessionList } from "./SessionList"
|
export { SessionList } from "./SessionList"
|
||||||
export { Sessions } from "./Sessions"
|
export { Sessions } from "./Sessions"
|
||||||
export { Session } from "./Session"
|
|
||||||
export { SetDataVersionParams } from "./SetDataVersionParams"
|
export { SetDataVersionParams } from "./SetDataVersionParams"
|
||||||
export { SetDependenciesParams } from "./SetDependenciesParams"
|
export { SetDependenciesParams } from "./SetDependenciesParams"
|
||||||
export { SetHealth } from "./SetHealth"
|
export { SetHealth } from "./SetHealth"
|
||||||
export { SetIconParams } from "./SetIconParams"
|
export { SetIconParams } from "./SetIconParams"
|
||||||
export { SetMainStatusStatus } from "./SetMainStatusStatus"
|
|
||||||
export { SetMainStatus } from "./SetMainStatus"
|
export { SetMainStatus } from "./SetMainStatus"
|
||||||
|
export { SetMainStatusStatus } from "./SetMainStatusStatus"
|
||||||
export { SetNameParams } from "./SetNameParams"
|
export { SetNameParams } from "./SetNameParams"
|
||||||
export { SetStoreParams } from "./SetStoreParams"
|
export { SetStoreParams } from "./SetStoreParams"
|
||||||
export { SetupExecuteParams } from "./SetupExecuteParams"
|
export { SetupExecuteParams } from "./SetupExecuteParams"
|
||||||
@@ -202,7 +202,7 @@ export { TestSmtpParams } from "./TestSmtpParams"
|
|||||||
export { UnsetInboundParams } from "./UnsetInboundParams"
|
export { UnsetInboundParams } from "./UnsetInboundParams"
|
||||||
export { UpdatingState } from "./UpdatingState"
|
export { UpdatingState } from "./UpdatingState"
|
||||||
export { VerifyCifsParams } from "./VerifyCifsParams"
|
export { VerifyCifsParams } from "./VerifyCifsParams"
|
||||||
export { VersionSignerParams } from "./VersionSignerParams"
|
|
||||||
export { Version } from "./Version"
|
export { Version } from "./Version"
|
||||||
|
export { VersionSignerParams } from "./VersionSignerParams"
|
||||||
export { VolumeId } from "./VolumeId"
|
export { VolumeId } from "./VolumeId"
|
||||||
export { WifiInfo } from "./WifiInfo"
|
export { WifiInfo } from "./WifiInfo"
|
||||||
|
|||||||
@@ -207,3 +207,25 @@ export type DeepPartial<T> = T extends unknown[]
|
|||||||
: T extends {}
|
: T extends {}
|
||||||
? { [P in keyof T]?: DeepPartial<T[P]> }
|
? { [P in keyof T]?: DeepPartial<T[P]> }
|
||||||
: T
|
: T
|
||||||
|
|
||||||
|
export type DeepWritable<T> = {
|
||||||
|
-readonly [K in keyof T]: T[K]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writable<T>(value: T): DeepWritable<T> {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DeepReadonly<T> = {
|
||||||
|
readonly [P in keyof T]: DeepReadonly<T[P]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readonly<T>(value: T): DeepReadonly<T> {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AllowReadonly<T> =
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
readonly [P in keyof T]: AllowReadonly<T[P]>
|
||||||
|
}
|
||||||
|
|||||||
8
sdk/base/package-lock.json
generated
8
sdk/base/package-lock.json
generated
@@ -13,7 +13,7 @@
|
|||||||
"deep-equality-data-structures": "^1.5.0",
|
"deep-equality-data-structures": "^1.5.0",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mime-types": "^3.0.1",
|
"mime-types": "^3.0.1",
|
||||||
"ts-matches": "^6.2.1",
|
"ts-matches": "^6.3.2",
|
||||||
"yaml": "^2.7.1"
|
"yaml": "^2.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -4636,9 +4636,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-matches": {
|
"node_modules/ts-matches": {
|
||||||
"version": "6.2.1",
|
"version": "6.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.3.2.tgz",
|
||||||
"integrity": "sha512-qdnMgTHsGCEGGK6QiaNMY2vD9eQtRp2Q+pAxcOAzxHJKDKTBYsc1ISTg1zp8H2+EmtCB0eko/1TwYUA5/mUGug==",
|
"integrity": "sha512-UhSgJymF8cLd4y0vV29qlKVCkQpUtekAaujXbQVc729FezS8HwqzepqvtjzQ3HboatIqN/Idor85O2RMwT7lIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ts-morph": {
|
"node_modules/ts-morph": {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
"@noble/hashes": "^1.7.2",
|
"@noble/hashes": "^1.7.2",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mime-types": "^3.0.1",
|
"mime-types": "^3.0.1",
|
||||||
"ts-matches": "^6.2.1",
|
"ts-matches": "^6.3.2",
|
||||||
"yaml": "^2.7.1",
|
"yaml": "^2.7.1",
|
||||||
"deep-equality-data-structures": "^1.5.0"
|
"deep-equality-data-structures": "^1.5.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1170,7 +1170,7 @@ export async function runCommand<Manifest extends T.SDKManifest>(
|
|||||||
.catch(() => "{}")
|
.catch(() => "{}")
|
||||||
.then(JSON.parse)
|
.then(JSON.parse)
|
||||||
commands = imageMeta.entrypoint ?? []
|
commands = imageMeta.entrypoint ?? []
|
||||||
commands.concat(...(command.overridCmd ?? imageMeta.cmd ?? []))
|
commands = commands.concat(...(command.overridCmd ?? imageMeta.cmd ?? []))
|
||||||
} else commands = splitCommand(command)
|
} else commands = splitCommand(command)
|
||||||
return SubContainer.withTemp(
|
return SubContainer.withTemp(
|
||||||
effects,
|
effects,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const runHealthScript = async <Manifest extends SDKManifest>(
|
|||||||
} = {},
|
} = {},
|
||||||
): Promise<HealthCheckResult> => {
|
): Promise<HealthCheckResult> => {
|
||||||
const res = await Promise.race([
|
const res = await Promise.race([
|
||||||
subcontainer.exec(runCommand),
|
subcontainer.execFail(runCommand),
|
||||||
timeoutPromise(timeout),
|
timeoutPromise(timeout),
|
||||||
]).catch((e) => {
|
]).catch((e) => {
|
||||||
console.warn(errorMessage)
|
console.warn(errorMessage)
|
||||||
|
|||||||
@@ -42,19 +42,21 @@ export class CommandController<Manifest extends T.SDKManifest> extends Drop {
|
|||||||
onStderr?: (chunk: Buffer | string | any) => void
|
onStderr?: (chunk: Buffer | string | any) => void
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
let commands: string[]
|
|
||||||
if (command instanceof T.UseEntrypoint) {
|
|
||||||
const imageMeta: T.ImageMetadata = await fs
|
|
||||||
.readFile(`/media/startos/images/${subcontainer.imageId}.json`, {
|
|
||||||
encoding: "utf8",
|
|
||||||
})
|
|
||||||
.catch(() => "{}")
|
|
||||||
.then(JSON.parse)
|
|
||||||
commands = imageMeta.entrypoint ?? []
|
|
||||||
commands.concat(...(command.overridCmd ?? imageMeta.cmd ?? []))
|
|
||||||
} else commands = splitCommand(command)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
let commands: string[]
|
||||||
|
if (command instanceof T.UseEntrypoint) {
|
||||||
|
const imageMeta: T.ImageMetadata = await fs
|
||||||
|
.readFile(`/media/startos/images/${subcontainer.imageId}.json`, {
|
||||||
|
encoding: "utf8",
|
||||||
|
})
|
||||||
|
.catch(() => "{}")
|
||||||
|
.then(JSON.parse)
|
||||||
|
commands = imageMeta.entrypoint ?? []
|
||||||
|
commands = commands.concat(
|
||||||
|
...(command.overridCmd ?? imageMeta.cmd ?? []),
|
||||||
|
)
|
||||||
|
} else commands = splitCommand(command)
|
||||||
|
|
||||||
let childProcess: cp.ChildProcess
|
let childProcess: cp.ChildProcess
|
||||||
if (options.runAsInit) {
|
if (options.runAsInit) {
|
||||||
childProcess = await subcontainer.launch(commands, {
|
childProcess = await subcontainer.launch(commands, {
|
||||||
@@ -111,10 +113,10 @@ export class CommandController<Manifest extends T.SDKManifest> extends Drop {
|
|||||||
get subContainerHandle() {
|
get subContainerHandle() {
|
||||||
return new SubContainerHandle(this.subcontainer)
|
return new SubContainerHandle(this.subcontainer)
|
||||||
}
|
}
|
||||||
async wait({ timeout = NO_TIMEOUT } = {}) {
|
async wait({ timeout = NO_TIMEOUT, keepSubcontainer = false } = {}) {
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.term()
|
this.term({ keepSubcontainer })
|
||||||
}, timeout)
|
}, timeout)
|
||||||
try {
|
try {
|
||||||
return await this.runningAnswer
|
return await this.runningAnswer
|
||||||
@@ -122,10 +124,14 @@ export class CommandController<Manifest extends T.SDKManifest> extends Drop {
|
|||||||
if (!this.state.exited) {
|
if (!this.state.exited) {
|
||||||
this.process.kill("SIGKILL")
|
this.process.kill("SIGKILL")
|
||||||
}
|
}
|
||||||
await this.subcontainer.destroy().catch((_) => {})
|
if (!keepSubcontainer) await this.subcontainer.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async term({ signal = SIGTERM, timeout = this.sigtermTimeout } = {}) {
|
async term({
|
||||||
|
signal = SIGTERM,
|
||||||
|
timeout = this.sigtermTimeout,
|
||||||
|
keepSubcontainer = false,
|
||||||
|
} = {}) {
|
||||||
try {
|
try {
|
||||||
if (!this.state.exited) {
|
if (!this.state.exited) {
|
||||||
if (signal !== "SIGKILL") {
|
if (signal !== "SIGKILL") {
|
||||||
@@ -142,10 +148,10 @@ export class CommandController<Manifest extends T.SDKManifest> extends Drop {
|
|||||||
|
|
||||||
await this.runningAnswer
|
await this.runningAnswer
|
||||||
} finally {
|
} finally {
|
||||||
await this.subcontainer.destroy()
|
if (!keepSubcontainer) await this.subcontainer.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onDrop(): void {
|
onDrop(): void {
|
||||||
this.term().catch(console.error)
|
this.term({ keepSubcontainer: true }).catch(console.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export class Daemon<Manifest extends T.SDKManifest> {
|
|||||||
return this.commandController?.subContainerHandle
|
return this.commandController?.subContainerHandle
|
||||||
}
|
}
|
||||||
static of<Manifest extends T.SDKManifest>() {
|
static of<Manifest extends T.SDKManifest>() {
|
||||||
return async <A extends string>(
|
return async (
|
||||||
effects: T.Effects,
|
effects: T.Effects,
|
||||||
subcontainer: SubContainer<Manifest>,
|
subcontainer: SubContainer<Manifest>,
|
||||||
command: T.CommandType,
|
command: T.CommandType,
|
||||||
@@ -54,17 +54,21 @@ export class Daemon<Manifest extends T.SDKManifest> {
|
|||||||
}
|
}
|
||||||
this.shouldBeRunning = true
|
this.shouldBeRunning = true
|
||||||
let timeoutCounter = 0
|
let timeoutCounter = 0
|
||||||
new Promise(async () => {
|
;(async () => {
|
||||||
while (this.shouldBeRunning) {
|
while (this.shouldBeRunning) {
|
||||||
if (this.commandController)
|
if (this.commandController)
|
||||||
await this.commandController.term().catch((err) => console.error(err))
|
await this.commandController
|
||||||
|
.term({ keepSubcontainer: true })
|
||||||
|
.catch((err) => console.error(err))
|
||||||
this.commandController = await this.startCommand()
|
this.commandController = await this.startCommand()
|
||||||
await this.commandController.wait().catch((err) => console.error(err))
|
await this.commandController
|
||||||
|
.wait({ keepSubcontainer: true })
|
||||||
|
.catch((err) => console.error(err))
|
||||||
await new Promise((resolve) => setTimeout(resolve, timeoutCounter))
|
await new Promise((resolve) => setTimeout(resolve, timeoutCounter))
|
||||||
timeoutCounter += TIMEOUT_INCREMENT_MS
|
timeoutCounter += TIMEOUT_INCREMENT_MS
|
||||||
timeoutCounter = Math.max(MAX_TIMEOUT_MS, timeoutCounter)
|
timeoutCounter = Math.min(MAX_TIMEOUT_MS, timeoutCounter)
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
})().catch((err) => {
|
||||||
console.error(asError(err))
|
console.error(asError(err))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export class Daemons<Manifest extends T.SDKManifest, Ids extends string>
|
|||||||
|
|
||||||
async build() {
|
async build() {
|
||||||
for (const daemon of this.healthDaemons) {
|
for (const daemon of this.healthDaemons) {
|
||||||
await daemon.updateStatus()
|
await daemon.init()
|
||||||
}
|
}
|
||||||
for (const health of this.healthChecks) {
|
for (const health of this.healthChecks) {
|
||||||
health.start()
|
health.start()
|
||||||
|
|||||||
@@ -169,4 +169,16 @@ export class HealthDaemon<Manifest extends SDKManifest> {
|
|||||||
const healths = this.dependencies.map((d) => d.running && d._health)
|
const healths = this.dependencies.map((d) => d.running && d._health)
|
||||||
this.changeRunning(healths.every((x) => x && x.result === "success"))
|
this.changeRunning(healths.every((x) => x && x.result === "success"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
if (this.ready.display) {
|
||||||
|
this.effects.setHealth({
|
||||||
|
id: this.id,
|
||||||
|
message: null,
|
||||||
|
name: this.ready.display,
|
||||||
|
result: "starting",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await this.updateStatus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,20 @@ export abstract class Drop {
|
|||||||
protected constructor() {
|
protected constructor() {
|
||||||
this.id = Drop.idCtr++
|
this.id = Drop.idCtr++
|
||||||
this.ref = { id: this.id }
|
this.ref = { id: this.id }
|
||||||
Drop.weak[this.id] = this.weak()
|
const weak = this.weak()
|
||||||
Drop.registry.register(this, this.id, this)
|
Drop.weak[this.id] = weak
|
||||||
|
Drop.registry.register(this.ref, this.id, this.ref)
|
||||||
|
|
||||||
|
return new Proxy(this, {
|
||||||
|
set(target: any, prop, value) {
|
||||||
|
if (prop === "ref") return false
|
||||||
|
target[prop] = value
|
||||||
|
;(weak as any)[prop] = value
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
protected register() {}
|
||||||
protected weak(): this {
|
protected weak(): this {
|
||||||
const weak = Object.assign(Object.create(Object.getPrototypeOf(this)), this)
|
const weak = Object.assign(Object.create(Object.getPrototypeOf(this)), this)
|
||||||
weak.ref = new WeakRef(this.ref)
|
weak.ref = new WeakRef(this.ref)
|
||||||
@@ -21,7 +32,7 @@ export abstract class Drop {
|
|||||||
abstract onDrop(): void
|
abstract onDrop(): void
|
||||||
drop(): void {
|
drop(): void {
|
||||||
this.onDrop()
|
this.onDrop()
|
||||||
Drop.registry.unregister(this)
|
Drop.registry.unregister(this.ref)
|
||||||
delete Drop.weak[this.id]
|
delete Drop.weak[this.id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ export interface ExecSpawnable {
|
|||||||
options?: CommandOptions & ExecOptions,
|
options?: CommandOptions & ExecOptions,
|
||||||
timeoutMs?: number | null,
|
timeoutMs?: number | null,
|
||||||
): Promise<ExecResults>
|
): Promise<ExecResults>
|
||||||
|
execFail(
|
||||||
|
command: string[],
|
||||||
|
options?: CommandOptions & ExecOptions,
|
||||||
|
timeoutMs?: number | null,
|
||||||
|
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }>
|
||||||
spawn(
|
spawn(
|
||||||
command: string[],
|
command: string[],
|
||||||
options?: CommandOptions & StdioOptions,
|
options?: CommandOptions & StdioOptions,
|
||||||
@@ -88,7 +93,9 @@ export class SubContainer<
|
|||||||
imageId: this.imageId,
|
imageId: this.imageId,
|
||||||
rootfs: this.rootfs,
|
rootfs: this.rootfs,
|
||||||
})
|
})
|
||||||
reject(new Error(`Failed to start subcontainer ${this.imageId}`))
|
return reject(
|
||||||
|
new Error(`Failed to start subcontainer ${this.imageId}`),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
await wait(1)
|
await wait(1)
|
||||||
}
|
}
|
||||||
@@ -144,8 +151,9 @@ export class SubContainer<
|
|||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
} finally {
|
} catch (e) {
|
||||||
await res.destroy()
|
await res.destroy()
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,11 +280,13 @@ export class SubContainer<
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDrop(): void {
|
onDrop(): void {
|
||||||
|
console.log(`Cleaning up dangling subcontainer ${this.guid}`)
|
||||||
this.destroy()
|
this.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description run a command inside this subcontainer
|
* @description run a command inside this subcontainer
|
||||||
|
* DOES NOT THROW ON NONZERO EXIT CODE (see execFail)
|
||||||
* @param commands an array representing the command and args to execute
|
* @param commands an array representing the command and args to execute
|
||||||
* @param options
|
* @param options
|
||||||
* @param timeoutMs how long to wait before killing the command in ms
|
* @param timeoutMs how long to wait before killing the command in ms
|
||||||
@@ -287,6 +297,7 @@ export class SubContainer<
|
|||||||
options?: CommandOptions & ExecOptions,
|
options?: CommandOptions & ExecOptions,
|
||||||
timeoutMs: number | null = 30000,
|
timeoutMs: number | null = 30000,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
|
throw: () => { stdout: string | Buffer; stderr: string | Buffer }
|
||||||
exitCode: number | null
|
exitCode: number | null
|
||||||
exitSignal: NodeJS.Signals | null
|
exitSignal: NodeJS.Signals | null
|
||||||
stdout: string | Buffer
|
stdout: string | Buffer
|
||||||
@@ -367,16 +378,43 @@ export class SubContainer<
|
|||||||
child.stderr.on("data", appendData(stderr))
|
child.stderr.on("data", appendData(stderr))
|
||||||
child.on("exit", (code, signal) => {
|
child.on("exit", (code, signal) => {
|
||||||
clearTimeout(killTimeout)
|
clearTimeout(killTimeout)
|
||||||
resolve({
|
const result = {
|
||||||
exitCode: code,
|
exitCode: code,
|
||||||
exitSignal: signal,
|
exitSignal: signal,
|
||||||
stdout: stdout.data,
|
stdout: stdout.data,
|
||||||
stderr: stderr.data,
|
stderr: stderr.data,
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
throw: () =>
|
||||||
|
!code && !signal
|
||||||
|
? { stdout: stdout.data, stderr: stderr.data }
|
||||||
|
: (() => {
|
||||||
|
throw new ExitError(command[0], result)
|
||||||
|
})(),
|
||||||
|
...result,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description run a command inside this subcontainer, throwing on non-zero exit status
|
||||||
|
* @param commands an array representing the command and args to execute
|
||||||
|
* @param options
|
||||||
|
* @param timeoutMs how long to wait before killing the command in ms
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async execFail(
|
||||||
|
command: string[],
|
||||||
|
options?: CommandOptions & ExecOptions,
|
||||||
|
timeoutMs: number | null = 30000,
|
||||||
|
): Promise<{
|
||||||
|
stdout: string | Buffer
|
||||||
|
stderr: string | Buffer
|
||||||
|
}> {
|
||||||
|
return this.exec(command, options, timeoutMs).then((res) => res.throw())
|
||||||
|
}
|
||||||
|
|
||||||
async launch(
|
async launch(
|
||||||
command: string[],
|
command: string[],
|
||||||
options?: CommandOptions,
|
options?: CommandOptions,
|
||||||
@@ -478,6 +516,15 @@ export class SubContainerHandle implements ExecSpawnable {
|
|||||||
): Promise<ExecResults> {
|
): Promise<ExecResults> {
|
||||||
return this.subContainer.exec(command, options, timeoutMs)
|
return this.subContainer.exec(command, options, timeoutMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
execFail(
|
||||||
|
command: string[],
|
||||||
|
options?: CommandOptions & ExecOptions,
|
||||||
|
timeoutMs?: number | null,
|
||||||
|
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> {
|
||||||
|
return this.subContainer.execFail(command, options, timeoutMs)
|
||||||
|
}
|
||||||
|
|
||||||
spawn(
|
spawn(
|
||||||
command: string[],
|
command: string[],
|
||||||
options: CommandOptions & StdioOptions = { stdio: "inherit" },
|
options: CommandOptions & StdioOptions = { stdio: "inherit" },
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export class FileHelper<A> {
|
|||||||
/**
|
/**
|
||||||
* Accepts full structured data and overwrites the existing file on disk if it exists.
|
* Accepts full structured data and overwrites the existing file on disk if it exists.
|
||||||
*/
|
*/
|
||||||
async write(effects: T.Effects, data: A) {
|
async write(effects: T.Effects, data: T.AllowReadonly<A> | A) {
|
||||||
await this.writeFile(this.validate(data))
|
await this.writeFile(this.validate(data))
|
||||||
if (effects.constRetry && this.consts.includes(effects.constRetry))
|
if (effects.constRetry && this.consts.includes(effects.constRetry))
|
||||||
throw new Error(`Canceled: write after const: ${this.path}`)
|
throw new Error(`Canceled: write after const: ${this.path}`)
|
||||||
@@ -244,7 +244,7 @@ export class FileHelper<A> {
|
|||||||
/**
|
/**
|
||||||
* Accepts partial structured data and performs a merge with the existing file on disk.
|
* Accepts partial structured data and performs a merge with the existing file on disk.
|
||||||
*/
|
*/
|
||||||
async merge(effects: T.Effects, data: T.DeepPartial<A>) {
|
async merge(effects: T.Effects, data: T.AllowReadonly<T.DeepPartial<A>>) {
|
||||||
const fileDataRaw = await this.readFileRaw()
|
const fileDataRaw = await this.readFileRaw()
|
||||||
let fileData: any = fileDataRaw === null ? null : this.readData(fileDataRaw)
|
let fileData: any = fileDataRaw === null ? null : this.readData(fileDataRaw)
|
||||||
try {
|
try {
|
||||||
|
|||||||
12
sdk/package/package-lock.json
generated
12
sdk/package/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@start9labs/start-sdk",
|
"name": "@start9labs/start-sdk",
|
||||||
"version": "0.4.0-beta.6",
|
"version": "0.4.0-beta.11",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@start9labs/start-sdk",
|
"name": "@start9labs/start-sdk",
|
||||||
"version": "0.4.0-beta.6",
|
"version": "0.4.0-beta.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iarna/toml": "^3.0.0",
|
"@iarna/toml": "^3.0.0",
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"ini": "^5.0.0",
|
"ini": "^5.0.0",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mime-types": "^3.0.1",
|
"mime-types": "^3.0.1",
|
||||||
"ts-matches": "^6.2.1",
|
"ts-matches": "^6.3.2",
|
||||||
"yaml": "^2.7.1"
|
"yaml": "^2.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -4820,9 +4820,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-matches": {
|
"node_modules/ts-matches": {
|
||||||
"version": "6.2.1",
|
"version": "6.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.3.2.tgz",
|
||||||
"integrity": "sha512-qdnMgTHsGCEGGK6QiaNMY2vD9eQtRp2Q+pAxcOAzxHJKDKTBYsc1ISTg1zp8H2+EmtCB0eko/1TwYUA5/mUGug==",
|
"integrity": "sha512-UhSgJymF8cLd4y0vV29qlKVCkQpUtekAaujXbQVc729FezS8HwqzepqvtjzQ3HboatIqN/Idor85O2RMwT7lIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ts-morph": {
|
"node_modules/ts-morph": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@start9labs/start-sdk",
|
"name": "@start9labs/start-sdk",
|
||||||
"version": "0.4.0-beta.6",
|
"version": "0.4.0-beta.11",
|
||||||
"description": "Software development kit to facilitate packaging services for StartOS",
|
"description": "Software development kit to facilitate packaging services for StartOS",
|
||||||
"main": "./package/lib/index.js",
|
"main": "./package/lib/index.js",
|
||||||
"types": "./package/lib/index.d.ts",
|
"types": "./package/lib/index.d.ts",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mime-types": "^3.0.1",
|
"mime-types": "^3.0.1",
|
||||||
"ts-matches": "^6.2.1",
|
"ts-matches": "^6.3.2",
|
||||||
"yaml": "^2.7.1",
|
"yaml": "^2.7.1",
|
||||||
"deep-equality-data-structures": "^2.0.0",
|
"deep-equality-data-structures": "^2.0.0",
|
||||||
"ini": "^5.0.0",
|
"ini": "^5.0.0",
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ Additionally, there are two libraries for shared code:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
node --version
|
node --version
|
||||||
v20.17.0
|
v22.15.0
|
||||||
|
|
||||||
npm --version
|
npm --version
|
||||||
v11.1.0
|
v11.3.0
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Install and enable the Prettier extension for your text editor
|
#### Install and enable the Prettier extension for your text editor
|
||||||
|
|||||||
2
web/package-lock.json
generated
2
web/package-lock.json
generated
@@ -129,7 +129,7 @@
|
|||||||
"deep-equality-data-structures": "^1.5.0",
|
"deep-equality-data-structures": "^1.5.0",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mime-types": "^3.0.1",
|
"mime-types": "^3.0.1",
|
||||||
"ts-matches": "^6.2.1",
|
"ts-matches": "^6.3.2",
|
||||||
"yaml": "^2.7.1"
|
"yaml": "^2.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default {
|
|||||||
78: 'Serwisy',
|
78: 'Serwisy',
|
||||||
79: 'Rejestr serwisów',
|
79: 'Rejestr serwisów',
|
||||||
80: 'Instalacja ręczna',
|
80: 'Instalacja ręczna',
|
||||||
81: 'Aktualizacje',
|
81: 'Uaktualnienia',
|
||||||
82: 'Metryki',
|
82: 'Metryki',
|
||||||
83: 'Logi',
|
83: 'Logi',
|
||||||
84: 'Powiadomienia',
|
84: 'Powiadomienia',
|
||||||
@@ -106,7 +106,7 @@ export default {
|
|||||||
103: 'Czy jesteś pewien?',
|
103: 'Czy jesteś pewien?',
|
||||||
104: 'Wybierz domenę',
|
104: 'Wybierz domenę',
|
||||||
105: 'Lokalne',
|
105: 'Lokalne',
|
||||||
106: 'Adresy lokalne są dostępne tylko dla urządzeń podłączonych do tej samej sieci LAN co Twój serwer, bezpośrednio lub przez VPN.',
|
106: 'Adresy lokalne są dostępne tylko dla urządzeń podłączonych do tej samej sieci LAN co twój serwer, bezpośrednio lub przez VPN.',
|
||||||
107: 'Dowiedz się więcej',
|
107: 'Dowiedz się więcej',
|
||||||
108: 'Publiczny',
|
108: 'Publiczny',
|
||||||
109: 'Prywatny',
|
109: 'Prywatny',
|
||||||
@@ -152,7 +152,7 @@ export default {
|
|||||||
149: 'Serwisy z tego rejestru są tworzone i utrzymywane przez członków społeczności Start9. Instalujesz je na własne ryzyko. W przypadku problemów lub pytań skontaktuj się z twórcą pakietu.',
|
149: 'Serwisy z tego rejestru są tworzone i utrzymywane przez członków społeczności Start9. Instalujesz je na własne ryzyko. W przypadku problemów lub pytań skontaktuj się z twórcą pakietu.',
|
||||||
150: 'Serwisy z tego rejestru są w fazie testów beta i mogą zawierać błędy. Instalujesz je na własne ryzyko.',
|
150: 'Serwisy z tego rejestru są w fazie testów beta i mogą zawierać błędy. Instalujesz je na własne ryzyko.',
|
||||||
151: 'Serwisy z tego rejestru są w fazie testów alfa. Mogą zawierać błędy i potencjalnie uszkodzić system. Instalujesz je na własne ryzyko.',
|
151: 'Serwisy z tego rejestru są w fazie testów alfa. Mogą zawierać błędy i potencjalnie uszkodzić system. Instalujesz je na własne ryzyko.',
|
||||||
152: 'To jest rejestr niestandardowy. Start9 nie może zweryfikować integralności ani funkcjonalności serwisów z tego rejestru, a mogą one uszkodzić Twój system. Instalujesz je na własne ryzyko.',
|
152: 'To jest rejestr niestandardowy. Start9 nie może zweryfikować integralności ani funkcjonalności serwisów z tego rejestru, a mogą one uszkodzić twój system. Instalujesz je na własne ryzyko.',
|
||||||
153: 'Rejestry domyślne',
|
153: 'Rejestry domyślne',
|
||||||
154: 'Rejestry niestandardowe',
|
154: 'Rejestry niestandardowe',
|
||||||
155: 'Dodaj niestandardowy rejestr',
|
155: 'Dodaj niestandardowy rejestr',
|
||||||
@@ -238,7 +238,7 @@ export default {
|
|||||||
235: 'Oczekiwanie na wynik',
|
235: 'Oczekiwanie na wynik',
|
||||||
236: 'Uruchamianie',
|
236: 'Uruchamianie',
|
||||||
237: 'Sukces',
|
237: 'Sukces',
|
||||||
238: 'Kontrole stanu',
|
238: 'Kontrola stanu',
|
||||||
239: 'Brak kontroli stanu',
|
239: 'Brak kontroli stanu',
|
||||||
240: 'Nazwa',
|
240: 'Nazwa',
|
||||||
241: 'Status',
|
241: 'Status',
|
||||||
@@ -249,8 +249,8 @@ export default {
|
|||||||
246: 'Zobacz poniżej',
|
246: 'Zobacz poniżej',
|
||||||
247: 'Sterowanie',
|
247: 'Sterowanie',
|
||||||
248: 'Brak zainstalowanych serwisów',
|
248: 'Brak zainstalowanych serwisów',
|
||||||
249: 'Uruchomiona',
|
249: 'Uruchomiony',
|
||||||
250: 'Zatrzymana',
|
250: 'Zatrzymany',
|
||||||
251: 'Wymagane zadanie',
|
251: 'Wymagane zadanie',
|
||||||
252: 'Aktualizowanie',
|
252: 'Aktualizowanie',
|
||||||
253: 'Zatrzymywanie',
|
253: 'Zatrzymywanie',
|
||||||
@@ -323,7 +323,7 @@ export default {
|
|||||||
320: 'Utwórz kopię zapasową StartOS i danych serwisów, łącząc się z urządzeniem w sieci lokalnej lub z fizycznym dyskiem podłączonym do Twojego serwera.',
|
320: 'Utwórz kopię zapasową StartOS i danych serwisów, łącząc się z urządzeniem w sieci lokalnej lub z fizycznym dyskiem podłączonym do Twojego serwera.',
|
||||||
321: 'Przywróć StartOS i dane serwisów z urządzenia w sieci lokalnej lub z fizycznego dysku podłączonego do Twojego serwera, który zawiera istniejącą kopię zapasową.',
|
321: 'Przywróć StartOS i dane serwisów z urządzenia w sieci lokalnej lub z fizycznego dysku podłączonego do Twojego serwera, który zawiera istniejącą kopię zapasową.',
|
||||||
322: 'Ostatnia kopia zapasowa',
|
322: 'Ostatnia kopia zapasowa',
|
||||||
323: 'Folder na innym komputerze, który jest podłączony do tej samej sieci co Twój serwer Start9.',
|
323: 'Folder na innym komputerze, który jest podłączony do tej samej sieci co twój serwer Start9.',
|
||||||
324: 'Fizyczny dysk, który jest podłączony bezpośrednio do Twojego serwera Start9.',
|
324: 'Fizyczny dysk, który jest podłączony bezpośrednio do Twojego serwera Start9.',
|
||||||
325: 'Wybierz serwisy do kopii zapasowej',
|
325: 'Wybierz serwisy do kopii zapasowej',
|
||||||
326: 'Wybierz kopię zapasową serwera',
|
326: 'Wybierz kopię zapasową serwera',
|
||||||
@@ -344,9 +344,9 @@ export default {
|
|||||||
341: 'Hash pakietu',
|
341: 'Hash pakietu',
|
||||||
342: 'Opublikowano',
|
342: 'Opublikowano',
|
||||||
343: 'Nowy folder sieciowy',
|
343: 'Nowy folder sieciowy',
|
||||||
344: 'Aktualizuj folder sieciowy',
|
344: 'Uaktualnij folder sieciowy',
|
||||||
345: 'Testowanie połączenia z folderem współdzielonym',
|
345: 'Testowanie połączenia z folderem współdzielonym',
|
||||||
346: 'Upewnij się, że (1) komputer docelowy jest podłączony do tej samej sieci LAN co Twój serwer Start9, (2) folder docelowy jest udostępniany i (3) nazwa hosta, ścieżka i dane logowania są poprawne.',
|
346: 'Upewnij się, że (1) komputer docelowy jest podłączony do tej samej sieci LAN co twój serwer Start9, (2) folder docelowy jest udostępniany i (3) nazwa hosta, ścieżka i dane logowania są poprawne.',
|
||||||
347: 'Nie można połączyć',
|
347: 'Nie można połączyć',
|
||||||
348: 'Folder sieciowy nie zawiera prawidłowej kopii zapasowej',
|
348: 'Folder sieciowy nie zawiera prawidłowej kopii zapasowej',
|
||||||
349: 'Połącz',
|
349: 'Połącz',
|
||||||
@@ -450,7 +450,7 @@ export default {
|
|||||||
447: 'Nie podjęto próby',
|
447: 'Nie podjęto próby',
|
||||||
448: 'Niepowodzenie',
|
448: 'Niepowodzenie',
|
||||||
449: 'Powodzenie',
|
449: 'Powodzenie',
|
||||||
450: 'Uruchom ponownie serwer, aby te aktualizacje zostały zastosowane. Może to potrwać kilka minut, zanim będzie ponownie dostępny.',
|
450: 'Uruchom ponownie serwer, aby zastosować aktualizacje. Ponowne uruchomienie może potrwać kilka minut, zanim serwer będzie ponownie dostępny',
|
||||||
451: 'Pobieranie StartOS zakończone',
|
451: 'Pobieranie StartOS zakończone',
|
||||||
452: 'Wykryto nieznany dysk magazynujący',
|
452: 'Wykryto nieznany dysk magazynujący',
|
||||||
453: 'Aby użyć innego dysku magazynującego, wymień obecny i kliknij URUCHOM PONOWNIE SERWER poniżej. Aby użyć obecnego dysku, kliknij UŻYJ OBECNEGO DYSKU poniżej, a następnie postępuj zgodnie z instrukcjami. Żadne dane nie zostaną usunięte podczas tego procesu.',
|
453: 'Aby użyć innego dysku magazynującego, wymień obecny i kliknij URUCHOM PONOWNIE SERWER poniżej. Aby użyć obecnego dysku, kliknij UŻYJ OBECNEGO DYSKU poniżej, a następnie postępuj zgodnie z instrukcjami. Żadne dane nie zostaną usunięte podczas tego procesu.',
|
||||||
|
|||||||
Reference in New Issue
Block a user