summaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorAva Hahn <a.hahn@f5.com>2024-06-18 23:06:05 -0700
committerAva Hahn <110854134+avahahn@users.noreply.github.com>2024-06-19 15:16:40 -0700
commit57a0f94efb2550ea1c6cb593b2b968e022c89346 (patch)
tree68c5e285a92ab8201de393f95c27c13e4faa6bab /tools
parente0c15ae4575335fb079e2d33fc853a547b2380c9 (diff)
downloadunit-57a0f94efb2550ea1c6cb593b2b968e022c89346.tar.gz
unit-57a0f94efb2550ea1c6cb593b2b968e022c89346.tar.bz2
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 <a.hahn@f5.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/unitctl/Cargo.lock66
-rw-r--r--tools/unitctl/README.md14
-rw-r--r--tools/unitctl/unitctl/Cargo.toml1
-rw-r--r--tools/unitctl/unitctl/src/cmd/mod.rs1
-rw-r--r--tools/unitctl/unitctl/src/cmd/save.rs52
-rw-r--r--tools/unitctl/unitctl/src/main.rs8
-rw-r--r--tools/unitctl/unitctl/src/unitctl.rs10
7 files changed, 130 insertions, 22 deletions
diff --git a/tools/unitctl/Cargo.lock b/tools/unitctl/Cargo.lock
index 16241296..20279963 100644
--- a/tools/unitctl/Cargo.lock
+++ b/tools/unitctl/Cargo.lock
@@ -485,23 +485,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.1"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
- "errno-dragonfly",
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
-dependencies = [
- "cc",
"libc",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -511,6 +500,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
+name = "filetime"
+version = "0.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1009,9 +1010,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.150"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libloading"
@@ -1034,9 +1035,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.11"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "log"
@@ -1488,15 +1489,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
-version = "0.38.25"
+version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.4.1",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -1789,6 +1790,17 @@ dependencies = [
]
[[package]]
+name = "tar"
+version = "0.4.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
name = "tempfile"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2061,6 +2073,7 @@ dependencies = [
"serde",
"serde_json",
"serde_yaml",
+ "tar",
"tempfile",
"tokio",
"unit-client-rs",
@@ -2440,6 +2453,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
+name = "xattr"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
+dependencies = [
+ "libc",
+ "linux-raw-sys",
+ "rustix",
+]
+
+[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/tools/unitctl/README.md b/tools/unitctl/README.md
index dca16e63..74366007 100644
--- a/tools/unitctl/README.md
+++ b/tools/unitctl/README.md
@@ -177,6 +177,20 @@ Imported /opt/unit/config/put.json -> /config
Imported 3 files
```
+### Export configuration from a running Unit instance
+```
+$ unitctl export -f config.tar
+```
+
+Addtionally, standard out can be used:
+```
+$ unitctl export -f -
+$ unitctl export -f - | tar xf - config.json
+$ unitctl export -f - > config.tar
+```
+
+*Note:* The exported configuration omits certificates.
+
### Wait for socket to become available
```
$ unitctl --wait-timeout-seconds=3 --wait-max-tries=4 import /opt/unit/config`
diff --git a/tools/unitctl/unitctl/Cargo.toml b/tools/unitctl/unitctl/Cargo.toml
index 98930fb3..8d83b424 100644
--- a/tools/unitctl/unitctl/Cargo.toml
+++ b/tools/unitctl/unitctl/Cargo.toml
@@ -32,6 +32,7 @@ hyperlocal = "0.8"
hyper-tls = "0.5"
tokio = { version = "1.35", features = ["macros"] }
futures = "0.3"
+tar = "0.4.41"
[package.metadata.deb]
copyright = "2022, F5"
diff --git a/tools/unitctl/unitctl/src/cmd/mod.rs b/tools/unitctl/unitctl/src/cmd/mod.rs
index 07c50912..f2a2c120 100644
--- a/tools/unitctl/unitctl/src/cmd/mod.rs
+++ b/tools/unitctl/unitctl/src/cmd/mod.rs
@@ -5,3 +5,4 @@ pub(crate) mod import;
pub(crate) mod instances;
pub(crate) mod listeners;
pub(crate) mod status;
+pub(crate) mod save;
diff --git a/tools/unitctl/unitctl/src/cmd/save.rs b/tools/unitctl/unitctl/src/cmd/save.rs
new file mode 100644
index 00000000..bce8fdb9
--- /dev/null
+++ b/tools/unitctl/unitctl/src/cmd/save.rs
@@ -0,0 +1,52 @@
+use crate::unitctl::UnitCtl;
+use crate::wait;
+use crate::UnitctlError;
+use crate::requests::send_empty_body_deserialize_response;
+use unit_client_rs::unit_client::UnitClient;
+use tar::{Builder, Header};
+use std::fs::File;
+use std::io::stdout;
+
+
+pub async fn cmd(
+ cli: &UnitCtl,
+ filename: &String
+) -> Result<(), UnitctlError> {
+ if !filename.ends_with(".tar") {
+ eprintln!("Warning: writing uncompressed tarball to {}", filename);
+ }
+
+ let control_socket = wait::wait_for_socket(cli).await?;
+ let client = UnitClient::new(control_socket);
+
+ let config_res = serde_json::to_string_pretty(
+ &send_empty_body_deserialize_response(&client, "GET", "/config").await?
+ );
+ if let Err(e) = config_res {
+ return Err(UnitctlError::DeserializationError{message: e.to_string()})
+ }
+
+ let current_config = config_res
+ .unwrap()
+ .into_bytes();
+
+ //let current_js_modules = send_empty_body_deserialize_response(&client, "GET", "/js_modules")
+ // .await?;
+
+ let mut conf_header = Header::new_gnu();
+ conf_header.set_size(current_config.len() as u64);
+ conf_header.set_mode(0o644);
+ conf_header.set_cksum();
+
+ // builder has a different type depending on output
+ if filename == "-" {
+ let mut ar = Builder::new(stdout());
+ ar.append_data(&mut conf_header, "config.json", current_config.as_slice()).unwrap();
+ } else {
+ let file = File::create(filename).unwrap();
+ let mut ar = Builder::new(file);
+ ar.append_data(&mut conf_header, "config.json", current_config.as_slice()).unwrap();
+ }
+
+ Ok(())
+}
diff --git a/tools/unitctl/unitctl/src/main.rs b/tools/unitctl/unitctl/src/main.rs
index 6c9faaf7..8f33fc16 100644
--- a/tools/unitctl/unitctl/src/main.rs
+++ b/tools/unitctl/unitctl/src/main.rs
@@ -8,7 +8,11 @@ extern crate unit_client_rs;
use clap::Parser;
-use crate::cmd::{applications, edit, execute as execute_cmd, import, instances, listeners, status};
+use crate::cmd::{
+ applications, edit, execute as execute_cmd,
+ import, instances, listeners, status,
+ save
+};
use crate::output_format::OutputFormat;
use crate::unitctl::{Commands, UnitCtl};
use crate::unitctl_error::UnitctlError;
@@ -46,6 +50,8 @@ async fn main() -> Result<(), UnitctlError> {
Commands::Status { output_format } => status::cmd(&cli, output_format).await,
Commands::Listeners { output_format } => listeners::cmd(&cli, output_format).await,
+
+ Commands::Export { ref filename } => save::cmd(&cli, filename).await,
}
.map_err(|error| {
eprint_error(&error);
diff --git a/tools/unitctl/unitctl/src/unitctl.rs b/tools/unitctl/unitctl/src/unitctl.rs
index 47f33820..e567116b 100644
--- a/tools/unitctl/unitctl/src/unitctl.rs
+++ b/tools/unitctl/unitctl/src/unitctl.rs
@@ -116,6 +116,16 @@ pub(crate) enum Commands {
},
#[command(about = "List all configured Unit applications")]
App(ApplicationArgs),
+
+ #[command(about = "Export the current configuration of UNIT")]
+ Export {
+ #[arg(
+ required = true,
+ short = 'f',
+ help = "tarball filename to save configuration to"
+ )]
+ filename: String
+ },
}
#[derive(Debug, Args)]