]> git.proxmox.com Git - proxmox-backup.git/blob - src/bin/proxmox-daily-update.rs
split out pbs-runtime module
[proxmox-backup.git] / src / bin / proxmox-daily-update.rs
1 use anyhow::Error;
2 use serde_json::{json, Value};
3
4 use proxmox::api::{cli::*, RpcEnvironment, ApiHandler};
5
6 use proxmox_backup::api2;
7 use proxmox_backup::tools::subscription;
8
9 async fn wait_for_local_worker(upid_str: &str) -> Result<(), Error> {
10 let upid: proxmox_backup::server::UPID = upid_str.parse()?;
11 let sleep_duration = core::time::Duration::new(0, 100_000_000);
12
13 loop {
14 if !proxmox_backup::server::worker_is_active_local(&upid) {
15 break;
16 }
17 tokio::time::sleep(sleep_duration).await;
18 }
19 Ok(())
20 }
21
22 /// Daily update
23 async fn do_update(
24 rpcenv: &mut dyn RpcEnvironment,
25 ) -> Result<Value, Error> {
26 let param = json!({});
27
28 let method = &api2::node::subscription::API_METHOD_CHECK_SUBSCRIPTION;
29 let _res = match method.handler {
30 ApiHandler::Sync(handler) => (handler)(param, method, rpcenv)?,
31 _ => unreachable!(),
32 };
33
34 let notify = match subscription::read_subscription() {
35 Ok(Some(subscription)) => subscription.status == subscription::SubscriptionStatus::ACTIVE,
36 Ok(None) => false,
37 Err(err) => {
38 eprintln!("Error reading subscription - {}", err);
39 false
40 },
41 };
42
43 let param = json!({
44 "notify": notify,
45 });
46 let method = &api2::node::apt::API_METHOD_APT_UPDATE_DATABASE;
47 let upid = match method.handler {
48 ApiHandler::Sync(handler) => (handler)(param, method, rpcenv)?,
49 _ => unreachable!(),
50 };
51 wait_for_local_worker(upid.as_str().unwrap()).await?;
52
53 match check_acme_certificates(rpcenv).await {
54 Ok(()) => (),
55 Err(err) => {
56 eprintln!("error checking certificates: {}", err);
57 }
58 }
59
60 // TODO: cleanup tasks like in PVE?
61
62 Ok(Value::Null)
63 }
64
65 async fn check_acme_certificates(rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
66 let (config, _) = proxmox_backup::config::node::config()?;
67
68 // do we even have any acme domains configures?
69 if config.acme_domains().next().is_none() {
70 return Ok(());
71 }
72
73 if !api2::node::certificates::cert_expires_soon()? {
74 println!("Certificate does not expire within the next 30 days, not renewing.");
75 return Ok(());
76 }
77
78 let info = &api2::node::certificates::API_METHOD_RENEW_ACME_CERT;
79 let result = match info.handler {
80 ApiHandler::Sync(handler) => (handler)(json!({}), info, rpcenv)?,
81 _ => unreachable!(),
82 };
83 wait_for_local_worker(result.as_str().unwrap()).await?;
84
85 Ok(())
86 }
87
88 fn main() {
89 proxmox_backup::tools::setup_safe_path_env();
90
91 let mut rpcenv = CliEnvironment::new();
92 rpcenv.set_auth_id(Some(String::from("root@pam")));
93
94 if let Err(err) = pbs_runtime::main(do_update(&mut rpcenv)) {
95 eprintln!("error during update: {}", err);
96 std::process::exit(1);
97 }
98 }