From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox-offline-mirror 2/2] helper: add status command
Date: Wed, 21 Sep 2022 13:04:07 +0200 [thread overview]
Message-ID: <20220921110407.2988743-2-f.gruenbichler@proxmox.com> (raw)
In-Reply-To: <20220921110407.2988743-1-f.gruenbichler@proxmox.com>
similar to `proxmox-offline-mirror medium status <ID>`, but limited to
the information that is stored on the medium itself. this command can be
used to get a quick overview over what's on a medium, or for automated
setup of the contained repositories.
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
src/bin/proxmox-offline-mirror-helper.rs | 98 +++++++++++++++++++++++-
1 file changed, 97 insertions(+), 1 deletion(-)
diff --git a/src/bin/proxmox-offline-mirror-helper.rs b/src/bin/proxmox-offline-mirror-helper.rs
index 4efb343..353973f 100644
--- a/src/bin/proxmox-offline-mirror-helper.rs
+++ b/src/bin/proxmox-offline-mirror-helper.rs
@@ -12,7 +12,10 @@ use proxmox_sys::{fs::file_get_contents, linux::tty};
use proxmox_time::epoch_to_rfc3339_utc;
use serde_json::Value;
-use proxmox_router::cli::{run_cli_command, CliCommand, CliCommandMap, CliEnvironment};
+use proxmox_router::cli::{
+ format_and_print_result, get_output_format, run_cli_command, CliCommand, CliCommandMap,
+ CliEnvironment, OUTPUT_FORMAT,
+};
use proxmox_schema::{api, param_bail};
use proxmox_offline_mirror::helpers::tty::{
@@ -319,11 +322,104 @@ async fn setup_offline_key(
}
}
+#[api(
+ input: {
+ properties: {
+ mountpoint: {
+ type: String,
+ description: "Path to medium mountpoint",
+ },
+ "output-format": {
+ schema: OUTPUT_FORMAT,
+ optional: true,
+ },
+ },
+ },
+)]
+/// Prints status of medium
+async fn status(mountpoint: String, param: Value) -> Result<(), Error> {
+ let output_format = get_output_format(¶m);
+
+ let mountpoint = Path::new(&mountpoint);
+ if !mountpoint.exists() {
+ bail!("Medium mountpoint doesn't exist.");
+ }
+
+ let mut statefile = mountpoint.to_path_buf();
+ statefile.push(".mirror-state");
+
+ let raw = file_get_contents(&statefile)?;
+ let state: MediumState = serde_json::from_slice(&raw)?;
+
+ if output_format == "text" {
+ println!("Last sync: {}", epoch_to_rfc3339_utc(state.last_sync)?);
+ for (mirror, info) in &state.mirrors {
+ println!("\nMirror {mirror}:");
+ match medium::list_snapshots(mountpoint, mirror) {
+ Ok(snapshots) => {
+ match (snapshots.first(), snapshots.last()) {
+ (Some(first), Some(last)) if first == last => {
+ println!("1 snapshot: {}", first);
+ }
+ (Some(first), Some(last)) => {
+ println!("{} snapshots: '{first}..{last}'", snapshots.len());
+ }
+ _ => {
+ println!("No snapshots.");
+ }
+ };
+ if let Some(last) = snapshots.last() {
+ println!(
+ "repository config: {}",
+ proxmox_offline_mirror::generate_repo_file_line(
+ mountpoint, mirror, info, last
+ )?
+ );
+ }
+ }
+ Err(err) => {
+ println!("Failed to obtain snapshot list - {err}");
+ }
+ }
+ }
+ } else {
+ let mut json: serde_json::value::Map<String, Value> = serde_json::json!(state)
+ .as_object()
+ .ok_or_else(|| format_err!("Failed to serialize state file"))?
+ .to_owned();
+ for mirror in state.mirrors.keys() {
+ let mirror_json = json
+ .get_mut("mirrors")
+ .and_then(|v| v.as_object_mut())
+ .and_then(|o| o.get_mut(mirror))
+ .and_then(|v| v.as_object_mut())
+ .ok_or_else(|| format_err!("Failed to obtain JSON field for mirror {mirror}"))?;
+
+ match medium::list_snapshots(mountpoint, mirror) {
+ Ok(snapshots) => {
+ mirror_json.insert("snapshots".to_owned(), serde_json::json!(snapshots));
+ }
+ Err(err) => {
+ mirror_json.insert(
+ "errors".to_owned(),
+ serde_json::json!(format!("Failed to obtain snapshot list - {err}")),
+ );
+ }
+ }
+ }
+ json.remove("subscriptions");
+ format_and_print_result(&json.into(), &output_format);
+ }
+
+ Ok(())
+}
+
fn main() {
let rpcenv = CliEnvironment::new();
let cmd_def = CliCommandMap::new()
.insert("setup", CliCommand::new(&API_METHOD_SETUP))
+ .insert("status", CliCommand::new(&API_METHOD_STATUS))
.insert(
"offline-key",
CliCommand::new(&API_METHOD_SETUP_OFFLINE_KEY),
--
2.30.2
next prev parent reply other threads:[~2022-09-21 11:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-21 11:04 [pve-devel] [PATCH proxmox-offline-mirror 1/2] helper: make mountpoint non-optional Fabian Grünbichler
2022-09-21 11:04 ` Fabian Grünbichler [this message]
2022-10-21 11:03 ` [pve-devel] applied-series: " Wolfgang Bumiller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220921110407.2988743-2-f.gruenbichler@proxmox.com \
--to=f.gruenbichler@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox