Skip to content

Commit cad1720

Browse files
authored
Static linked executable as a runnable container (#182)
1 parent c10e6e7 commit cad1720

File tree

11 files changed

+289
-1
lines changed

11 files changed

+289
-1
lines changed

.github/workflows/ocipkg.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,32 @@ jobs:
4848
- name: Show alpine version
4949
run: cat $HOME/.local/share/ocipkg/docker.io/library/alpine/__latest/etc/alpine-release
5050

51+
runnable:
52+
runs-on: ubuntu-22.04
53+
steps:
54+
- uses: actions/checkout@v4
55+
- uses: actions-rs/cargo@v1
56+
with:
57+
command: install
58+
args: --path=ocipkg-cli/ -f
59+
- name: Add path
60+
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
61+
62+
- name: Build examples/static-exe
63+
run: |
64+
rustup target add x86_64-unknown-linux-musl
65+
cargo build --release
66+
working-directory: examples/static-exe
67+
68+
- name: pack
69+
run: |
70+
ocipkg runnable examples/static-exe/target/x86_64-unknown-linux-musl/release/static-exe -o test.tar --tag static-exe
71+
72+
- name: Test podman can run the
73+
run: |
74+
podman load < test.tar
75+
podman run --rm static-exe
76+
5177
get:
5278
runs-on: ubuntu-22.04
5379
steps:

Cargo.lock

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
members = ["ocipkg", "ocipkg-cli"]
3-
exclude = ["examples/rust/lib", "examples/rust/exe"]
3+
exclude = ["examples/static-exe", "examples/rust/lib", "examples/rust/exe"]
44
resolver = "2"
55

66
[workspace.dependencies]
@@ -15,6 +15,7 @@ directories = "5.0.1"
1515
env_logger = "0.11.7"
1616
flate2 = "1.1.0"
1717
git2 = "0.19.0"
18+
goblin = "0.9.3"
1819
lazy_static = "1.5.0"
1920
log = "0.4.26"
2021
maplit = "1.0.2"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "x86_64-unknown-linux-musl"

examples/static-exe/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/static-exe/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "static-exe"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]

examples/static-exe/src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::env;
2+
3+
fn main() {
4+
let args: Vec<String> = env::args().collect();
5+
let name = if args.len() > 1 { &args[1] } else { "World" };
6+
println!("Hello, {}!", name);
7+
}

ocipkg-cli/src/bin/ocipkg.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ enum Opt {
3333
tag: Option<String>,
3434
},
3535

36+
/// Compose a static-linked executable file into an oci-archive tar file
37+
Runnable {
38+
/// Path of static-linked exetuable file
39+
input: PathBuf,
40+
41+
/// Path of output tar archive in oci-archive format. Default is input file name with .tar extension
42+
#[arg(short = 'o', long = "output")]
43+
output: Option<PathBuf>,
44+
45+
/// Overwrite the output file if it exists
46+
#[arg(short = 'f', long = "overwrite")]
47+
overwrite: bool,
48+
49+
/// Name of container, use UUID v4 hyphenated if not set.
50+
#[arg(short = 't', long = "tag")]
51+
tag: Option<String>,
52+
},
53+
3654
/// Load and expand container local cache
3755
Load {
3856
/// Input oci-archive
@@ -121,6 +139,33 @@ fn main() -> Result<()> {
121139
let _artifact = b.build()?;
122140
}
123141

142+
Opt::Runnable {
143+
input,
144+
output,
145+
overwrite,
146+
tag,
147+
} => {
148+
let output = output.unwrap_or_else(|| {
149+
let mut output = input.clone();
150+
output.set_extension("tar");
151+
output
152+
});
153+
let image_name = if let Some(name) = tag {
154+
ocipkg::ImageName::parse(&name)?
155+
} else {
156+
ocipkg::ImageName::default()
157+
};
158+
159+
if overwrite && output.exists() {
160+
log::warn!("Overwriting existing file: {}", output.display());
161+
std::fs::remove_file(&output)?;
162+
}
163+
164+
log::info!("Creating runnable image at {}", output.display());
165+
let _out =
166+
ocipkg::image::RunnableBuilder::new_archive(output, image_name)?.build(&input)?;
167+
}
168+
124169
Opt::Load { input, overwrite } => {
125170
ocipkg::image::load(&input, overwrite)?;
126171
}

ocipkg/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ base64.workspace = true
1616
chrono.workspace = true
1717
directories.workspace = true
1818
flate2.workspace = true
19+
goblin.workspace = true
1920
lazy_static.workspace = true
2021
log.workspace = true
2122
maplit.workspace = true

ocipkg/src/image/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod oci_archive;
1111
mod oci_artifact;
1212
mod oci_dir;
1313
mod remote;
14+
mod runnable;
1415

1516
pub use artifact::*;
1617
pub use config::*;
@@ -19,3 +20,4 @@ pub use oci_archive::*;
1920
pub use oci_artifact::*;
2021
pub use oci_dir::*;
2122
pub use remote::*;
23+
pub use runnable::*;

0 commit comments

Comments
 (0)