Skip to content

Commit 19610be

Browse files
authored
Merge pull request #663 from HuijingHei/drop-systemd-service
Drop systemd service
2 parents 8f1f8f8 + 261fb5e commit 19610be

File tree

14 files changed

+79
-423
lines changed

14 files changed

+79
-423
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ jobs:
5353
device=$(losetup --list --noheadings --output NAME,BACK-FILE | grep myimage.raw | awk '{print $1}')
5454
sudo mount "${device}p2" /mnt/
5555
sudo ls /mnt/EFI/centos/{grub.cfg,shimx64.efi}
56+
sudo umount /mnt
5657
sudo losetup -D "${device}"
5758
sudo rm -f myimage.raw
5859
- name: bootc install to filesystem

Makefile

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ ifeq ($(CONTAINER_RUNTIME), podman)
1818
IMAGE_PREFIX = localhost/
1919
endif
2020

21-
units = $(addprefix systemd/, bootupd.service bootupd.socket)
22-
2321
.PHONY: all
24-
all: $(units)
22+
all:
2523
cargo build ${CARGO_ARGS}
2624
ln -f target/${PROFILE}/bootupd target/${PROFILE}/bootupctl
2725

@@ -33,17 +31,11 @@ create-build-container:
3331
build-in-container: create-build-container
3432
${CONTAINER_RUNTIME} run -ti --rm -v .:/srv/bootupd:z ${IMAGE_PREFIX}${IMAGE_NAME} make
3533

36-
.PHONY: install-units
37-
install-units: $(units)
38-
for unit in $(units); do install -D -m 644 --target-directory=$(DESTDIR)$(PREFIX)/lib/systemd/system/ $$unit; done
39-
4034
.PHONY: install
41-
install: install-units
35+
install:
4236
mkdir -p "${DESTDIR}$(PREFIX)/bin" "${DESTDIR}$(LIBEXECDIR)"
4337
install -D -t "${DESTDIR}$(LIBEXECDIR)" target/${PROFILE}/bootupd
4438
ln -f ${DESTDIR}$(LIBEXECDIR)/bootupd ${DESTDIR}$(PREFIX)/bin/bootupctl
45-
install -d "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants"
46-
ln -s ../bootupd.socket "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants"
4739

4840
install-grub-static:
4941
install -m 644 -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg

contrib/packaging/bootupd.spec

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,6 @@ cargo build --release
5252
%make_install INSTALL="install -p -c"
5353
make install-grub-static DESTDIR=%{?buildroot} INSTALL="%{__install} -p"
5454

55-
%post -n %{crate}
56-
%systemd_post bootupd.service bootupd.socket
57-
58-
%preun -n %{crate}
59-
%systemd_preun bootupd.service bootupd.socket
60-
61-
%postun -n %{crate}
62-
%systemd_postun bootupd.service bootupd.socket
63-
6455
%changelog
6556
* Tue Oct 18 2022 Colin Walters <[email protected]> - 0.2.8-3
6657
- Dummy changelog

src/bootupd.rs

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,18 @@
11
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))]
22
use crate::bios;
3+
use crate::component;
34
use crate::component::{Component, ValidationResult};
45
use crate::coreos;
56
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
67
use crate::efi;
78
use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status};
89
use crate::util;
9-
use crate::{component, ipc};
1010
use anyhow::{anyhow, Context, Result};
1111
use serde::{Deserialize, Serialize};
1212
use std::borrow::Cow;
1313
use std::collections::BTreeMap;
1414
use std::path::Path;
1515

16-
/// A message sent from client to server
17-
#[derive(Debug, Serialize, Deserialize)]
18-
pub(crate) enum ClientRequest {
19-
/// Update a component
20-
Update { component: String },
21-
/// Update a component via adoption
22-
AdoptAndUpdate { component: String },
23-
/// Validate a component
24-
Validate { component: String },
25-
/// Print the current state
26-
Status,
27-
}
28-
2916
pub(crate) enum ConfigMode {
3017
None,
3118
Static,
@@ -408,8 +395,8 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {
408395
Ok(())
409396
}
410397

411-
pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> {
412-
let status: Status = c.send(&ClientRequest::Status)?;
398+
pub(crate) fn client_run_update() -> Result<()> {
399+
let status: Status = status()?;
413400
if status.components.is_empty() && status.adoptable.is_empty() {
414401
println!("No components installed.");
415402
return Ok(());
@@ -420,9 +407,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result
420407
ComponentUpdatable::Upgradable => {}
421408
_ => continue,
422409
};
423-
match c.send(&ClientRequest::Update {
424-
component: name.to_string(),
425-
})? {
410+
match update(name)? {
426411
ComponentUpdateResult::AtLatestVersion => {
427412
// Shouldn't happen unless we raced with another client
428413
eprintln!(
@@ -450,9 +435,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result
450435
}
451436
for (name, adoptable) in status.adoptable.iter() {
452437
if adoptable.confident {
453-
let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate {
454-
component: name.to_string(),
455-
})?;
438+
let r: ContentMetadata = adopt_and_update(name)?;
456439
println!("Adopted and updated: {}: {}", name, r.version);
457440
updated = true;
458441
} else {
@@ -465,32 +448,28 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result
465448
Ok(())
466449
}
467450

468-
pub(crate) fn client_run_adopt_and_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> {
469-
let status: Status = c.send(&ClientRequest::Status)?;
451+
pub(crate) fn client_run_adopt_and_update() -> Result<()> {
452+
let status: Status = status()?;
470453
if status.adoptable.is_empty() {
471454
println!("No components are adoptable.");
472455
} else {
473456
for (name, _) in status.adoptable.iter() {
474-
let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate {
475-
component: name.to_string(),
476-
})?;
457+
let r: ContentMetadata = adopt_and_update(name)?;
477458
println!("Adopted and updated: {}: {}", name, r.version);
478459
}
479460
}
480461
Ok(())
481462
}
482463

483-
pub(crate) fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> {
484-
let status: Status = c.send(&ClientRequest::Status)?;
464+
pub(crate) fn client_run_validate() -> Result<()> {
465+
let status: Status = status()?;
485466
if status.components.is_empty() {
486467
println!("No components installed.");
487468
return Ok(());
488469
}
489470
let mut caught_validation_error = false;
490471
for (name, _) in status.components.iter() {
491-
match c.send(&ClientRequest::Validate {
492-
component: name.to_string(),
493-
})? {
472+
match validate(name)? {
494473
ValidationResult::Valid => {
495474
println!("Validated: {}", name);
496475
}

src/cli/bootupctl.rs

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
use crate::bootupd;
2-
use crate::ipc::ClientToDaemonConnection;
3-
use crate::model::Status;
42
use anyhow::Result;
53
use clap::Parser;
64
use log::LevelFilter;
75

6+
use std::os::unix::process::CommandExt;
7+
use std::process::Command;
8+
9+
static SYSTEMD_ARGS_BOOTUPD: &[&str] = &[
10+
"--unit",
11+
"bootupd",
12+
"--property",
13+
"PrivateNetwork=yes",
14+
"--property",
15+
"ProtectHome=yes",
16+
"--property",
17+
"MountFlags=slave",
18+
"--pipe",
19+
];
20+
821
/// `bootupctl` sub-commands.
922
#[derive(Debug, Parser)]
1023
#[clap(name = "bootupctl", about = "Bootupd client application", version)]
@@ -87,10 +100,8 @@ impl CtlCommand {
87100

88101
/// Runner for `status` verb.
89102
fn run_status(opts: StatusOpts) -> Result<()> {
90-
let mut client = ClientToDaemonConnection::new();
91-
client.connect()?;
92-
93-
let r: Status = client.send(&bootupd::ClientRequest::Status)?;
103+
ensure_running_in_systemd()?;
104+
let r = bootupd::status()?;
94105
if opts.json {
95106
let stdout = std::io::stdout();
96107
let mut stdout = stdout.lock();
@@ -101,38 +112,54 @@ impl CtlCommand {
101112
bootupd::print_status(&r)?;
102113
}
103114

104-
client.shutdown()?;
105115
Ok(())
106116
}
107117

108118
/// Runner for `update` verb.
109119
fn run_update() -> Result<()> {
110-
let mut client = ClientToDaemonConnection::new();
111-
client.connect()?;
112-
113-
bootupd::client_run_update(&mut client)?;
114-
115-
client.shutdown()?;
116-
Ok(())
120+
ensure_running_in_systemd()?;
121+
bootupd::client_run_update()
117122
}
118123

119124
/// Runner for `update` verb.
120125
fn run_adopt_and_update() -> Result<()> {
121-
let mut client = ClientToDaemonConnection::new();
122-
client.connect()?;
123-
124-
bootupd::client_run_adopt_and_update(&mut client)?;
125-
126-
client.shutdown()?;
127-
Ok(())
126+
ensure_running_in_systemd()?;
127+
bootupd::client_run_adopt_and_update()
128128
}
129129

130130
/// Runner for `validate` verb.
131131
fn run_validate() -> Result<()> {
132-
let mut client = ClientToDaemonConnection::new();
133-
client.connect()?;
134-
bootupd::client_run_validate(&mut client)?;
135-
client.shutdown()?;
136-
Ok(())
132+
ensure_running_in_systemd()?;
133+
bootupd::client_run_validate()
134+
}
135+
}
136+
137+
/// Checks if the current process is (apparently at least)
138+
/// running under systemd.
139+
fn running_in_systemd() -> bool {
140+
std::env::var_os("INVOCATION_ID").is_some()
141+
}
142+
143+
/// Require root permission
144+
fn require_root_permission() -> Result<()> {
145+
if !nix::unistd::Uid::effective().is_root() {
146+
anyhow::bail!("This command requires root privileges")
147+
}
148+
Ok(())
149+
}
150+
151+
/// Detect if we're running in systemd; if we're not, we re-exec ourselves via
152+
/// systemd-run. Then we can just directly run code in what is now the daemon.
153+
fn ensure_running_in_systemd() -> Result<()> {
154+
require_root_permission()?;
155+
let running_in_systemd = running_in_systemd();
156+
if !running_in_systemd {
157+
let r = Command::new("systemd-run")
158+
.args(SYSTEMD_ARGS_BOOTUPD)
159+
.args(std::env::args())
160+
.exec();
161+
// If we got here, it's always an error
162+
return Err(r.into());
137163
}
164+
Ok(())
138165
}

src/cli/bootupd.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ impl DCommand {
3131
/// CLI sub-commands.
3232
#[derive(Debug, Parser)]
3333
pub enum DVerb {
34-
#[clap(name = "daemon", about = "Run service logic")]
35-
Daemon,
3634
#[clap(name = "generate-update-metadata", about = "Generate metadata")]
3735
GenerateUpdateMetadata(GenerateOpts),
3836
#[clap(name = "install", about = "Install components")]
@@ -88,7 +86,6 @@ impl DCommand {
8886
/// Run CLI application.
8987
pub fn run(self) -> Result<()> {
9088
match self.cmd {
91-
DVerb::Daemon => crate::daemon::run(),
9289
DVerb::Install(opts) => Self::run_install(opts),
9390
DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts),
9491
}

src/cli/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ mod tests {
6262
#[test]
6363
fn test_multicall_dispatch() {
6464
{
65-
let d_argv = vec!["/usr/bin/bootupd".to_string(), "daemon".to_string()];
65+
let d_argv = vec![
66+
"/usr/bin/bootupd".to_string(),
67+
"generate-update-metadata".to_string(),
68+
];
6669
let cli = MultiCall::from_args(d_argv);
6770
match cli {
6871
MultiCall::Ctl(cmd) => panic!("{:?}", cmd),
@@ -89,12 +92,15 @@ mod tests {
8992

9093
#[test]
9194
fn test_verbosity() {
92-
let default = MultiCall::from_args(vec!["bootupd".to_string(), "daemon".to_string()]);
95+
let default = MultiCall::from_args(vec![
96+
"bootupd".to_string(),
97+
"generate-update-metadata".to_string(),
98+
]);
9399
assert_eq!(default.loglevel(), LevelFilter::Warn);
94100

95101
let info = MultiCall::from_args(vec![
96102
"bootupd".to_string(),
97-
"daemon".to_string(),
103+
"generate-update-metadata".to_string(),
98104
"-v".to_string(),
99105
]);
100106
assert_eq!(info.loglevel(), LevelFilter::Info);

0 commit comments

Comments
 (0)