Skip to content

Commit

Permalink
Add config api to enable host config (#19)
Browse files Browse the repository at this point in the history
* Feat. adding /config api

* Feat. remove libssl-dev fron deps
  • Loading branch information
juliusl authored Feb 10, 2023
1 parent 7fc7d34 commit d411f17
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ required-features = ["editor"]

[package.metadata.deb]
name = "acr-mirror"
depends = "jq, libssl-dev"
depends = "jq"
maintainer-scripts = "lib/debian"
assets = [
[
Expand Down
2 changes: 1 addition & 1 deletion src/bin/shared/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub struct MirrorSettings {
/// If initializing settings, only initialize the hosts.toml file
///
#[clap(long, action)]
pub hosts_config_only: bool,
pub init_hosts_config_only: bool,
/// Root of the current filesystem,
///
/// This is usually just `/` however when testing it's useful to specify since root is a privelaged folder.
Expand Down
2 changes: 1 addition & 1 deletion src/bin/shared/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl Commands {
teleport_format,
registry_host,
fs_root,
hosts_config_only,
init_hosts_config_only: hosts_config_only,
..
}) => {
if mirror_runmd.exists() {
Expand Down
71 changes: 56 additions & 15 deletions src/config/hosts_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use logos::Logos;
use std::{
collections::{BTreeMap, BTreeSet},
fmt::Display,
path::PathBuf, io::Write
io::Write,
path::PathBuf,
};
use tracing::error;

/// Folder name of the default hosts_config folder used by containerd,
///
///
const HOSTS_CONFIG_FOLDER: &'static str = "etc/containerd/certs.d";

/// Struct for creating a hosts.toml file for containerd hosts configuration,
Expand All @@ -34,7 +35,7 @@ impl HostsConfig {
}

/// Enables legacy support for containerd version under 1.7
///
///
pub fn enable_legacy_support(mut self) -> Self {
self.legacy_support = true;
self
Expand All @@ -48,16 +49,9 @@ impl HostsConfig {
}

/// Serializes and writes the current config to
///
///
pub fn install(&self, root_dir: Option<impl Into<PathBuf>>) -> Result<PathBuf, std::io::Error> {
let path = root_dir.map(|r| r.into()).unwrap_or(PathBuf::from("/"));
let path = path.join(HOSTS_CONFIG_FOLDER);

let path = if let Some(server) = self.server.as_ref() {
path.join(server)
} else {
path.join("_default")
};
let path = self.install_dir(root_dir);

std::fs::create_dir_all(&path)?;

Expand All @@ -71,6 +65,49 @@ impl HostsConfig {

Ok(path)
}

/// Uninstalls the config,
///
pub fn uninstall(&self, root_dir: Option<impl Into<PathBuf>>) -> Result<(), std::io::Error> {
let path = self.install_dir(root_dir);

std::fs::create_dir_all(&path)?;

let path = path.join("hosts.toml");

if !path.exists() {
return Ok(());
} else {
std::fs::remove_file(path)?;
}

Ok(())
}

/// Returns true if the config is installed,
///
pub fn installed(&self, root_dir: Option<impl Into<PathBuf>>) -> bool {
self.install_dir(root_dir)
.canonicalize()
.ok()
.map(|p| p.join("hosts.toml").exists())
.unwrap_or_default()
}

/// Returns the path to the config,
///
fn install_dir(&self, root_dir: Option<impl Into<PathBuf>>) -> PathBuf {
let path = root_dir.map(|r| r.into()).unwrap_or(PathBuf::from("/"));
let path = path.join(HOSTS_CONFIG_FOLDER);

let path = if let Some(server) = self.server.as_ref() {
path.join(server)
} else {
path.join("_default")
};

path
}
}

impl Display for HostsConfig {
Expand Down Expand Up @@ -306,9 +343,11 @@ server = "https://test.azurecr.io"
.trim_start(),
format!("{}", host_config)
);
let location = host_config.install(Some(".test")).expect("should be able to install");
let location = host_config
.install(Some(".test"))
.expect("should be able to install");
eprintln!("{:?}", location);

// Test w/o server=
let host_config = HostsConfig::new(None::<String>);
let host_config = host_config.add_host(
Expand All @@ -334,7 +373,9 @@ server = "https://test.azurecr.io"
format!("{}", host_config)
);

let location = host_config.install(Some(".test")).expect("should be able to install");
let location = host_config
.install(Some(".test"))
.expect("should be able to install");
eprintln!("{:?}", location);
}

Expand Down
9 changes: 9 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ impl Error {
}
}

/// Returns true if the category is an invalid operation,
///
pub fn is_invalid_operation(&self) -> bool {
match self.category {
ErrorCategory::InvalidOperation(_) => true,
_ => false,
}
}

/// Returns a composite error,
///
pub fn also(&self, other: Self) -> Self {
Expand Down
49 changes: 32 additions & 17 deletions src/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
use crate::default_access_provider;
use crate::Artifact;
use crate::ArtifactManifest;
use crate::Authenticate;
use crate::Descriptor;
use crate::Discover;
use crate::ImageIndex;
use crate::ImageManifest;
use crate::Login;
use crate::Mirror;
use crate::Resolve;
use crate::Teleport;
use lifec::prelude::AttributeParser;
use lifec::prelude::Block;
use lifec::prelude::Host;
Expand All @@ -13,29 +25,17 @@ use lifec::project::default_world;
use lifec::project::Project;
use lifec::runtime::Runtime;
use lifec_poem::WebApp;
use poem::Route;
use poem::EndpointExt;
use poem::web::Data;
use poem::handler;
use poem::get;
use poem::handler;
use poem::web::Data;
use poem::EndpointExt;
use poem::Route;
use specs::WorldExt;
use std::sync::Arc;
use crate::Teleport;
use crate::Resolve;
use crate::Mirror;
use crate::Login;
use crate::ImageManifest;
use crate::ImageIndex;
use crate::Discover;
use crate::Descriptor;
use crate::Authenticate;
use crate::ArtifactManifest;
use crate::Artifact;
use crate::default_access_provider;

mod proxy_target;
pub use proxy_target::ProxyTarget;
pub use proxy_target::Object;
pub use proxy_target::ProxyTarget;

mod manifests;
pub use manifests::Manifests;
Expand All @@ -54,6 +54,9 @@ mod auth;
use auth::handle_auth;
pub use auth::OAuthToken;

mod config;
use config::handle_config;

/// Struct for creating a customizable registry proxy,
///
/// This proxy is a server that intercepts registry requests intended for upstream registries,
Expand Down Expand Up @@ -191,6 +194,12 @@ impl WebApp for RegistryProxy {
.data(self.context.clone())
.data(default_access_provider(file_provider)),
)
.at(
"/config",
get(handle_config.data(self.context.clone()))
.put(handle_config.data(self.context.clone()))
.delete(handle_config.data(self.context.clone())),
)
.nest("/v2", route)
} else {
panic!("Cannot start w/o config")
Expand Down Expand Up @@ -626,6 +635,12 @@ mod tests {
resp.assert_status(StatusCode::SERVICE_UNAVAILABLE);
});

let test_5 = cli.clone();
tokio::spawn(async move {
let resp = test_5.get("/config?ns=tenant.registry.io").send().await;
resp.assert_status(StatusCode::SERVICE_UNAVAILABLE);
});

// It's important that all requests start before this line, otherwise the host will exit immediately b/c there will be no operations pending
host.async_wait_for_exit(
Some(Instant::now() + Duration::from_millis(100)),
Expand Down
Loading

0 comments on commit d411f17

Please sign in to comment.