mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
update ota script, rbind for dependency mounts, cli list-ingredients fix, and formatting
This commit is contained in:
@@ -15,13 +15,12 @@ if [ "$SKIP_DL" != "1" ]; then
|
||||
fi
|
||||
|
||||
if [ -n "$RUN_ID" ]; then
|
||||
for arch in aarch64 aarch64-nonfree riscv64 riscv64-nonfree x86_64 x86_64-nonfree raspberrypi; do
|
||||
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
|
||||
while ! gh run download -R Start9Labs/start-os $RUN_ID -n $arch.squashfs -D $(pwd); do sleep 1; done
|
||||
done
|
||||
for arch in aarch64 aarch64-nonfree riscv64 riscv64-nonfree x86_64 x86_64-nonfree; do
|
||||
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
|
||||
while ! gh run download -R Start9Labs/start-os $RUN_ID -n $arch.iso -D $(pwd); do sleep 1; done
|
||||
done
|
||||
while ! gh run download -R Start9Labs/start-os $RUN_ID -n raspberrypi.img -D $(pwd); do sleep 1; done
|
||||
fi
|
||||
|
||||
if [ -n "$ST_RUN_ID" ]; then
|
||||
@@ -57,31 +56,23 @@ start-cli --registry=https://alpha-registry-x.start9.com registry os version add
|
||||
if [ "$SKIP_UL" = "2" ]; then
|
||||
exit 2
|
||||
elif [ "$SKIP_UL" != "1" ]; then
|
||||
for file in *.squashfs *.iso *.deb start-cli_*; do
|
||||
for file in *.deb start-cli_*; do
|
||||
gh release upload -R Start9Labs/start-os v$VERSION $file
|
||||
done
|
||||
for file in *.img; do
|
||||
if ! [ -f $file.gz ]; then
|
||||
cat $file | pigz > $file.gz
|
||||
fi
|
||||
gh release upload -R Start9Labs/start-os v$VERSION $file.gz
|
||||
for file in *.iso *.squashfs; do
|
||||
s3cmd put -P $file s3://startos-images/v$VERSION/$file
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$SKIP_INDEX" != "1" ]; then
|
||||
for arch in aarch64 aarch64-nonfree riscv64 riscv64-nonfree x86_64 x86_64-nonfree; do
|
||||
for arch in aarch64 aarch64-nonfree riscv64 x86_64 x86_64-nonfree; do
|
||||
for file in *_$arch.squashfs *_$arch.iso; do
|
||||
start-cli --registry=https://alpha-registry-x.start9.com registry os asset add --platform=$arch --version=$VERSION $file https://github.com/Start9Labs/start-os/releases/download/v$VERSION/$(echo -n "$file" | sed 's/~/./g')
|
||||
done
|
||||
done
|
||||
for arch in raspberrypi; do
|
||||
for file in *_$arch.squashfs; do
|
||||
start-cli --registry=https://alpha-registry-x.start9.com registry os asset add --platform=$arch --version=$VERSION $file https://github.com/Start9Labs/start-os/releases/download/v$VERSION/$(echo -n "$file" | sed 's/~/./g')
|
||||
start-cli --registry=https://alpha-registry-x.start9.com registry os asset add --platform=$arch --version=$VERSION $file https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$file
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
for file in *.iso *.img *.img.gz *.squashfs *.deb start-cli_*; do
|
||||
for file in *.iso *.squashfs *.deb start-cli_*; do
|
||||
gpg -u 7CFFDA41CA66056A --detach-sign --armor -o "${file}.asc" "$file"
|
||||
done
|
||||
|
||||
@@ -90,20 +81,30 @@ tar -czvf signatures.tar.gz *.asc
|
||||
|
||||
gh release upload -R Start9Labs/start-os v$VERSION signatures.tar.gz
|
||||
|
||||
cat << EOF
|
||||
# ISO Downloads
|
||||
|
||||
- [x86_64/AMD64](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_x86_64-nonfree.iso))
|
||||
- [x86_64/AMD64 (Slim/FOSS-Only)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_x86_64.iso) "Without proprietary software or drivers")
|
||||
- [aarch64/ARM64](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_aarch64-nonfree.iso))
|
||||
- [aarch64/ARM64 (Slim/FOSS-Only)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_aarch64.iso) "Without proprietary software or drivers")
|
||||
- [RISCV64 (RVA23)](https://startos-images.nyc3.cdn.digitaloceanspaces.com/v$VERSION/$(ls *_riscv64.iso))
|
||||
|
||||
EOF
|
||||
cat << 'EOF'
|
||||
# StartOS Checksums
|
||||
|
||||
## SHA-256
|
||||
```
|
||||
EOF
|
||||
sha256sum *.iso *.img *img.gz *.squashfs
|
||||
sha256sum *.iso *.squashfs
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
## BLAKE-3
|
||||
```
|
||||
EOF
|
||||
b3sum *.iso *.img *.img.gz *.squashfs
|
||||
b3sum *.iso *.squashfs
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
@@ -139,4 +140,3 @@ b3sum start-cli_*
|
||||
cat << 'EOF'
|
||||
```
|
||||
EOF
|
||||
|
||||
|
||||
@@ -180,7 +180,13 @@ pub async fn update(
|
||||
.as_idx_mut(&id)
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("backup.target.cifs.target-not-found", id = BackupTargetId::Cifs { id })),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"backup.target.cifs.target-not-found",
|
||||
id = BackupTargetId::Cifs { id }
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
)
|
||||
})?
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use rust_i18n::t;
|
||||
|
||||
pub fn renamed(old: &str, new: &str) -> ! {
|
||||
eprintln!(
|
||||
"{}",
|
||||
t!("bins.deprecated.renamed", old = old, new = new)
|
||||
);
|
||||
eprintln!("{}", t!("bins.deprecated.renamed", old = old, new = new));
|
||||
std::process::exit(1)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::time::Duration;
|
||||
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::eyre;
|
||||
use rust_i18n::t;
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use rust_i18n::t;
|
||||
use tokio::signal::unix::signal;
|
||||
use tracing::instrument;
|
||||
|
||||
|
||||
@@ -160,21 +160,23 @@ impl CliContext {
|
||||
if !path.exists() {
|
||||
continue;
|
||||
}
|
||||
let pair = <ed25519::KeypairBytes as ed25519::pkcs8::DecodePrivateKey>::from_pkcs8_pem(
|
||||
let pair =
|
||||
<ed25519::KeypairBytes as ed25519::pkcs8::DecodePrivateKey>::from_pkcs8_pem(
|
||||
&std::fs::read_to_string(path)?,
|
||||
)
|
||||
.with_kind(crate::ErrorKind::Pem)?;
|
||||
let secret = ed25519_dalek::SecretKey::try_from(&pair.secret_key[..]).map_err(|_| {
|
||||
let secret =
|
||||
ed25519_dalek::SecretKey::try_from(&pair.secret_key[..]).map_err(|_| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("context.cli.pkcs8-key-incorrect-length")),
|
||||
ErrorKind::OpenSsl,
|
||||
)
|
||||
})?;
|
||||
return Ok(secret.into())
|
||||
return Ok(secret.into());
|
||||
}
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("context.cli.developer-key-does-not-exist")),
|
||||
crate::ErrorKind::Uninitialized
|
||||
crate::ErrorKind::Uninitialized,
|
||||
))
|
||||
})
|
||||
}
|
||||
@@ -195,8 +197,12 @@ impl CliContext {
|
||||
.into());
|
||||
}
|
||||
};
|
||||
url.set_scheme(ws_scheme)
|
||||
.map_err(|_| Error::new(eyre!("{}", t!("context.cli.cannot-set-url-scheme")), crate::ErrorKind::ParseUrl))?;
|
||||
url.set_scheme(ws_scheme).map_err(|_| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("context.cli.cannot-set-url-scheme")),
|
||||
crate::ErrorKind::ParseUrl,
|
||||
)
|
||||
})?;
|
||||
url.path_segments_mut()
|
||||
.map_err(|_| eyre!("Url cannot be base"))
|
||||
.with_kind(crate::ErrorKind::ParseUrl)?
|
||||
|
||||
@@ -27,7 +27,10 @@ impl DiagnosticContext {
|
||||
disk_guid: Option<InternedString>,
|
||||
error: Error,
|
||||
) -> Result<Self, Error> {
|
||||
tracing::error!("{}", t!("context.diagnostic.starting-diagnostic-ui", error = error));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("context.diagnostic.starting-diagnostic-ui", error = error)
|
||||
);
|
||||
tracing::debug!("{:?}", error);
|
||||
|
||||
let (shutdown, _) = tokio::sync::broadcast::channel(1);
|
||||
|
||||
@@ -463,7 +463,10 @@ impl RpcContext {
|
||||
.await
|
||||
.result
|
||||
{
|
||||
tracing::error!("{}", t!("context.rpc.error-in-session-cleanup-cron", error = e));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("context.rpc.error-in-session-cleanup-cron", error = e)
|
||||
);
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,11 @@ pub enum RevisionsRes {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub struct CliDumpParams {
|
||||
#[arg(long = "include-private", short = 'p', help = "help.arg.include-private-data")]
|
||||
#[arg(
|
||||
long = "include-private",
|
||||
short = 'p',
|
||||
help = "help.arg.include-private-data"
|
||||
)]
|
||||
#[serde(default)]
|
||||
include_private: bool,
|
||||
#[arg(help = "help.arg.db-path")]
|
||||
|
||||
@@ -70,12 +70,20 @@ async fn e2fsck_runner(
|
||||
if code & 4 != 0 {
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("disk.fsck.errors-not-corrected", device = logicalname.as_ref().display(), stderr = e2fsck_stderr),
|
||||
t!(
|
||||
"disk.fsck.errors-not-corrected",
|
||||
device = logicalname.as_ref().display(),
|
||||
stderr = e2fsck_stderr
|
||||
),
|
||||
);
|
||||
} else if code & 1 != 0 {
|
||||
tracing::warn!(
|
||||
"{}",
|
||||
t!("disk.fsck.errors-corrected", device = logicalname.as_ref().display(), stderr = e2fsck_stderr),
|
||||
t!(
|
||||
"disk.fsck.errors-corrected",
|
||||
device = logicalname.as_ref().display(),
|
||||
stderr = e2fsck_stderr
|
||||
),
|
||||
);
|
||||
}
|
||||
if code < 8 {
|
||||
|
||||
@@ -29,25 +29,31 @@ impl Default for FileType {
|
||||
pub struct Bind<Src: AsRef<Path>> {
|
||||
src: Src,
|
||||
filetype: FileType,
|
||||
recursive: bool,
|
||||
}
|
||||
impl<Src: AsRef<Path>> Bind<Src> {
|
||||
pub fn new(src: Src) -> Self {
|
||||
Self {
|
||||
src,
|
||||
filetype: FileType::Directory,
|
||||
recursive: false,
|
||||
}
|
||||
}
|
||||
pub fn with_type(mut self, filetype: FileType) -> Self {
|
||||
self.filetype = filetype;
|
||||
self
|
||||
}
|
||||
pub fn recursive(mut self, recursive: bool) -> Self {
|
||||
self.recursive = recursive;
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<Src: AsRef<Path> + Send + Sync> FileSystem for Bind<Src> {
|
||||
async fn source(&self) -> Result<Option<impl AsRef<Path>>, Error> {
|
||||
Ok(Some(&self.src))
|
||||
}
|
||||
fn extra_args(&self) -> impl IntoIterator<Item = impl AsRef<std::ffi::OsStr>> {
|
||||
["--bind"]
|
||||
[if self.recursive { "--rbind" } else { "--bind" }]
|
||||
}
|
||||
async fn pre_mount(&self, mountpoint: &Path, mount_type: MountType) -> Result<(), Error> {
|
||||
let from_meta = tokio::fs::metadata(&self.src).await.ok();
|
||||
|
||||
@@ -24,7 +24,11 @@ pub async fn bind<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
) -> Result<(), Error> {
|
||||
tracing::info!(
|
||||
"{}",
|
||||
t!("disk.mount.binding", src = src.as_ref().display(), dst = dst.as_ref().display())
|
||||
t!(
|
||||
"disk.mount.binding",
|
||||
src = src.as_ref().display(),
|
||||
dst = dst.as_ref().display()
|
||||
)
|
||||
);
|
||||
if is_mountpoint(&dst).await? {
|
||||
unmount(dst.as_ref(), true).await?;
|
||||
|
||||
@@ -183,7 +183,8 @@ impl ErrorKind {
|
||||
UpdateFailed => t!("error.update-failed"),
|
||||
Smtp => t!("error.smtp"),
|
||||
SetSysInfo => t!("error.set-sys-info"),
|
||||
}.to_string()
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
impl Display for ErrorKind {
|
||||
|
||||
@@ -6,7 +6,6 @@ use std::str::FromStr;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
use axum::extract::ws;
|
||||
use crate::util::net::WebSocket;
|
||||
use chrono::{DateTime, Utc};
|
||||
use clap::builder::ValueParserFactory;
|
||||
use clap::{Args, FromArgMatches, Parser};
|
||||
@@ -31,6 +30,7 @@ use crate::context::{CliContext, RpcContext};
|
||||
use crate::error::ResultExt;
|
||||
use crate::prelude::*;
|
||||
use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
|
||||
use crate::util::net::WebSocket;
|
||||
use crate::util::serde::Reversible;
|
||||
use crate::util::{FromStrParser, Invoke};
|
||||
|
||||
@@ -330,12 +330,22 @@ pub struct LogsParams<Extra: FromArgMatches + Args = Empty> {
|
||||
extra: Extra,
|
||||
#[arg(short = 'l', long = "limit", help = "help.arg.log-limit")]
|
||||
limit: Option<usize>,
|
||||
#[arg(short = 'c', long = "cursor", conflicts_with = "follow", help = "help.arg.log-cursor")]
|
||||
#[arg(
|
||||
short = 'c',
|
||||
long = "cursor",
|
||||
conflicts_with = "follow",
|
||||
help = "help.arg.log-cursor"
|
||||
)]
|
||||
cursor: Option<String>,
|
||||
#[arg(short = 'b', long = "boot", help = "help.arg.log-boot")]
|
||||
#[serde(default)]
|
||||
boot: Option<BootIdentifier>,
|
||||
#[arg(short = 'B', long = "before", conflicts_with = "follow", help = "help.arg.log-before")]
|
||||
#[arg(
|
||||
short = 'B',
|
||||
long = "before",
|
||||
conflicts_with = "follow",
|
||||
help = "help.arg.log-before"
|
||||
)]
|
||||
#[serde(default)]
|
||||
before: bool,
|
||||
}
|
||||
@@ -553,9 +563,11 @@ pub async fn journalctl(
|
||||
follow_cmd.arg("--lines=0");
|
||||
}
|
||||
let mut child = follow_cmd.stdout(Stdio::piped()).spawn()?;
|
||||
let out =
|
||||
BufReader::new(child.stdout.take().ok_or_else(|| {
|
||||
Error::new(eyre!("{}", t!("logs.no-stdout-available")), crate::ErrorKind::Journald)
|
||||
let out = BufReader::new(child.stdout.take().ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("logs.no-stdout-available")),
|
||||
crate::ErrorKind::Journald,
|
||||
)
|
||||
})?);
|
||||
|
||||
let journalctl_entries = LinesStream::new(out.lines());
|
||||
@@ -701,7 +713,10 @@ pub async fn follow_logs<Context: AsRef<RpcContinuations>>(
|
||||
RpcContinuation::ws(
|
||||
move |socket| async move {
|
||||
if let Err(e) = ws_handler(first_entry, stream, socket).await {
|
||||
tracing::error!("{}", t!("logs.error-in-log-stream", error = e.to_string()));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("logs.error-in-log-stream", error = e.to_string())
|
||||
);
|
||||
}
|
||||
},
|
||||
Duration::from_secs(30),
|
||||
|
||||
@@ -40,7 +40,10 @@ impl LocalAuthContext for RpcContext {
|
||||
}
|
||||
|
||||
fn unauthorized() -> Error {
|
||||
Error::new(eyre!("{}", t!("middleware.auth.unauthorized")), crate::ErrorKind::Authorization)
|
||||
Error::new(
|
||||
eyre!("{}", t!("middleware.auth.unauthorized")),
|
||||
crate::ErrorKind::Authorization,
|
||||
)
|
||||
}
|
||||
|
||||
async fn check_from_header<C: LocalAuthContext>(header: Option<&HeaderValue>) -> Result<(), Error> {
|
||||
|
||||
@@ -244,7 +244,10 @@ impl ValidSessionToken {
|
||||
C::access_sessions(db)
|
||||
.as_idx_mut(session_hash)
|
||||
.ok_or_else(|| {
|
||||
Error::new(eyre!("{}", t!("middleware.auth.unauthorized")), crate::ErrorKind::Authorization)
|
||||
Error::new(
|
||||
eyre!("{}", t!("middleware.auth.unauthorized")),
|
||||
crate::ErrorKind::Authorization,
|
||||
)
|
||||
})?
|
||||
.mutate(|s| {
|
||||
s.last_active = Utc::now();
|
||||
|
||||
@@ -347,6 +347,10 @@ pub async fn call_remote<Ctx: SigningContext + AsRef<Client>>(
|
||||
.with_kind(ErrorKind::Deserialization)?
|
||||
.result
|
||||
}
|
||||
_ => Err(Error::new(eyre!("{}", t!("middleware.auth.unknown-content-type")), ErrorKind::Network).into()),
|
||||
_ => Err(Error::new(
|
||||
eyre!("{}", t!("middleware.auth.unknown-content-type")),
|
||||
ErrorKind::Network,
|
||||
)
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,13 @@ impl Middleware<RpcContext> for SyncDb {
|
||||
}
|
||||
.await
|
||||
{
|
||||
tracing::error!("{}", t!("middleware.db.error-writing-patch-sequence-header", error = e));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"middleware.db.error-writing-patch-sequence-header",
|
||||
error = e
|
||||
)
|
||||
);
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,13 @@ impl PortForwardController {
|
||||
}
|
||||
.await
|
||||
{
|
||||
tracing::error!("{}", t!("net.forward.error-initializing-controller", error = format!("{e:#}")));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"net.forward.error-initializing-controller",
|
||||
error = format!("{e:#}")
|
||||
)
|
||||
);
|
||||
tracing::debug!("{e:?}");
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
|
||||
@@ -171,16 +171,13 @@ where
|
||||
let mut tls_handler = self.tls_handler.clone();
|
||||
let mut fut = async move {
|
||||
let res = async {
|
||||
let mut acceptor = LazyConfigAcceptor::new(
|
||||
Acceptor::default(),
|
||||
BackTrackingIO::new(stream),
|
||||
);
|
||||
let mut acceptor =
|
||||
LazyConfigAcceptor::new(Acceptor::default(), BackTrackingIO::new(stream));
|
||||
let mut mid: tokio_rustls::StartHandshake<BackTrackingIO<AcceptStream>> =
|
||||
match (&mut acceptor).await {
|
||||
Ok(a) => a,
|
||||
Err(e) => {
|
||||
let mut stream =
|
||||
acceptor.take_io().or_not_found("acceptor io")?;
|
||||
let mut stream = acceptor.take_io().or_not_found("acceptor io")?;
|
||||
let (_, buf) = stream.rewind();
|
||||
if std::str::from_utf8(buf)
|
||||
.ok()
|
||||
|
||||
@@ -324,7 +324,12 @@ pub async fn list_keys(ctx: RpcContext) -> Result<BTreeSet<OnionAddress>, Error>
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub struct ResetParams {
|
||||
#[arg(name = "wipe-state", short = 'w', long = "wipe-state", help = "help.arg.wipe-tor-state")]
|
||||
#[arg(
|
||||
name = "wipe-state",
|
||||
short = 'w',
|
||||
long = "wipe-state",
|
||||
help = "help.arg.wipe-tor-state"
|
||||
)]
|
||||
wipe_state: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,12 @@ pub async fn list_keys(ctx: RpcContext) -> Result<BTreeSet<OnionAddress>, Error>
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub struct ResetParams {
|
||||
#[arg(name = "wipe-state", short = 'w', long = "wipe-state", help = "help.arg.wipe-tor-state")]
|
||||
#[arg(
|
||||
name = "wipe-state",
|
||||
short = 'w',
|
||||
long = "wipe-state",
|
||||
help = "help.arg.wipe-tor-state"
|
||||
)]
|
||||
wipe_state: bool,
|
||||
#[arg(help = "help.arg.reset-reason")]
|
||||
reason: String,
|
||||
|
||||
@@ -94,7 +94,12 @@ impl Model<BTreeMap<Guid, SignerInfo>> {
|
||||
.next()
|
||||
.transpose()?
|
||||
.map(|(a, _)| a)
|
||||
.ok_or_else(|| Error::new(eyre!("{}", t!("registry.admin.unknown-signer")), ErrorKind::Authorization))
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.admin.unknown-signer")),
|
||||
ErrorKind::Authorization,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_signer_info(&self, key: &AnyVerifyingKey) -> Result<(Guid, SignerInfo), Error> {
|
||||
@@ -104,7 +109,12 @@ impl Model<BTreeMap<Guid, SignerInfo>> {
|
||||
.filter_ok(|(_, s)| s.keys.contains(key))
|
||||
.next()
|
||||
.transpose()?
|
||||
.ok_or_else(|| Error::new(eyre!("{}", t!("registry.admin.unknown-signer")), ErrorKind::Authorization))
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.admin.unknown-signer")),
|
||||
ErrorKind::Authorization,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_signer(&mut self, signer: &SignerInfo) -> Result<Guid, Error> {
|
||||
@@ -119,7 +129,11 @@ impl Model<BTreeMap<Guid, SignerInfo>> {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("registry.admin.signer-already-exists", guid = guid, name = s.name)
|
||||
t!(
|
||||
"registry.admin.signer-already-exists",
|
||||
guid = guid,
|
||||
name = s.name
|
||||
)
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
|
||||
@@ -44,7 +44,11 @@ const DEFAULT_REGISTRY_LISTEN: SocketAddr =
|
||||
pub struct RegistryConfig {
|
||||
#[arg(short = 'c', long = "config", help = "help.arg.config-file-path")]
|
||||
pub config: Option<PathBuf>,
|
||||
#[arg(short = 'l', long = "listen", help = "help.arg.registry-listen-address")]
|
||||
#[arg(
|
||||
short = 'l',
|
||||
long = "listen",
|
||||
help = "help.arg.registry-listen-address"
|
||||
)]
|
||||
pub registry_listen: Option<SocketAddr>,
|
||||
#[arg(short = 'H', long = "hostname", help = "help.arg.registry-hostname")]
|
||||
pub registry_hostname: Vec<InternedString>,
|
||||
@@ -52,7 +56,11 @@ pub struct RegistryConfig {
|
||||
pub tor_proxy: Option<Url>,
|
||||
#[arg(short = 'd', long = "datadir", help = "help.arg.data-directory")]
|
||||
pub datadir: Option<PathBuf>,
|
||||
#[arg(short = 'u', long = "pg-connection-url", help = "help.arg.postgres-connection-url")]
|
||||
#[arg(
|
||||
short = 'u',
|
||||
long = "pg-connection-url",
|
||||
help = "help.arg.postgres-connection-url"
|
||||
)]
|
||||
pub pg_connection_url: Option<String>,
|
||||
}
|
||||
impl ContextConfig for RegistryConfig {
|
||||
@@ -195,9 +203,11 @@ impl CallRemote<RegistryContext> for CliContext {
|
||||
.push("v0");
|
||||
url
|
||||
} else {
|
||||
return Err(
|
||||
Error::new(eyre!("{}", t!("registry.context.registry-required")), ErrorKind::InvalidRequest).into(),
|
||||
);
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("registry.context.registry-required")),
|
||||
ErrorKind::InvalidRequest,
|
||||
)
|
||||
.into());
|
||||
};
|
||||
|
||||
if let Ok(local) = cookie {
|
||||
@@ -331,7 +341,10 @@ impl SignatureAuthContext for RegistryContext {
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::new(eyre!("{}", t!("registry.context.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.context.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
async fn post_auth_hook(
|
||||
&self,
|
||||
|
||||
@@ -154,7 +154,10 @@ async fn add_asset(
|
||||
})?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.os.asset.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.os.asset.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
@@ -231,10 +234,12 @@ pub async fn cli_add_asset(
|
||||
|
||||
sign_phase.start();
|
||||
let blake3 = file.blake3_mmap().await?;
|
||||
let size = file
|
||||
.size()
|
||||
.await
|
||||
.ok_or_else(|| Error::new(eyre!("{}", t!("registry.os.asset.failed-read-metadata")), ErrorKind::Filesystem))?;
|
||||
let size = file.size().await.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.os.asset.failed-read-metadata")),
|
||||
ErrorKind::Filesystem,
|
||||
)
|
||||
})?;
|
||||
let commitment = Blake3Commitment {
|
||||
hash: Base64(*blake3.as_bytes()),
|
||||
size,
|
||||
@@ -336,7 +341,10 @@ async fn remove_asset(
|
||||
.remove(&platform)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.os.asset.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.os.asset.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -125,17 +125,9 @@ pub struct CliGetOsAssetParams {
|
||||
pub version: Version,
|
||||
#[arg(help = "help.arg.platform")]
|
||||
pub platform: InternedString,
|
||||
#[arg(
|
||||
long = "download",
|
||||
short = 'd',
|
||||
help = "help.arg.download-directory"
|
||||
)]
|
||||
#[arg(long = "download", short = 'd', help = "help.arg.download-directory")]
|
||||
pub download: Option<PathBuf>,
|
||||
#[arg(
|
||||
long = "reverify",
|
||||
short = 'r',
|
||||
help = "help.arg.reverify-hash"
|
||||
)]
|
||||
#[arg(long = "reverify", short = 'r', help = "help.arg.reverify-hash")]
|
||||
pub reverify: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,10 @@ async fn sign_asset(
|
||||
.contains(&guid)
|
||||
{
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("registry.os.asset.signer-not-authorized", guid = guid)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("registry.os.asset.signer-not-authorized", guid = guid)
|
||||
),
|
||||
ErrorKind::Authorization,
|
||||
));
|
||||
}
|
||||
@@ -184,10 +187,12 @@ pub async fn cli_sign_asset(
|
||||
|
||||
sign_phase.start();
|
||||
let blake3 = file.blake3_mmap().await?;
|
||||
let size = file
|
||||
.size()
|
||||
.await
|
||||
.ok_or_else(|| Error::new(eyre!("{}", t!("registry.os.asset.failed-read-metadata")), ErrorKind::Filesystem))?;
|
||||
let size = file.size().await.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.os.asset.failed-read-metadata")),
|
||||
ErrorKind::Filesystem,
|
||||
)
|
||||
})?;
|
||||
let commitment = Blake3Commitment {
|
||||
hash: Base64(*blake3.as_bytes()),
|
||||
size,
|
||||
|
||||
@@ -26,7 +26,6 @@ pub fn os_api<C: Context>() -> ParentHandler<C> {
|
||||
)
|
||||
.subcommand(
|
||||
"version",
|
||||
version::version_api::<C>()
|
||||
.with_about("about.commands-add-remove-list-versions"),
|
||||
version::version_api::<C>().with_about("about.commands-add-remove-list-versions"),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,14 @@ pub async fn remove_version_signer(
|
||||
.mutate(|s| Ok(s.remove(&signer)))?
|
||||
{
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("registry.os.version.signer-not-authorized", signer = signer, version = version)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"registry.os.version.signer-not-authorized",
|
||||
signer = signer,
|
||||
version = version
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -112,7 +112,10 @@ pub async fn add_package(
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.package.add.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.package.add.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
@@ -228,8 +231,12 @@ pub async fn remove_package(
|
||||
}: RemovePackageParams,
|
||||
) -> Result<bool, Error> {
|
||||
let peek = ctx.db.peek().await;
|
||||
let signer =
|
||||
signer.ok_or_else(|| Error::new(eyre!("{}", t!("registry.package.missing-signer")), ErrorKind::InvalidRequest))?;
|
||||
let signer = signer.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.package.missing-signer")),
|
||||
ErrorKind::InvalidRequest,
|
||||
)
|
||||
})?;
|
||||
let signer_guid = peek.as_index().as_signers().get_signer(&signer)?;
|
||||
|
||||
let rev = ctx
|
||||
@@ -270,7 +277,10 @@ pub async fn remove_package(
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.package.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.package.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await;
|
||||
@@ -345,7 +355,10 @@ pub async fn add_mirror(
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.package.add-mirror.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.package.add-mirror.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
@@ -461,8 +474,12 @@ pub async fn remove_mirror(
|
||||
}: RemoveMirrorParams,
|
||||
) -> Result<(), Error> {
|
||||
let peek = ctx.db.peek().await;
|
||||
let signer =
|
||||
signer.ok_or_else(|| Error::new(eyre!("{}", t!("registry.package.missing-signer")), ErrorKind::InvalidRequest))?;
|
||||
let signer = signer.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("registry.package.missing-signer")),
|
||||
ErrorKind::InvalidRequest,
|
||||
)
|
||||
})?;
|
||||
let signer_guid = peek.as_index().as_signers().get_signer(&signer)?;
|
||||
|
||||
ctx.db
|
||||
@@ -501,7 +518,10 @@ pub async fn remove_mirror(
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("registry.package.remove-mirror.unauthorized")), ErrorKind::Authorization))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("registry.package.remove-mirror.unauthorized")),
|
||||
ErrorKind::Authorization,
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -52,10 +52,14 @@ pub fn package_api<C: Context>() -> ParentHandler<C> {
|
||||
if !changed {
|
||||
tracing::warn!(
|
||||
"{}",
|
||||
t!("registry.package.remove-not-exist",
|
||||
t!(
|
||||
"registry.package.remove-not-exist",
|
||||
id = args.params.id,
|
||||
version = args.params.version,
|
||||
sighash = args.params.sighash.map_or(String::new(), |h| format!("#{h}"))
|
||||
sighash = args
|
||||
.params
|
||||
.sighash
|
||||
.map_or(String::new(), |h| format!("#{h}"))
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -96,7 +100,6 @@ pub fn package_api<C: Context>() -> ParentHandler<C> {
|
||||
)
|
||||
.subcommand(
|
||||
"category",
|
||||
category::category_api::<C>()
|
||||
.with_about("about.update-categories-registry"),
|
||||
category::category_api::<C>().with_about("about.update-categories-registry"),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,14 @@ pub async fn remove_package_signer(
|
||||
.is_some()
|
||||
{
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("registry.package.signer.not-authorized", signer = signer, id = id)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"registry.package.signer.not-authorized",
|
||||
signer = signer,
|
||||
id = id
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -385,13 +385,17 @@ impl ImageSource {
|
||||
pub fn ingredients(&self) -> Vec<PathBuf> {
|
||||
match self {
|
||||
Self::Packed => Vec::new(),
|
||||
Self::DockerBuild { dockerfile, .. } => {
|
||||
vec![
|
||||
dockerfile
|
||||
Self::DockerBuild {
|
||||
dockerfile,
|
||||
workdir,
|
||||
..
|
||||
} => {
|
||||
vec![dockerfile.clone().unwrap_or_else(|| {
|
||||
workdir
|
||||
.as_deref()
|
||||
.unwrap_or(Path::new("Dockerfile"))
|
||||
.to_owned(),
|
||||
]
|
||||
.unwrap_or(Path::new("."))
|
||||
.join("Dockerfile")
|
||||
})]
|
||||
}
|
||||
Self::DockerTag(_) => Vec::new(),
|
||||
}
|
||||
|
||||
@@ -102,7 +102,13 @@ pub fn update_tasks(
|
||||
}
|
||||
}
|
||||
None => {
|
||||
tracing::error!("{}", t!("service.action.action-request-invalid-state", task = format!("{:?}", v.task)));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.action.action-request-invalid-state",
|
||||
task = format!("{:?}", v.task)
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -151,7 +157,10 @@ impl Handler<RunAction> for ServiceActor {
|
||||
.de()?;
|
||||
if matches!(&action.visibility, ActionVisibility::Disabled(_)) {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.action.action-is-disabled", action_id = action_id)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("service.action.action-is-disabled", action_id = action_id)
|
||||
),
|
||||
ErrorKind::Action,
|
||||
));
|
||||
}
|
||||
@@ -162,7 +171,13 @@ impl Handler<RunAction> for ServiceActor {
|
||||
_ => false,
|
||||
} {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.action.service-not-in-allowed-status", action_id = action_id)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.action.service-not-in-allowed-status",
|
||||
action_id = action_id
|
||||
)
|
||||
),
|
||||
ErrorKind::Action,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -181,7 +181,10 @@ async fn run_action(
|
||||
|
||||
if package_id != &context.seed.id {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.effects.action.calling-actions-on-other-packages-unsupported")),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("service.effects.action.calling-actions-on-other-packages-unsupported")
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
context
|
||||
@@ -226,7 +229,10 @@ async fn create_task(
|
||||
TaskCondition::InputNotMatches => {
|
||||
let Some(input) = task.input.as_ref() else {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.effects.action.input-not-matches-requires-input")),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("service.effects.action.input-not-matches-requires-input")
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
};
|
||||
@@ -244,7 +250,12 @@ async fn create_task(
|
||||
else {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"{}", t!("service.effects.action.action-has-no-input", action_id = task.action_id, package_id = task.package_id)
|
||||
"{}",
|
||||
t!(
|
||||
"service.effects.action.action-has-no-input",
|
||||
action_id = task.action_id,
|
||||
package_id = task.package_id
|
||||
)
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
|
||||
@@ -79,7 +79,7 @@ pub async fn mount(
|
||||
}
|
||||
|
||||
IdMapped::new(
|
||||
Bind::new(source).with_type(filetype),
|
||||
Bind::new(source).with_type(filetype).recursive(true),
|
||||
IdMap::stack(
|
||||
vec![IdMap {
|
||||
from_id: 0,
|
||||
|
||||
@@ -28,7 +28,6 @@ use tokio_tungstenite::tungstenite::protocol::frame::coding::CloseCode;
|
||||
use ts_rs::TS;
|
||||
use url::Url;
|
||||
|
||||
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::db::model::package::{
|
||||
InstalledState, ManifestPreference, PackageState, PackageStateMatchModelRef, TaskSeverity,
|
||||
@@ -184,7 +183,10 @@ impl ServiceRef {
|
||||
Arc::try_unwrap(service.seed)
|
||||
.map_err(|_| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("service.mod.service-actor-seed-held-after-shutdown")),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("service.mod.service-actor-seed-held-after-shutdown")
|
||||
),
|
||||
ErrorKind::Unknown,
|
||||
)
|
||||
})?
|
||||
@@ -376,12 +378,16 @@ impl Service {
|
||||
{
|
||||
Ok(PackageState::Installed(InstalledState { manifest }))
|
||||
} else {
|
||||
Err(Error::new(eyre!("{}", t!("service.mod.race-condition-detected")), ErrorKind::Database))
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("service.mod.race-condition-detected")),
|
||||
ErrorKind::Database,
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.await.result?;
|
||||
.await
|
||||
.result?;
|
||||
handle_installed(s9pk).await
|
||||
}
|
||||
PackageStateMatchModelRef::Removing(_) | PackageStateMatchModelRef::Restoring(_) => {
|
||||
@@ -447,7 +453,13 @@ impl Service {
|
||||
handle_installed(S9pk::open(s9pk_path, Some(id)).await?).await
|
||||
}
|
||||
PackageStateMatchModelRef::Error(e) => Err(Error::new(
|
||||
eyre!("{}", t!("service.mod.failed-to-parse-package-data-entry", error = format!("{e:?}"))),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.mod.failed-to-parse-package-data-entry",
|
||||
error = format!("{e:?}")
|
||||
)
|
||||
),
|
||||
ErrorKind::Deserialization,
|
||||
)),
|
||||
}
|
||||
@@ -553,7 +565,11 @@ impl Service {
|
||||
true
|
||||
} else {
|
||||
tracing::warn!(
|
||||
"{}", t!("service.mod.deleting-task-action-no-longer-exists", id = id)
|
||||
"{}",
|
||||
t!(
|
||||
"service.mod.deleting-task-action-no-longer-exists",
|
||||
id = id
|
||||
)
|
||||
);
|
||||
false
|
||||
}
|
||||
@@ -791,7 +807,12 @@ pub async fn attach(
|
||||
.join("\n");
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"{}", t!("service.mod.no-matching-subcontainers", id = id, subcontainers = subcontainers)
|
||||
"{}",
|
||||
t!(
|
||||
"service.mod.no-matching-subcontainers",
|
||||
id = id,
|
||||
subcontainers = subcontainers
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
));
|
||||
@@ -830,7 +851,14 @@ pub async fn attach(
|
||||
.map(format_subcontainer_pair)
|
||||
.join("\n");
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.mod.multiple-subcontainers-found", id = id, subcontainer_ids = subcontainer_ids)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.mod.multiple-subcontainers-found",
|
||||
id = id,
|
||||
subcontainer_ids = subcontainer_ids
|
||||
)
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
}
|
||||
@@ -1120,7 +1148,13 @@ async fn get_passwd_command(etc_passwd_path: PathBuf, user: &str) -> RootCommand
|
||||
}
|
||||
}
|
||||
Err(Error::new(
|
||||
eyre!("{}", t!("service.mod.could-not-parse-etc-passwd", contents = contents)),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.mod.could-not-parse-etc-passwd",
|
||||
contents = contents
|
||||
)
|
||||
),
|
||||
ErrorKind::Filesystem,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -364,7 +364,14 @@ impl PersistentContainer {
|
||||
let handle = NonDetachingJoinHandle::from(tokio::spawn(async move {
|
||||
let chown_status = async {
|
||||
let res = server.run_unix(&path, |err| {
|
||||
tracing::error!("{}", t!("service.persistent-container.error-on-unix-socket", path = path.display(), error = err))
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.persistent-container.error-on-unix-socket",
|
||||
path = path.display(),
|
||||
error = err
|
||||
)
|
||||
)
|
||||
})?;
|
||||
Command::new("chown")
|
||||
.arg("100000:100000")
|
||||
@@ -386,7 +393,10 @@ impl PersistentContainer {
|
||||
}));
|
||||
let shutdown = recv.await.map_err(|_| {
|
||||
Error::new(
|
||||
eyre!("{}", t!("service.persistent-container.unix-socket-server-panicked")),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("service.persistent-container.unix-socket-server-panicked")
|
||||
),
|
||||
ErrorKind::Unknown,
|
||||
)
|
||||
})??;
|
||||
@@ -473,7 +483,13 @@ impl PersistentContainer {
|
||||
if let Some(destroy) = self.destroy(uninit) {
|
||||
destroy.await?;
|
||||
}
|
||||
tracing::info!("{}", t!("service.persistent-container.service-exited", id = self.s9pk.as_manifest().id));
|
||||
tracing::info!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.persistent-container.service-exited",
|
||||
id = self.s9pk.as_manifest().id
|
||||
)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -47,9 +47,18 @@ impl Actor for ServiceActor {
|
||||
}
|
||||
.await
|
||||
{
|
||||
tracing::error!("{}", t!("service.service-actor.error-synchronizing-state", error = e));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("service.service-actor.error-synchronizing-state", error = e)
|
||||
);
|
||||
tracing::debug!("{e:?}");
|
||||
tracing::error!("{}", t!("service.service-actor.retrying-in-seconds", seconds = SYNC_RETRY_COOLDOWN_SECONDS));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.service-actor.retrying-in-seconds",
|
||||
seconds = SYNC_RETRY_COOLDOWN_SECONDS
|
||||
)
|
||||
);
|
||||
tokio::time::timeout(
|
||||
Duration::from_secs(SYNC_RETRY_COOLDOWN_SECONDS),
|
||||
async {
|
||||
|
||||
@@ -62,7 +62,13 @@ pub async fn cleanup(ctx: &RpcContext, id: &PackageId, soft: bool) -> Result<(),
|
||||
| PackageState::Removing(InstalledState { manifest }) => manifest,
|
||||
s => {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("service.uninstall.invalid-package-state-for-cleanup", state = format!("{s:?}"))),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"service.uninstall.invalid-package-state-for-cleanup",
|
||||
state = format!("{s:?}")
|
||||
)
|
||||
),
|
||||
ErrorKind::InvalidRequest,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
use crate::PLATFORM;
|
||||
use crate::context::RpcContext;
|
||||
use crate::disk::main::export;
|
||||
@@ -36,18 +35,33 @@ impl Shutdown {
|
||||
.invoke(crate::ErrorKind::Journald)
|
||||
.await
|
||||
{
|
||||
tracing::error!("{}", t!("shutdown.error-stopping-journald", error = e.to_string()));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!("shutdown.error-stopping-journald", error = e.to_string())
|
||||
);
|
||||
tracing::debug!("{:?}", e);
|
||||
}
|
||||
if let Some(guid) = &self.disk_guid {
|
||||
if let Err(e) = export(guid, crate::DATA_DIR).await {
|
||||
tracing::error!("{}", t!("shutdown.error-exporting-volume-group", error = e.to_string()));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"shutdown.error-exporting-volume-group",
|
||||
error = e.to_string()
|
||||
)
|
||||
);
|
||||
tracing::debug!("{:?}", e);
|
||||
}
|
||||
}
|
||||
if &*PLATFORM != "raspberrypi" || self.restart {
|
||||
if let Err(e) = SHUTDOWN.play().await {
|
||||
tracing::error!("{}", t!("shutdown.error-playing-shutdown-song", error = e.to_string()));
|
||||
tracing::error!(
|
||||
"{}",
|
||||
t!(
|
||||
"shutdown.error-playing-shutdown-song",
|
||||
error = e.to_string()
|
||||
)
|
||||
);
|
||||
tracing::debug!("{:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
|
||||
.subcommand("web", super::web::web_api::<C>())
|
||||
.subcommand(
|
||||
"db",
|
||||
super::db::db_api::<C>()
|
||||
.with_about("about.commands-interact-with-db-dump-apply"),
|
||||
super::db::db_api::<C>().with_about("about.commands-interact-with-db-dump-apply"),
|
||||
)
|
||||
.subcommand(
|
||||
"auth",
|
||||
|
||||
@@ -179,7 +179,10 @@ pub async fn cli_update_system(
|
||||
Some(v) => {
|
||||
if let Some(progress) = res.progress {
|
||||
let mut ws = context.ws_continuation(progress).await?;
|
||||
let mut progress = PhasedProgressBar::new(&t!("update.updating-to-version", version = v.to_string()));
|
||||
let mut progress = PhasedProgressBar::new(&t!(
|
||||
"update.updating-to-version",
|
||||
version = v.to_string()
|
||||
));
|
||||
let mut prev = None;
|
||||
while let Some(msg) = ws.try_next().await.with_kind(ErrorKind::Network)? {
|
||||
if let tokio_tungstenite::tungstenite::Message::Text(msg) = msg {
|
||||
@@ -202,7 +205,10 @@ pub async fn cli_update_system(
|
||||
}
|
||||
println!("{}", t!("update.complete-restart-to-apply"))
|
||||
} else {
|
||||
println!("{}", t!("update.updating-to-version", version = v.to_string()))
|
||||
println!(
|
||||
"{}",
|
||||
t!("update.updating-to-version", version = v.to_string())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,11 @@ impl WebSocket {
|
||||
if self.ping_state.is_some() {
|
||||
self.fused = true;
|
||||
break Poll::Ready(Some(Err(axum::Error::new(eyre!(
|
||||
"{}", t!("util.net.websocket-ping-timeout", timeout = format!("{PING_TIMEOUT:?}"))
|
||||
"{}",
|
||||
t!(
|
||||
"util.net.websocket-ping-timeout",
|
||||
timeout = format!("{PING_TIMEOUT:?}")
|
||||
)
|
||||
)))));
|
||||
}
|
||||
self.ping_state = Some((false, rand::random()));
|
||||
|
||||
@@ -1151,7 +1151,13 @@ pub fn apply_expr(input: jaq_core::Val, expr: &str) -> Result<jaq_core::Val, Err
|
||||
|
||||
let Some(expr) = expr else {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("util.serde.failed-to-parse-expression", errors = format!("{:?}", errs))),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"util.serde.failed-to-parse-expression",
|
||||
errors = format!("{:?}", errs)
|
||||
)
|
||||
),
|
||||
crate::ErrorKind::InvalidRequest,
|
||||
));
|
||||
};
|
||||
@@ -1167,7 +1173,13 @@ pub fn apply_expr(input: jaq_core::Val, expr: &str) -> Result<jaq_core::Val, Err
|
||||
|
||||
if !errs.is_empty() {
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("util.serde.failed-to-compile-expression", errors = format!("{:?}", errs))),
|
||||
eyre!(
|
||||
"{}",
|
||||
t!(
|
||||
"util.serde.failed-to-compile-expression",
|
||||
errors = format!("{:?}", errs)
|
||||
)
|
||||
),
|
||||
crate::ErrorKind::InvalidRequest,
|
||||
));
|
||||
};
|
||||
|
||||
@@ -50,7 +50,10 @@ pub async fn prompt<T, E: std::fmt::Display, Parse: FnMut(&str) -> Result<T, E>>
|
||||
}
|
||||
}
|
||||
ReadlineEvent::Eof | ReadlineEvent::Interrupted => {
|
||||
return Err(Error::new(eyre!("{}", t!("util.tui.aborted")), ErrorKind::Cancelled));
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("util.tui.aborted")),
|
||||
ErrorKind::Cancelled,
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@@ -83,7 +86,10 @@ pub async fn prompt_multiline<
|
||||
Err(e) => writeln!(&mut rl_ctx.shared_writer, "{e}")?,
|
||||
},
|
||||
ReadlineEvent::Eof | ReadlineEvent::Interrupted => {
|
||||
return Err(Error::new(eyre!("{}", t!("util.tui.aborted")), ErrorKind::Cancelled));
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("util.tui.aborted")),
|
||||
ErrorKind::Cancelled,
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@@ -119,7 +125,10 @@ pub async fn choose_custom_display<'t, T>(
|
||||
.await
|
||||
.map_err(map_miette)?;
|
||||
if choice.len() < 1 {
|
||||
return Err(Error::new(eyre!("{}", t!("util.tui.aborted")), ErrorKind::Cancelled));
|
||||
return Err(Error::new(
|
||||
eyre!("{}", t!("util.tui.aborted")),
|
||||
ErrorKind::Cancelled,
|
||||
));
|
||||
}
|
||||
let (idx, choice_str) = string_choices
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user