Skip to content

Commit 57a0f94

Browse files
committed
tools/unitctl: unitctl export
* new subcommand for "export" in CLI * new cmd submodule for exporting config tarballs * logic to also output to stdout * README additions * limitations documented Signed-off-by: Ava Hahn <[email protected]>
1 parent e0c15ae commit 57a0f94

File tree

7 files changed

+130
-22
lines changed

7 files changed

+130
-22
lines changed

tools/unitctl/Cargo.lock

Lines changed: 45 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/unitctl/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,20 @@ Imported /opt/unit/config/put.json -> /config
177177
Imported 3 files
178178
```
179179

180+
### Export configuration from a running Unit instance
181+
```
182+
$ unitctl export -f config.tar
183+
```
184+
185+
Addtionally, standard out can be used:
186+
```
187+
$ unitctl export -f -
188+
$ unitctl export -f - | tar xf - config.json
189+
$ unitctl export -f - > config.tar
190+
```
191+
192+
*Note:* The exported configuration omits certificates.
193+
180194
### Wait for socket to become available
181195
```
182196
$ unitctl --wait-timeout-seconds=3 --wait-max-tries=4 import /opt/unit/config`

tools/unitctl/unitctl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ hyperlocal = "0.8"
3232
hyper-tls = "0.5"
3333
tokio = { version = "1.35", features = ["macros"] }
3434
futures = "0.3"
35+
tar = "0.4.41"
3536

3637
[package.metadata.deb]
3738
copyright = "2022, F5"

tools/unitctl/unitctl/src/cmd/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub(crate) mod import;
55
pub(crate) mod instances;
66
pub(crate) mod listeners;
77
pub(crate) mod status;
8+
pub(crate) mod save;

tools/unitctl/unitctl/src/cmd/save.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use crate::unitctl::UnitCtl;
2+
use crate::wait;
3+
use crate::UnitctlError;
4+
use crate::requests::send_empty_body_deserialize_response;
5+
use unit_client_rs::unit_client::UnitClient;
6+
use tar::{Builder, Header};
7+
use std::fs::File;
8+
use std::io::stdout;
9+
10+
11+
pub async fn cmd(
12+
cli: &UnitCtl,
13+
filename: &String
14+
) -> Result<(), UnitctlError> {
15+
if !filename.ends_with(".tar") {
16+
eprintln!("Warning: writing uncompressed tarball to {}", filename);
17+
}
18+
19+
let control_socket = wait::wait_for_socket(cli).await?;
20+
let client = UnitClient::new(control_socket);
21+
22+
let config_res = serde_json::to_string_pretty(
23+
&send_empty_body_deserialize_response(&client, "GET", "/config").await?
24+
);
25+
if let Err(e) = config_res {
26+
return Err(UnitctlError::DeserializationError{message: e.to_string()})
27+
}
28+
29+
let current_config = config_res
30+
.unwrap()
31+
.into_bytes();
32+
33+
//let current_js_modules = send_empty_body_deserialize_response(&client, "GET", "/js_modules")
34+
// .await?;
35+
36+
let mut conf_header = Header::new_gnu();
37+
conf_header.set_size(current_config.len() as u64);
38+
conf_header.set_mode(0o644);
39+
conf_header.set_cksum();
40+
41+
// builder has a different type depending on output
42+
if filename == "-" {
43+
let mut ar = Builder::new(stdout());
44+
ar.append_data(&mut conf_header, "config.json", current_config.as_slice()).unwrap();
45+
} else {
46+
let file = File::create(filename).unwrap();
47+
let mut ar = Builder::new(file);
48+
ar.append_data(&mut conf_header, "config.json", current_config.as_slice()).unwrap();
49+
}
50+
51+
Ok(())
52+
}

tools/unitctl/unitctl/src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ extern crate unit_client_rs;
88

99
use clap::Parser;
1010

11-
use crate::cmd::{applications, edit, execute as execute_cmd, import, instances, listeners, status};
11+
use crate::cmd::{
12+
applications, edit, execute as execute_cmd,
13+
import, instances, listeners, status,
14+
save
15+
};
1216
use crate::output_format::OutputFormat;
1317
use crate::unitctl::{Commands, UnitCtl};
1418
use crate::unitctl_error::UnitctlError;
@@ -46,6 +50,8 @@ async fn main() -> Result<(), UnitctlError> {
4650
Commands::Status { output_format } => status::cmd(&cli, output_format).await,
4751

4852
Commands::Listeners { output_format } => listeners::cmd(&cli, output_format).await,
53+
54+
Commands::Export { ref filename } => save::cmd(&cli, filename).await,
4955
}
5056
.map_err(|error| {
5157
eprint_error(&error);

tools/unitctl/unitctl/src/unitctl.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ pub(crate) enum Commands {
116116
},
117117
#[command(about = "List all configured Unit applications")]
118118
App(ApplicationArgs),
119+
120+
#[command(about = "Export the current configuration of UNIT")]
121+
Export {
122+
#[arg(
123+
required = true,
124+
short = 'f',
125+
help = "tarball filename to save configuration to"
126+
)]
127+
filename: String
128+
},
119129
}
120130

121131
#[derive(Debug, Args)]

0 commit comments

Comments
 (0)