Skip to content

Commit 6f1a715

Browse files
committed
feat(boil): Relax vendor version constraint
Previously we required the vendor version to be a valid semver (like we use for SDP releases: 26.3.0). This constraint has been relaxed to allow any valid container tag. Replaced semver crate with regex.
1 parent ae4dda7 commit 6f1a715

8 files changed

Lines changed: 32 additions & 67 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ git2 = "0.20.1"
1616
glob = "0.3.2"
1717
oci-spec = "0.9.0"
1818
rstest = "0.26.1"
19-
semver = { version = "1.0.26", features = ["serde"] }
19+
regex = "1.12.3"
2020
serde = { version = "1.0.217", features = ["derive"] }
2121
serde_json = "1.0.140"
2222
snafu = "0.9.0"

rust/boil/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ clap_complete_nushell.workspace = true
1515
git2.workspace = true
1616
glob.workspace = true
1717
oci-spec.workspace = true
18-
semver.workspace = true
18+
regex.workspace = true
1919
serde.workspace = true
2020
serde_json.workspace = true
2121
snafu.workspace = true

rust/boil/src/cli/build.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ use std::{
22
fmt::{Debug, Display},
33
path::PathBuf,
44
str::FromStr,
5+
sync::LazyLock,
56
};
67

78
use clap::{Args, ValueHint, value_parser};
8-
use semver::Version;
9+
use regex::Regex;
910
use snafu::{ResultExt, Snafu, ensure};
1011
use strum::EnumDiscriminants;
1112
use url::Host;
@@ -30,7 +31,7 @@ pub struct BuildArguments {
3031
default_value_t = Self::default_image_version(),
3132
help_heading = "Image Options"
3233
)]
33-
pub image_version: Version,
34+
pub image_version: String,
3435

3536
/// Target platform of the image.
3637
#[arg(
@@ -129,16 +130,29 @@ pub struct BuildArguments {
129130
pub rest: Vec<String>,
130131
}
131132

133+
// This is derived from the general rule where the length of the tag can be up to 128 chars
134+
// But that checking needs to be at a higher layer.
135+
static VALID_IMAGE_TAG: LazyLock<Regex> =
136+
LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$").expect("regex is valid"));
137+
132138
impl BuildArguments {
133-
fn parse_image_version(input: &str) -> Result<Version, ParseImageVersionError> {
134-
let version = Version::from_str(input).context(ParseVersionSnafu)?;
135-
ensure!(version.build.is_empty(), ContainsBuildMetadataSnafu);
139+
/// Ensure that the given version will be valid for use in the image tag
140+
fn parse_image_version(version: &str) -> Result<String, ParseImageVersionError> {
141+
// TODO (@NickLarsenNZ): Probably want to minus the characters used in front (x.y.z-stackable).
142+
// But maybe that validation needs to go up a layer.
143+
if version.len() > 128 {
144+
return VersionTooLongSnafu.fail();
145+
}
146+
147+
if !VALID_IMAGE_TAG.is_match(version) {
148+
return ParseVersionSnafu { version }.fail();
149+
}
136150

137-
Ok(version)
151+
Ok(version.to_owned())
138152
}
139153

140-
fn default_image_version() -> Version {
141-
"0.0.0-dev".parse().expect("must be a valid SemVer")
154+
fn default_image_version() -> String {
155+
"0.0.0-dev".to_owned()
142156
}
143157

144158
fn default_registry() -> HostPort {
@@ -160,11 +174,11 @@ impl BuildArguments {
160174

161175
#[derive(Debug, Snafu)]
162176
pub enum ParseImageVersionError {
163-
#[snafu(display("failed to parse semantic version"))]
164-
ParseVersion { source: semver::Error },
177+
#[snafu(display("The version exceeds the 128 character limit"))]
178+
VersionTooLong,
165179

166-
#[snafu(display("semantic version must not contain build metadata"))]
167-
ContainsBuildMetadata,
180+
#[snafu(display("invalid image tag characters for {version:?}"))]
181+
ParseVersion { version: String },
168182
}
169183

170184
#[derive(Debug, PartialEq, Snafu, EnumDiscriminants)]

rust/boil/src/cmd/build.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,6 @@ pub enum Error {
4444

4545
/// This is the `boil build` command handler function.
4646
pub fn run_command(args: Box<BuildArguments>, config: Config) -> Result<(), Error> {
47-
// TODO (@Techassi): Parse Dockerfile instead to build the target graph
48-
// Validation
49-
ensure!(
50-
args.image_version.build.is_empty(),
51-
InvalidImageVersionSnafu
52-
);
53-
5447
// Create bakefile
5548
let bakefile = Bakefile::from_cli_args(&args, config).context(CreateBakefileSnafu)?;
5649
let image_manifest_uris = bakefile.image_manifest_uris();

rust/boil/src/core/bakefile.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@ use oci_spec::image::{
1111
ANNOTATION_AUTHORS, ANNOTATION_CREATED, ANNOTATION_DOCUMENTATION, ANNOTATION_LICENSES,
1212
ANNOTATION_REVISION, ANNOTATION_SOURCE, ANNOTATION_VENDOR, ANNOTATION_VERSION,
1313
};
14-
use semver::Version;
1514
use serde::Serialize;
1615
use snafu::{OptionExt, ResultExt, Snafu, ensure};
1716
use time::format_description::well_known::Rfc3339;
1817

1918
use crate::{
20-
VersionExt,
2119
cli::{self, HostPort},
2220
config::{self, Config, Metadata},
2321
constants::DOCKER_LABEL_BUILD_DATE,
@@ -294,7 +292,7 @@ impl Bakefile {
294292
let target = BakefileTarget::common(
295293
date_time,
296294
revision,
297-
cli_args.image_version.base_prerelease(),
295+
cli_args.image_version.clone(),
298296
container_build_args,
299297
user_container_build_args,
300298
metadata,
@@ -642,7 +640,7 @@ impl BakefileTarget {
642640
fn image_version_annotation(
643641
image_version: &str,
644642
vendor_tag_prefix: &str,
645-
vendor_image_version: &Version,
643+
vendor_image_version: &str,
646644
) -> Vec<String> {
647645
let image_index_manifest_tag = utils::format_image_index_manifest_tag(
648646
image_version,

rust/boil/src/main.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use clap::Parser;
2-
use semver::Version;
32
use snafu::{ResultExt, Snafu};
43

54
use crate::{
@@ -46,39 +45,6 @@ impl<T> IfContext for T {
4645
}
4746
}
4847

49-
pub trait VersionExt {
50-
/// Returns the base of a [`Version`] as a string, eg. `1.2.3`.
51-
fn base(&self) -> String;
52-
53-
/// Returns the base and prerelease of a [`Version`] as a string, eg. `1.2.3-rc.1`.
54-
fn base_prerelease(&self) -> String;
55-
}
56-
57-
impl VersionExt for Version {
58-
fn base(&self) -> String {
59-
let Self {
60-
major,
61-
minor,
62-
patch,
63-
..
64-
} = self;
65-
66-
format!("{major}.{minor}.{patch}")
67-
}
68-
69-
fn base_prerelease(&self) -> String {
70-
let mut base = self.base();
71-
72-
// Well, that was a big doozy, ruined the whole release...
73-
if !self.pre.is_empty() {
74-
base.push('-');
75-
base.push_str(&self.pre);
76-
}
77-
78-
base
79-
}
80-
}
81-
8248
#[derive(Debug, Snafu)]
8349
enum Error {
8450
#[snafu(display("failed to run build command"))]

rust/boil/src/utils.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::process::Command;
22

3-
use semver::Version;
4-
53
use crate::{cli::HostPort, core::platform::Architecture};
64

75
/// Formats and returns the image repository URI, eg. `oci.stackable.tech/sdp/opa`.
@@ -22,7 +20,7 @@ pub fn format_image_manifest_uri(image_repository_uri: &str, image_manifest_tag:
2220
pub fn format_image_index_manifest_tag(
2321
image_version: &str,
2422
vendor_tag_prefix: &str,
25-
vendor_image_version: &Version,
23+
vendor_image_version: &str,
2624
) -> String {
2725
format!("{image_version}-{vendor_tag_prefix}{vendor_image_version}")
2826
}

0 commit comments

Comments
 (0)