mirror of
https://github.com/michael-yuji/xc.git
synced 2026-03-17 22:35:43 +01:00
add a new patch action to modify image config and redirect action for better port redirect insight
This commit is contained in:
@@ -21,9 +21,11 @@
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
// SUCH DAMAGE.
|
||||
use clap::Subcommand;
|
||||
use clap::{Parser, Subcommand};
|
||||
use oci_util::image_reference::ImageReference;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use varutil::string_interpolation::Var;
|
||||
use xc::models::{jail_image::JailConfig, EnvSpec};
|
||||
use xcd::ipc::*;
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
@@ -37,13 +39,60 @@ pub(crate) enum ImageAction {
|
||||
Show {
|
||||
image_id: String,
|
||||
},
|
||||
GetMeta {
|
||||
GetConfig {
|
||||
image_id: String,
|
||||
},
|
||||
ReplaceMeta {
|
||||
SetConfig {
|
||||
image_id: String,
|
||||
meta_path: String,
|
||||
},
|
||||
#[clap(subcommand)]
|
||||
Patch(PatchActions),
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub(crate) enum PatchActions {
|
||||
AddEnv {
|
||||
#[clap(long, action)]
|
||||
required: bool,
|
||||
#[clap(short = 'd', long = "description")]
|
||||
description: Option<String>,
|
||||
env: String,
|
||||
image_reference: ImageReference,
|
||||
},
|
||||
}
|
||||
|
||||
fn patch_image<F>(
|
||||
conn: &mut UnixStream,
|
||||
image_reference: &ImageReference,
|
||||
f: F,
|
||||
) -> Result<(), crate::ActionError>
|
||||
where
|
||||
F: FnOnce(&mut JailConfig),
|
||||
{
|
||||
let image_name = &image_reference.name;
|
||||
let tag = &image_reference.tag;
|
||||
let reqt = DescribeImageRequest {
|
||||
image_name: image_name.to_string(),
|
||||
tag: tag.to_string(),
|
||||
};
|
||||
let res = do_describe_image(conn, reqt)?;
|
||||
match res {
|
||||
Err(e) => {
|
||||
eprintln!("{e:#?}");
|
||||
}
|
||||
Ok(res) => {
|
||||
let mut config = res.jail_image.jail_config();
|
||||
f(&mut config);
|
||||
let req = SetConfigRequest {
|
||||
name: image_name.to_string(),
|
||||
tag: tag.to_string(),
|
||||
config,
|
||||
};
|
||||
_ = do_replace_meta(conn, req)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn use_image_action(
|
||||
@@ -51,6 +100,25 @@ pub(crate) fn use_image_action(
|
||||
action: ImageAction,
|
||||
) -> Result<(), crate::ActionError> {
|
||||
match action {
|
||||
ImageAction::Patch(patch) => match patch {
|
||||
PatchActions::AddEnv {
|
||||
required,
|
||||
description,
|
||||
env,
|
||||
image_reference,
|
||||
} => {
|
||||
patch_image(conn, &image_reference, |config| {
|
||||
let env_var = Var::new(env).expect("invalid environment variable name");
|
||||
config.envs.insert(
|
||||
env_var,
|
||||
EnvSpec {
|
||||
description,
|
||||
required,
|
||||
},
|
||||
);
|
||||
})?;
|
||||
}
|
||||
},
|
||||
ImageAction::Import {
|
||||
image_id,
|
||||
path,
|
||||
@@ -99,7 +167,7 @@ pub(crate) fn use_image_action(
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageAction::GetMeta { image_id } => {
|
||||
ImageAction::GetConfig { image_id } => {
|
||||
let (image_name, tag) = image_id.rsplit_once(':').expect("invalid image id");
|
||||
let reqt = DescribeImageRequest {
|
||||
image_name: image_name.to_string(),
|
||||
@@ -116,13 +184,13 @@ pub(crate) fn use_image_action(
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageAction::ReplaceMeta {
|
||||
ImageAction::SetConfig {
|
||||
image_id,
|
||||
meta_path,
|
||||
} => {
|
||||
let (name, tag) = image_id.rsplit_once(':').expect("invalid image id");
|
||||
|
||||
let meta: xc::models::jail_image::JailConfig = if meta_path == *"-" {
|
||||
let config: xc::models::jail_image::JailConfig = if meta_path == *"-" {
|
||||
//let input = std::io::read_to_string(std::io::stdin())?;
|
||||
serde_json::from_reader(std::io::stdin()).unwrap()
|
||||
} else {
|
||||
@@ -133,10 +201,10 @@ pub(crate) fn use_image_action(
|
||||
serde_json::from_reader(meta_file).unwrap()
|
||||
};
|
||||
|
||||
let req = ReplaceMetaRequest {
|
||||
let req = SetConfigRequest {
|
||||
name: name.to_string(),
|
||||
tag: tag.to_string(),
|
||||
meta,
|
||||
config,
|
||||
};
|
||||
let manifest = do_replace_meta(conn, req)?;
|
||||
// let manifest = request(conn, "replace_meta", req)?;
|
||||
|
||||
@@ -27,12 +27,14 @@ mod error;
|
||||
mod format;
|
||||
mod image;
|
||||
mod network;
|
||||
mod redirect;
|
||||
|
||||
use crate::channel::{use_channel_action, ChannelAction};
|
||||
use crate::error::ActionError;
|
||||
use crate::format::{BindMount, EnvPair, IpWant, PublishSpec};
|
||||
use crate::image::{use_image_action, ImageAction};
|
||||
use crate::network::{use_network_action, NetworkAction};
|
||||
use crate::redirect::{use_rdr_action, RdrAction};
|
||||
|
||||
use clap::Parser;
|
||||
use freebsd::event::{eventfd, EventFdNotify};
|
||||
@@ -42,7 +44,6 @@ use oci_util::digest::OciDigest;
|
||||
use oci_util::image_reference::ImageReference;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::io::{stdin, Read};
|
||||
use std::os::fd::{AsRawFd, IntoRawFd};
|
||||
use std::os::unix::net::UnixStream;
|
||||
use term_table::homogeneous::{TableLayout, TableSource, Title};
|
||||
@@ -134,11 +135,8 @@ enum Action {
|
||||
image_reference: ImageReference,
|
||||
new_image_reference: ImageReference,
|
||||
},
|
||||
Rdr {
|
||||
#[clap(long = "publish", short = 'p', multiple_occurrences = true)]
|
||||
publish: Vec<PublishSpec>,
|
||||
name: String,
|
||||
},
|
||||
#[clap(subcommand)]
|
||||
Rdr(RdrAction),
|
||||
Run {
|
||||
#[clap(long, default_value_t, action)]
|
||||
no_clean: bool,
|
||||
@@ -246,8 +244,8 @@ fn main() -> Result<(), ActionError> {
|
||||
eprintln!("{res:#?}");
|
||||
}
|
||||
Action::Kill { name } => {
|
||||
let req = DestroyContainerRequest { name };
|
||||
let res = do_destroy_container(&mut conn, req)?.unwrap();
|
||||
let req = KillContainerRequest { name };
|
||||
let res = do_kill_container(&mut conn, req)?.unwrap();
|
||||
eprintln!("{res:#?}");
|
||||
}
|
||||
Action::Link { name } => {
|
||||
@@ -284,7 +282,6 @@ fn main() -> Result<(), ActionError> {
|
||||
}
|
||||
|
||||
let password = password.unwrap_or_else(|| {
|
||||
let mut password = String::new();
|
||||
print!("Enter password: \n");
|
||||
rpassword::read_password().unwrap()
|
||||
});
|
||||
@@ -435,18 +432,8 @@ fn main() -> Result<(), ActionError> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Action::Rdr { name, publish } => {
|
||||
for expose in publish.iter() {
|
||||
let redirection = expose.to_host_spec();
|
||||
let request = DoRdr {
|
||||
name: name.clone(),
|
||||
redirection,
|
||||
};
|
||||
if let Ok(response) = do_rdr_container(&mut conn, request)? {
|
||||
eprintln!("{response:#?}");
|
||||
}
|
||||
}
|
||||
Action::Rdr(rdr) => {
|
||||
_ = use_rdr_action(&mut conn, rdr);
|
||||
}
|
||||
Action::Run {
|
||||
image_reference,
|
||||
|
||||
78
xc-bin/src/redirect.rs
Normal file
78
xc-bin/src/redirect.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2023 Yan Ka, Chiu.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions, and the following disclaimer,
|
||||
// without modification, immediately at the beginning of the file.
|
||||
// 2. The name of the author may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
// SUCH DAMAGE.
|
||||
use clap::Parser;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use xcd::ipc::*;
|
||||
|
||||
use crate::format::PublishSpec;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub(crate) enum RdrAction {
|
||||
Add {
|
||||
#[clap(long = "publish", short = 'p', multiple_occurrences = true)]
|
||||
publish: Vec<PublishSpec>,
|
||||
name: String,
|
||||
},
|
||||
List {
|
||||
name: String,
|
||||
#[clap(short = 'H', action)]
|
||||
without_header: bool,
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) fn use_rdr_action(
|
||||
conn: &mut UnixStream,
|
||||
action: RdrAction,
|
||||
) -> Result<(), crate::ActionError> {
|
||||
match action {
|
||||
RdrAction::Add { name, publish } => {
|
||||
for expose in publish.iter() {
|
||||
let redirection = expose.to_host_spec();
|
||||
let request = DoRdr {
|
||||
name: name.clone(),
|
||||
redirection,
|
||||
};
|
||||
if let Ok(response) = do_rdr_container(conn, request)? {
|
||||
eprintln!("{response:#?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
RdrAction::List {
|
||||
name,
|
||||
without_header,
|
||||
} => {
|
||||
let response = do_list_site_rdr(conn, ContainerRdrList { name })?;
|
||||
if let Ok(response) = response {
|
||||
if !without_header {
|
||||
let count = response.len();
|
||||
println!("{count} redirection(s)");
|
||||
}
|
||||
for rdr in response.iter() {
|
||||
println!("{}", rdr.to_pf_rule());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -31,7 +31,6 @@ use freebsd::fs::zfs::ZfsHandle;
|
||||
use oci_util::digest::OciDigest;
|
||||
use oci_util::distribution::client::*;
|
||||
use oci_util::image_reference::ImageReference;
|
||||
use oci_util::image_reference::ImageTag;
|
||||
use oci_util::layer::ChainId;
|
||||
use oci_util::models::ImageManifest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
Reference in New Issue
Block a user