Skip to content

Commit

Permalink
feat: add '--insecure' option for invalid tls certs, allow writing im…
Browse files Browse the repository at this point in the history
…age name with https:// or http://

Signed-off-by: BioTheWolff <[email protected]>
  • Loading branch information
sea-gull-diana authored and remi-espie committed May 3, 2024
1 parent 7c5173b commit 3bfd951
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/fs-gen/src/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ pub struct CliArgs {
/// Password can also be passed via STDIN: [echo <PASSWORD> | fs-gen ... -p -]
#[arg(short='p', long="password", default_value=None)]
pub password: Option<MaybeStdin<String>>,

/// Allow invalid TLS certificates
#[arg(long="insecure", action=ArgAction::SetTrue)]
pub insecure: bool,
}

impl CliArgs {
Expand Down
11 changes: 8 additions & 3 deletions src/fs-gen/src/loader/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(crate) fn download_image_fs(
output_file: PathBuf,
username: Option<String>,
password: Option<MaybeStdin<String>>,
insecure: bool,
) -> Result<Vec<PathBuf>, ImageLoaderError> {
info!("Downloading image...");
let image = Image::from_str(image_name);
Expand All @@ -28,7 +29,11 @@ pub(crate) fn download_image_fs(
);

// Get download token and download manifest
let client = Client::new();
let client = Client::builder()
.danger_accept_invalid_certs(insecure)
.build()
.map_err(|e| ImageLoaderError::Error { source: e.into() })?;

let token = &get_docker_download_token(&client, &image, username, password)?;
let manifest = download_manifest(&client, token, &image, &image.tag)
.map_err(|e| ImageLoaderError::Error { source: e })?;
Expand Down Expand Up @@ -96,7 +101,7 @@ fn download_manifest(
) -> Result<ManifestV2> {
// Query Docker Hub API to get the image manifest
let manifest_url = format!(
"https://{}/v2/{}/{}/manifests/{}",
"{}/v2/{}/{}/manifests/{}",
image.registry, image.repository, image.name, digest
);

Expand Down Expand Up @@ -141,7 +146,7 @@ fn download_layers(
for layer in layers {
let digest = &layer.digest;
let layer_url = format!(
"https://{}/v2/{}/{}/blobs/{}",
"{}/v2/{}/{}/blobs/{}",
image.registry, image.repository, image.name, digest
);

Expand Down
16 changes: 14 additions & 2 deletions src/fs-gen/src/loader/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,31 @@ pub struct Image {
impl Image {
// Get image's repository, name and tag
pub fn from_str(image_name: &str) -> Image {
const DEFAULT_REGISTRY: &str = "registry-1.docker.io";
const DEFAULT_REGISTRY: &str = "https://registry-1.docker.io";
const DEFAULT_REPOSITORY: &str = "library";
const DEFAULT_TAG: &str = "latest";

let protocol = if image_name.starts_with("http://") {
"http://"
} else {
"https://"
};

let mut image_data: Vec<&str> = image_name
.trim_start_matches("http://")
.trim_start_matches("https://")
.trim_start_matches("docker.io/")
.splitn(3, '/')
.collect();

// Get registry link (part of name before the first '/' with dots) or use the default registry
let registry = if image_data[0].contains('.') {
image_data.remove(0).to_string()
format!("{}{}", protocol, image_data.remove(0))
} else {
DEFAULT_REGISTRY.to_string()
};

// Set image repository and name
let (repository, name) = match image_data.len() {
1 => (DEFAULT_REPOSITORY.to_string(), image_data[0].to_string()),
2 => (image_data[0].to_string(), image_data[1].to_string()),
Expand All @@ -78,6 +88,8 @@ impl Image {
image_data[1].to_string() + "/" + image_data[2],
),
};

// Set image tag, default: 'latest'
let image_and_tag: Vec<&str> = name.split(':').collect();
let (name, tag) = if image_and_tag.len() < 2 {
(image_and_tag[0].to_string(), DEFAULT_TAG.to_string())
Expand Down
7 changes: 4 additions & 3 deletions src/fs-gen/src/loader/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ pub(super) fn get_registry_auth_data(
image: &Image,
) -> Result<Registry, ImageLoaderError> {
let manifest_url = format!(
"https://{}/v2/{}/{}/manifests/{}",
"{}/v2/{}/{}/manifests/{}",
image.registry, image.repository, image.name, image.tag
);

let unauth_request = client
let unauth_response = client
.get(manifest_url)
.send()
.with_context(|| format!("Could not send request to {}", image.registry))?;
let auth_header: &str = unauth_request.headers()["www-authenticate"]

let auth_header: &str = unauth_response.headers()["www-authenticate"]
.to_str()
.map_err(|e| ImageLoaderError::Error { source: e.into() })?;
let auth_data: Vec<&str> = auth_header.split('"').collect();
Expand Down
1 change: 1 addition & 0 deletions src/fs-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fn run(args: CliArgs) -> Result<()> {
layers_subdir,
args.username,
args.password,
args.insecure,
) {
Err(e) => bail!(e),
Ok(e) => e,
Expand Down

0 comments on commit 3bfd951

Please sign in to comment.