server/cli/src/repo_key_cli.rs
//! `holger repo-key` — the repository signing key of the deb and rpm views, on this box
//! (lane HOL-SIGNED-APT-DNF, `server_lib::repo_sign`).
//!
//! | verb | what |
//! |---|---|
//! | `create --config <ron>` | make this box's key in the data root's key store (once; 0600), print its public half |
//! | `show --config <ron>` | print the public key `/-/repo-key.asc` serves |
//!
//! The public key goes to stdout (an armored `PGP PUBLIC KEY BLOCK`, what apt's `signed-by=`
//! and dnf's `gpgkey=` take); the fingerprint and the file go to stderr. The secret key is
//! never printed.
use std::path::PathBuf;
use anyhow::Result;
use clap::{Args, Subcommand};
use server_lib::repo_sign;
#[derive(Args)]
pub struct RepoKeyArgs {
#[command(subcommand)]
pub verb: RepoKeyVerb,
}
#[derive(Subcommand)]
pub enum RepoKeyVerb {
/// Make this box's repository signing key (an Ed25519 OpenPGP key, in
/// `<data root>/repo-signing/secret.asc`, mode 0600), once, and print its public half.
/// A key already there is never replaced: remove the file first to make a new one.
Create {
#[arg(short, long)]
config: PathBuf,
/// The key's user ID (what apt and gpg print beside the fingerprint).
#[arg(long, default_value = repo_sign::DEFAULT_USER_ID)]
user_id: String,
},
/// Print this box's public repository key (what `/-/repo-key.asc` serves).
Show {
#[arg(short, long)]
config: PathBuf,
},
}
/// `holger repo-key`.
pub fn run(a: RepoKeyArgs) -> Result<()> {
match a.verb {
RepoKeyVerb::Create { config, user_id } => {
let root = server_lib::read_ron_config(&config)?.data_root();
let key = repo_sign::create(&root, &user_id)?;
eprintln!(
"made the repository signing key {} ({}) in {}; the deb and rpm views sign with it \
from the next start, and {} serves the public key below",
key.fingerprint_hex(),
key.user_id(),
repo_sign::secret_path(&root).display(),
repo_sign::KEY_PATH
);
print!("{}", key.public_armor());
}
RepoKeyVerb::Show { config } => {
let root = server_lib::read_ron_config(&config)?.data_root();
let Some(key) = repo_sign::load(&root)? else {
anyhow::bail!("{}", repo_sign::NO_KEY);
};
eprintln!("{} ({})", key.fingerprint_hex(), key.user_id());
print!("{}", key.public_armor());
}
}
Ok(())
}