mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
persist hostname in config overlay (#2769)
* persist hostname * add migration * fix version mismatch * remove dmesg logging from build
This commit is contained in:
2
Makefile
2
Makefile
@@ -213,7 +213,7 @@ emulate-reflash: $(ALL_TARGETS)
|
||||
@if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi
|
||||
$(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create')
|
||||
$(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM)
|
||||
$(call ssh,'sudo rm -f /media/startos/config/disk.guid')
|
||||
$(call ssh,'sudo rm -f /media/startos/config/disk.guid /media/startos/config/overlay/etc/hostname')
|
||||
$(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"')
|
||||
|
||||
upload-ota: results/$(BASENAME).squashfs
|
||||
|
||||
2
core/Cargo.lock
generated
2
core/Cargo.lock
generated
@@ -5051,7 +5051,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "start-os"
|
||||
version = "0.3.6-alpha.6"
|
||||
version = "0.3.6-alpha.7"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"async-compression",
|
||||
|
||||
@@ -14,7 +14,7 @@ keywords = [
|
||||
name = "start-os"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/Start9Labs/start-os"
|
||||
version = "0.3.6-alpha.6"
|
||||
version = "0.3.6-alpha.7"
|
||||
license = "MIT"
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::account::AccountInfo;
|
||||
use crate::context::config::ServerConfig;
|
||||
use crate::context::RpcContext;
|
||||
use crate::disk::OsPartitionInfo;
|
||||
use crate::hostname::Hostname;
|
||||
use crate::init::init_postgres;
|
||||
use crate::prelude::*;
|
||||
use crate::progress::FullProgressTracker;
|
||||
@@ -42,6 +43,8 @@ lazy_static::lazy_static! {
|
||||
pub struct SetupResult {
|
||||
pub tor_address: String,
|
||||
#[ts(type = "string")]
|
||||
pub hostname: Hostname,
|
||||
#[ts(type = "string")]
|
||||
pub lan_address: InternedString,
|
||||
pub root_ca: String,
|
||||
}
|
||||
@@ -50,6 +53,7 @@ impl TryFrom<&AccountInfo> for SetupResult {
|
||||
fn try_from(value: &AccountInfo) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
tor_address: format!("https://{}", value.tor_key.public().get_onion_address()),
|
||||
hostname: value.hostname.clone(),
|
||||
lan_address: value.hostname.lan_address(),
|
||||
root_ca: String::from_utf8(value.root_ca_cert.to_pem()?)?,
|
||||
})
|
||||
|
||||
@@ -9,6 +9,7 @@ use rpc_toolkit::{
|
||||
use crate::context::{CliContext, DiagnosticContext, RpcContext};
|
||||
use crate::init::SYSTEM_REBUILD_PATH;
|
||||
use crate::shutdown::Shutdown;
|
||||
use crate::util::io::delete_file;
|
||||
use crate::Error;
|
||||
|
||||
pub fn diagnostic<C: Context>() -> ParentHandler<C> {
|
||||
@@ -95,9 +96,7 @@ pub fn disk<C: Context>() -> ParentHandler<C> {
|
||||
}
|
||||
|
||||
pub async fn forget_disk<C: Context>(_: C) -> Result<(), Error> {
|
||||
let disk_guid = Path::new("/media/startos/config/disk.guid");
|
||||
if tokio::fs::metadata(disk_guid).await.is_ok() {
|
||||
tokio::fs::remove_file(disk_guid).await?;
|
||||
}
|
||||
delete_file("/media/startos/config/overlay/etc/hostname").await?;
|
||||
delete_file("/media/startos/config/disk.guid").await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::disk::OsPartitionInfo;
|
||||
use crate::net::utils::find_eth_iface;
|
||||
use crate::prelude::*;
|
||||
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
|
||||
use crate::util::io::{open_file, TmpDir};
|
||||
use crate::util::io::{delete_file, open_file, TmpDir};
|
||||
use crate::util::serde::IoFormat;
|
||||
use crate::util::Invoke;
|
||||
use crate::ARCH;
|
||||
@@ -180,18 +180,9 @@ pub async fn execute<C: Context>(
|
||||
{
|
||||
if let Err(e) = async {
|
||||
// cp -r ${guard}/config /tmp/config
|
||||
if tokio::fs::metadata(guard.path().join("config/upgrade"))
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
tokio::fs::remove_file(guard.path().join("config/upgrade")).await?;
|
||||
}
|
||||
if tokio::fs::metadata(guard.path().join("config/disk.guid"))
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
tokio::fs::remove_file(guard.path().join("config/disk.guid")).await?;
|
||||
}
|
||||
delete_file(guard.path().join("config/upgrade")).await?;
|
||||
delete_file(guard.path().join("config/overlay/etc/hostname")).await?;
|
||||
delete_file(guard.path().join("config/disk.guid")).await?;
|
||||
Command::new("cp")
|
||||
.arg("-r")
|
||||
.arg(guard.path().join("config"))
|
||||
|
||||
@@ -10,6 +10,7 @@ use rpc_toolkit::yajrc::RpcError;
|
||||
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::process::Command;
|
||||
use tokio::try_join;
|
||||
use tracing::instrument;
|
||||
use ts_rs::TS;
|
||||
@@ -36,6 +37,7 @@ use crate::progress::{FullProgress, PhaseProgressTrackerHandle};
|
||||
use crate::rpc_continuations::Guid;
|
||||
use crate::util::crypto::EncryptedWire;
|
||||
use crate::util::io::{create_file, dir_copy, dir_size, Counter};
|
||||
use crate::util::Invoke;
|
||||
use crate::{Error, ErrorKind, ResultExt};
|
||||
|
||||
pub fn setup<C: Context>() -> ParentHandler<C> {
|
||||
@@ -336,6 +338,11 @@ pub async fn complete(ctx: SetupContext) -> Result<SetupResult, Error> {
|
||||
let mut guid_file = create_file("/media/startos/config/disk.guid").await?;
|
||||
guid_file.write_all(ctx.disk_guid.as_bytes()).await?;
|
||||
guid_file.sync_all().await?;
|
||||
Command::new("systemd-firstboot")
|
||||
.arg("--root=/media/startos/config/overlay/")
|
||||
.arg(format!("--hostname={}", res.hostname.0))
|
||||
.invoke(ErrorKind::ParseSysInfo)
|
||||
.await?;
|
||||
Ok(res.clone())
|
||||
}
|
||||
Some(Err(e)) => Err(e.clone_output()),
|
||||
|
||||
@@ -923,6 +923,20 @@ pub async fn create_file(path: impl AsRef<Path>) -> Result<File, Error> {
|
||||
.with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("create {path:?}")))
|
||||
}
|
||||
|
||||
pub async fn delete_file(path: impl AsRef<Path>) -> Result<(), Error> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::remove_file(path)
|
||||
.await
|
||||
.or_else(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
.with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("delete {path:?}")))
|
||||
}
|
||||
|
||||
pub async fn rename(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<(), Error> {
|
||||
let src = src.as_ref();
|
||||
let dst = dst.as_ref();
|
||||
|
||||
@@ -306,7 +306,10 @@ where
|
||||
Ok(())
|
||||
}
|
||||
/// MUST be idempotent, and is run after *all* db migrations
|
||||
fn post_up(self, ctx: &RpcContext) -> impl Future<Output = Result<(), Error>> + Send + 'static {
|
||||
fn post_up<'a>(
|
||||
self,
|
||||
ctx: &'a RpcContext,
|
||||
) -> impl Future<Output = Result<(), Error>> + Send + 'a {
|
||||
async { Ok(()) }
|
||||
}
|
||||
fn down(self, db: &mut Value) -> Result<(), Error> {
|
||||
|
||||
@@ -19,6 +19,10 @@ use torut::onion::TorSecretKeyV3;
|
||||
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_5_2, VersionT};
|
||||
use crate::account::AccountInfo;
|
||||
use crate::auth::Sessions;
|
||||
use crate::backup::target::cifs::CifsTargets;
|
||||
use crate::context::RpcContext;
|
||||
use crate::db::model::Database;
|
||||
use crate::disk::mount::filesystem::cifs::Cifs;
|
||||
use crate::disk::mount::util::unmount;
|
||||
@@ -26,19 +30,15 @@ use crate::hostname::Hostname;
|
||||
use crate::net::forward::AvailablePorts;
|
||||
use crate::net::keys::KeyStore;
|
||||
use crate::net::ssl::CertStore;
|
||||
use crate::net::tor;
|
||||
use crate::net::tor::OnionStore;
|
||||
use crate::notifications::{Notification, Notifications};
|
||||
use crate::prelude::*;
|
||||
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
|
||||
use crate::ssh::{SshKeys, SshPubKey};
|
||||
use crate::util::crypto::ed25519_expand_key;
|
||||
use crate::util::serde::{Pem, PemEncoding};
|
||||
use crate::util::Invoke;
|
||||
use crate::{account::AccountInfo, net::tor};
|
||||
use crate::{auth::Sessions, context::RpcContext};
|
||||
use crate::{
|
||||
backup::target::cifs::CifsTargets,
|
||||
s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile,
|
||||
};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref V0_3_6_alpha_0: exver::Version = exver::Version::new(
|
||||
@@ -328,61 +328,58 @@ impl VersionT for Version {
|
||||
|
||||
#[instrument(skip(self, ctx))]
|
||||
/// MUST be idempotent, and is run after *all* db migrations
|
||||
fn post_up(self, ctx: &RpcContext) -> impl Future<Output = Result<(), Error>> + Send + 'static {
|
||||
let ctx = ctx.clone();
|
||||
async move {
|
||||
let path = Path::new("/embassy-data/package-data/archive/");
|
||||
async fn post_up(self, ctx: &RpcContext) -> Result<(), Error> {
|
||||
let path = Path::new("/embassy-data/package-data/archive/");
|
||||
if !path.is_dir() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"expected path ({}) to be a directory",
|
||||
path.to_string_lossy()
|
||||
),
|
||||
ErrorKind::Filesystem,
|
||||
));
|
||||
}
|
||||
// Should be the name of the package
|
||||
let mut paths = tokio::fs::read_dir(path).await?;
|
||||
while let Some(path) = paths.next_entry().await? {
|
||||
let path = path.path();
|
||||
if !path.is_dir() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"expected path ({}) to be a directory",
|
||||
path.to_string_lossy()
|
||||
),
|
||||
ErrorKind::Filesystem,
|
||||
));
|
||||
continue;
|
||||
}
|
||||
// Should be the name of the package
|
||||
// Should be the version of the package
|
||||
let mut paths = tokio::fs::read_dir(path).await?;
|
||||
while let Some(path) = paths.next_entry().await? {
|
||||
let path = path.path();
|
||||
if !path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
// Should be the version of the package
|
||||
|
||||
// Should be s9pk
|
||||
let mut paths = tokio::fs::read_dir(path).await?;
|
||||
while let Some(path) = paths.next_entry().await? {
|
||||
let path = path.path();
|
||||
if !path.is_dir() {
|
||||
if path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Should be s9pk
|
||||
let mut paths = tokio::fs::read_dir(path).await?;
|
||||
while let Some(path) = paths.next_entry().await? {
|
||||
let path = path.path();
|
||||
if path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let package_s9pk = tokio::fs::File::open(path).await?;
|
||||
let file = MultiCursorFile::open(&package_s9pk).await?;
|
||||
|
||||
let package_s9pk = tokio::fs::File::open(path).await?;
|
||||
let file = MultiCursorFile::open(&package_s9pk).await?;
|
||||
|
||||
let key = ctx.db.peek().await.into_private().into_compat_s9pk_key();
|
||||
ctx.services
|
||||
.install(
|
||||
ctx.clone(),
|
||||
|| crate::s9pk::load(file.clone(), || Ok(key.de()?.0), None),
|
||||
None::<crate::util::Never>,
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.await?
|
||||
.await?;
|
||||
}
|
||||
let key = ctx.db.peek().await.into_private().into_compat_s9pk_key();
|
||||
ctx.services
|
||||
.install(
|
||||
ctx.clone(),
|
||||
|| crate::s9pk::load(file.clone(), || Ok(key.de()?.0), None),
|
||||
None::<crate::util::Never>,
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.await?
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use exver::{PreReleaseSegment, VersionRange};
|
||||
use imbl_value::{json, InOMap};
|
||||
use tokio::process::Command;
|
||||
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_6_alpha_6, VersionT};
|
||||
use crate::prelude::*;
|
||||
use crate::util::Invoke;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref V0_3_6_alpha_7: exver::Version = exver::Version::new(
|
||||
@@ -44,6 +46,17 @@ impl VersionT for Version {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn post_up(self, ctx: &crate::context::RpcContext) -> Result<(), Error> {
|
||||
Command::new("systemd-firstboot")
|
||||
.arg("--root=/media/startos/config/overlay/")
|
||||
.arg(format!(
|
||||
"--hostname={}",
|
||||
ctx.account.read().await.hostname.0
|
||||
))
|
||||
.invoke(ErrorKind::ParseSysInfo)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
fn down(self, _db: &mut Value) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -57,13 +57,14 @@ if [ "$NON_FREE" = 1 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
PLATFORM_CONFIG_EXTRAS=
|
||||
PLATFORM_CONFIG_EXTRAS=()
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --firmware-binary false"
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --firmware-chroot false"
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --linux-flavours rpi-v8"
|
||||
PLATFORM_CONFIG_EXTRAS+=( --firmware-binary false )
|
||||
PLATFORM_CONFIG_EXTRAS+=( --firmware-chroot false )
|
||||
PLATFORM_CONFIG_EXTRAS+=( --linux-packages linux-image-6.6.51+rpt )
|
||||
PLATFORM_CONFIG_EXTRAS+=( --linux-flavours "rpi-v8 rpi-2712" )
|
||||
elif [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --linux-flavours rockchip64"
|
||||
PLATFORM_CONFIG_EXTRAS+=( --linux-flavours rockchip64 )
|
||||
fi
|
||||
|
||||
|
||||
@@ -87,7 +88,7 @@ lb config \
|
||||
--bootstrap-qemu-arch ${IB_TARGET_ARCH} \
|
||||
--bootstrap-qemu-static /usr/bin/qemu-${QEMU_ARCH}-static \
|
||||
--archive-areas "${ARCHIVE_AREAS}" \
|
||||
$PLATFORM_CONFIG_EXTRAS
|
||||
${PLATFORM_CONFIG_EXTRAS[@]}
|
||||
|
||||
# Overlays
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
export type SetupResult = {
|
||||
torAddress: string
|
||||
hostname: string
|
||||
lanAddress: string
|
||||
rootCa: string
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "startos-ui",
|
||||
"version": "0.3.6-alpha.6",
|
||||
"version": "0.3.6-alpha.7",
|
||||
"author": "Start9 Labs, Inc",
|
||||
"homepage": "https://start9.com/",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
"ackInstructions": {},
|
||||
"theme": "Dark",
|
||||
"widgets": [],
|
||||
"ack-welcome": "0.3.6-alpha.6"
|
||||
"ack-welcome": "0.3.6-alpha.7"
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ export class MockApiService extends ApiService {
|
||||
return {
|
||||
status: 'complete',
|
||||
torAddress: 'https://asdafsadasdasasdasdfasdfasdf.onion',
|
||||
hostname: 'adjective-noun',
|
||||
lanAddress: 'https://adjective-noun.local',
|
||||
rootCa: encodeBase64(rootCA),
|
||||
}
|
||||
@@ -283,6 +284,7 @@ export class MockApiService extends ApiService {
|
||||
await pauseFor(1000)
|
||||
return {
|
||||
torAddress: 'https://asdafsadasdasasdasdfasdfasdf.onion',
|
||||
hostname: 'adjective-noun',
|
||||
lanAddress: 'https://adjective-noun.local',
|
||||
rootCa: encodeBase64(rootCA),
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<ion-content class="ion-padding">
|
||||
<h2>This Release</h2>
|
||||
|
||||
<h4>0.3.6-alpha.6</h4>
|
||||
<h4>0.3.6-alpha.7</h4>
|
||||
<h6>This is an ALPHA release! DO NOT use for production data!</h6>
|
||||
<h6>
|
||||
Expect that any data you create or store on this version of the OS can be
|
||||
|
||||
Reference in New Issue
Block a user