Skip to content

Commit

Permalink
Update ImageName::as_path escaping for digest reference case (#134)
Browse files Browse the repository at this point in the history
Add escape rule of image name into path for #128 case:

```text
quay.io/jitesoft/alpine:sha256:6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c
```

will escape into

```
quay.io/jitesoft/alpine/__sha256__6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c
```
  • Loading branch information
termoshtt authored May 10, 2024
1 parent 060155a commit e1e277a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
2 changes: 1 addition & 1 deletion ocipkg/src/distribution/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::fmt;
/// Reference of container image stored in the repository
///
/// In [OCI distribution spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md):
/// > `<reference>` MUST be either (a) the digest of the manifest or (b) a tag
/// > `<reference>` MUST be either (a) the digest of the manifest or (b) a tag
/// > `<reference>` as a tag MUST be at most 128 characters
/// > in length and MUST match the following regular expression:
/// > ```text
Expand Down
41 changes: 34 additions & 7 deletions ocipkg/src/image_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@ use url::Url;
/// # Ok::<(), anyhow::Error>(())
/// ```
///
/// [Reference] can be a digest:
///
/// ```text
/// quay.io/jitesoft/alpine:sha256:6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c
/// ^^^^^^^-------------------- hostname
/// ^^^^^^^^^^^^^^^---- name
/// reference ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// ```
///
/// ```
/// use ocipkg::{ImageName, distribution::{Name, Reference}};
/// let name = ImageName::parse("quay.io/jitesoft/alpine:sha256:6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c")?;
/// assert_eq!(
/// name,
/// ImageName {
/// hostname: "quay.io".to_string(),
/// port: None,
/// name: Name::new("jitesoft/alpine")?,
/// reference: Reference::new("sha256:6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c")?,
/// }
/// );
/// # Ok::<(), anyhow::Error>(())
/// ```
///
/// Default values
/// ---------------
/// If `hostname` is absent, use `registry-1.docker.io` for docker compatibility:
Expand Down Expand Up @@ -175,13 +199,11 @@ impl ImageName {

/// Encode image name into a path by `{hostname}/{name}/__{reference}` or `{hostname}__{port}/{name}/__{reference}` if port is specified.
pub fn as_path(&self) -> PathBuf {
let reference = self.reference.replace(':', "__");
PathBuf::from(if let Some(port) = self.port {
format!(
"{}__{}/{}/__{}",
self.hostname, port, self.name, self.reference
)
format!("{}__{}/{}/__{}", self.hostname, port, self.name, reference)
} else {
format!("{}/{}/__{}", self.hostname, self.name, self.reference)
format!("{}/{}/__{}", self.hostname, self.name, reference)
})
}

Expand Down Expand Up @@ -217,9 +239,10 @@ impl ImageName {
let name = Name::new(&components[1..n - 1].join("/"))?;

let reference = Reference::new(
components[n - 1]
&components[n - 1]
.strip_prefix("__")
.with_context(|| anyhow!("Missing tag in path: {}", path.display()))?,
.with_context(|| anyhow!("Missing tag in path: {}", path.display()))?
.replace("__", ":"),
)?;

Ok(ImageName {
Expand Down Expand Up @@ -266,6 +289,10 @@ mod test {
"registry-1.docker.io/ubuntu/__20.04".as_ref(),
)?;
test_as_path("alpine", "registry-1.docker.io/alpine/__latest".as_ref())?;
test_as_path(
"quay.io/jitesoft/alpine:sha256:6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c",
"quay.io/jitesoft/alpine/__sha256__6755355f801f8e3694bffb1a925786813462cea16f1ce2b0290b6a48acf2500c".as_ref()
)?;
Ok(())
}
}

0 comments on commit e1e277a

Please sign in to comment.