Skip to content

Commit f5ef9fa

Browse files
committed
Try to detect OS distribution for DockerImage step
1 parent e98394e commit f5ef9fa

File tree

5 files changed

+123
-27
lines changed

5 files changed

+123
-27
lines changed

src/builder/commands/docker.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ use quire::{
2727

2828
#[cfg(feature="containers")]
2929
use crate::{
30+
builder::commands::alpine,
31+
builder::commands::ubuntu,
3032
builder::commands::tarcmd::TarCmd,
33+
builder::distrib::DistroBox,
3134
capsule::packages as capsule,
3235
container::util::clean_dir,
3336
file_util::{Dir, Lock},
3437
};
3538
use crate::build_step::{BuildStep, Config, Digest, Guard, StepError, VersionError};
39+
use crate::builder::distrib::parse_release_file;
3640

3741
const DEFAULT_REGISTRY_HOST: &str = "registry-1.docker.io";
3842
const DEFAULT_IMAGE_NAMESPACE: &str = "library";
@@ -148,7 +152,8 @@ impl BuildStep for DockerImage {
148152
.entry_handler(whiteout_entry_handler)
149153
.unpack()?;
150154
}
151-
Ok(())
155+
156+
detect_os_release(guard)
152157
}
153158

154159
fn is_dependent_on(&self) -> Option<&str> {
@@ -316,4 +321,48 @@ async fn download_blob(
316321
Err(e) => return Err(format!("{}", e)),
317322
}
318323
Ok(blob_path)
319-
}
324+
}
325+
326+
#[cfg(feature="containers")]
327+
fn detect_os_release(guard: &mut Guard) -> Result<(), StepError> {
328+
if let Ok(release_vars) = parse_release_file("/vagga/root/etc/os-release") {
329+
let os_id = release_vars.get("ID").map(String::as_str);
330+
match os_id {
331+
Some("ubuntu") => {
332+
if let Some(codename) = release_vars.get("UBUNTU_CODENAME") {
333+
let release = ubuntu::UbuntuRelease {
334+
codename: Some(codename.clone()),
335+
version: None,
336+
url: None,
337+
arch: String::from("amd64"), // TODO(tailhook) detect
338+
keep_chfn_command: false,
339+
eatmydata: true,
340+
};
341+
ubuntu::build::configure(guard, release)?;
342+
guard.distro.specific(|u: &mut ubuntu::Distro| {
343+
ubuntu::build::init_ubuntu_core(&mut guard.ctx, u)
344+
.map_err(|e| StepError::Compat(e))
345+
})?;
346+
} else {
347+
warn!("Missing ubuntu codename");
348+
}
349+
}
350+
Some("alpine") => {
351+
if let Some(version_id) = release_vars.get("VERSION_ID") {
352+
if let Some((alpine_version, _)) = version_id.rsplit_once('.') {
353+
let distro = alpine::Distro {
354+
version: format!("v{}", alpine_version),
355+
mirror: guard.ctx.settings.alpine_mirror().to_string(),
356+
base_setup: false,
357+
apk_update: true,
358+
};
359+
guard.distro.set(distro)?;
360+
}
361+
}
362+
}
363+
Some(_) | None => {}
364+
}
365+
}
366+
367+
Ok(())
368+
}

src/builder/commands/ubuntu.rs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fs::{remove_dir_all, rename, set_permissions, Permissions};
22
use std::os::unix::fs::{symlink};
33
use std::fs::File;
4-
use std::io::{self, BufReader, Write};
4+
use std::io::{self, Write};
55
use std::path::{Path, PathBuf};
66
use std::ffi::OsStr;
77

@@ -916,37 +916,22 @@ impl BuildStep for UbuntuRelease {
916916
}
917917

918918
#[cfg(feature="containers")]
919-
mod build {
920-
use std::io::BufRead;
919+
pub mod build {
921920
use std::os::unix::fs::PermissionsExt;
922921

923922
use unshare::Command;
923+
use crate::builder::distrib::parse_release_file;
924924

925925
use crate::capsule::download::download_file;
926926

927927
use super::*;
928928

929929
pub fn read_ubuntu_codename() -> Result<String, String>
930930
{
931-
let lsb_release_path = "/vagga/root/etc/lsb-release";
932-
let lsb_release_file = BufReader::new(
933-
try_msg!(File::open(&Path::new(lsb_release_path)),
934-
"Error reading /etc/lsb-release: {err}"));
935-
936-
for line in lsb_release_file.lines() {
937-
let line = try_msg!(line, "Error reading lsb file: {err}");
938-
if let Some(equals_pos) = line.find('=') {
939-
let key = line[..equals_pos].trim();
940-
941-
if key == "DISTRIB_CODENAME" {
942-
let value = line[(equals_pos + 1)..].trim();
943-
return Ok(value.to_string());
944-
}
945-
}
946-
}
947-
948-
Err(format!("Coudn't read codename from '{lsb_release_path}'",
949-
lsb_release_path=lsb_release_path))
931+
let release_vars = parse_release_file("/vagga/root/etc/lsb-release")?;
932+
release_vars.get("DISTRIB_CODENAME")
933+
.map(|v| v.clone())
934+
.ok_or(format!("Missing DISTRIB_CODENAME variable"))
950935
}
951936

952937
pub fn fetch_ubuntu_core(ctx: &mut Context, rel: &UbuntuRelease)
@@ -1103,7 +1088,7 @@ mod build {
11031088
pub fn configure(guard: &mut Guard, config: UbuntuRelease)
11041089
-> Result<(), StepError>
11051090
{
1106-
guard.distro.set(Distro {
1091+
let distro = Distro {
11071092
eatmydata: if config.eatmydata { EatMyData::Need } else { EatMyData::No },
11081093
config,
11091094
codename: None, // unknown yet
@@ -1112,8 +1097,10 @@ mod build {
11121097
apt_hkps: AptHkps::No,
11131098
has_indices: false,
11141099
has_universe: false,
1115-
})?;
1116-
configure_common(&mut guard.ctx)
1100+
};
1101+
guard.distro.set(distro)?;
1102+
configure_common(&mut guard.ctx)?;
1103+
Ok(())
11171104
}
11181105

11191106
pub fn configure_common(ctx: &mut Context) -> Result<(), StepError> {

src/builder/distrib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use std::collections::HashMap;
2+
use std::fs::File;
3+
use std::io::{BufRead, BufReader};
4+
use std::path::Path;
5+
16
use mopa::{Any, mopafy};
27

38
use crate::builder::commands::alpine;
@@ -102,3 +107,30 @@ impl DistroBox for Box<dyn Distribution> {
102107
Ok(())
103108
}
104109
}
110+
111+
pub fn parse_release_file(
112+
path: impl AsRef<Path>
113+
) -> Result<HashMap<String, String>, String> {
114+
let release_path = path.as_ref();
115+
let release_file = BufReader::new(
116+
try_msg!(
117+
File::open(release_path),
118+
"Error opening release file {path:?}: {err}", path=release_path
119+
)
120+
);
121+
122+
let mut vars = HashMap::new();
123+
for line in release_file.lines() {
124+
let line = try_msg!(
125+
line,
126+
"Error reading release file {path:?}: {err}", path=release_path
127+
);
128+
if let Some(equals_pos) = line.find('=') {
129+
let key = line[..equals_pos].trim();
130+
let value = line[(equals_pos + 1)..].trim();
131+
vars.insert(key.to_string(), value.to_string());
132+
}
133+
}
134+
135+
Ok(vars)
136+
}

tests/docker.bats

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ setup() {
1313
assert_line "Hello from Docker!"
1414
}
1515

16+
@test "docker: detect ubuntu" {
17+
run vagga _build ubuntu
18+
assert_success
19+
20+
run vagga _run ubuntu sh -c 'echo 21*2 | bc'
21+
assert_success
22+
assert_output 42
23+
}
24+
25+
@test "docker: detect alpine" {
26+
run vagga _build alpine
27+
assert_success
28+
29+
run vagga _run alpine sh -c 'echo 21*2 | bc'
30+
assert_success
31+
assert_output 42
32+
}
33+
1634
@test "docker: python" {
1735
run vagga _build python
1836
assert_success

tests/docker/vagga.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ containers:
44
- !DockerImage
55
image: library/hello-world
66

7+
ubuntu:
8+
setup:
9+
- !DockerImage ubuntu:focal
10+
- !Install [bc]
11+
12+
alpine:
13+
setup:
14+
- !DockerImage alpine:3.15
15+
- !Install [bc]
16+
717
python:
818
setup:
919
- !DockerImage

0 commit comments

Comments
 (0)