Skip to content

Commit

Permalink
Try to detect OS distribution for DockerImage step
Browse files Browse the repository at this point in the history
  • Loading branch information
anti-social committed Jan 10, 2022
1 parent e98394e commit f5ef9fa
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 27 deletions.
53 changes: 51 additions & 2 deletions src/builder/commands/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ use quire::{

#[cfg(feature="containers")]
use crate::{
builder::commands::alpine,
builder::commands::ubuntu,
builder::commands::tarcmd::TarCmd,
builder::distrib::DistroBox,
capsule::packages as capsule,
container::util::clean_dir,
file_util::{Dir, Lock},
};
use crate::build_step::{BuildStep, Config, Digest, Guard, StepError, VersionError};
use crate::builder::distrib::parse_release_file;

const DEFAULT_REGISTRY_HOST: &str = "registry-1.docker.io";
const DEFAULT_IMAGE_NAMESPACE: &str = "library";
Expand Down Expand Up @@ -148,7 +152,8 @@ impl BuildStep for DockerImage {
.entry_handler(whiteout_entry_handler)
.unpack()?;
}
Ok(())

detect_os_release(guard)
}

fn is_dependent_on(&self) -> Option<&str> {
Expand Down Expand Up @@ -316,4 +321,48 @@ async fn download_blob(
Err(e) => return Err(format!("{}", e)),
}
Ok(blob_path)
}
}

#[cfg(feature="containers")]
fn detect_os_release(guard: &mut Guard) -> Result<(), StepError> {
if let Ok(release_vars) = parse_release_file("/vagga/root/etc/os-release") {
let os_id = release_vars.get("ID").map(String::as_str);
match os_id {
Some("ubuntu") => {
if let Some(codename) = release_vars.get("UBUNTU_CODENAME") {
let release = ubuntu::UbuntuRelease {
codename: Some(codename.clone()),
version: None,
url: None,
arch: String::from("amd64"), // TODO(tailhook) detect
keep_chfn_command: false,
eatmydata: true,
};
ubuntu::build::configure(guard, release)?;
guard.distro.specific(|u: &mut ubuntu::Distro| {
ubuntu::build::init_ubuntu_core(&mut guard.ctx, u)
.map_err(|e| StepError::Compat(e))
})?;
} else {
warn!("Missing ubuntu codename");
}
}
Some("alpine") => {
if let Some(version_id) = release_vars.get("VERSION_ID") {
if let Some((alpine_version, _)) = version_id.rsplit_once('.') {
let distro = alpine::Distro {
version: format!("v{}", alpine_version),
mirror: guard.ctx.settings.alpine_mirror().to_string(),
base_setup: false,
apk_update: true,
};
guard.distro.set(distro)?;
}
}
}
Some(_) | None => {}
}
}

Ok(())
}
37 changes: 12 additions & 25 deletions src/builder/commands/ubuntu.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fs::{remove_dir_all, rename, set_permissions, Permissions};
use std::os::unix::fs::{symlink};
use std::fs::File;
use std::io::{self, BufReader, Write};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::ffi::OsStr;

Expand Down Expand Up @@ -916,37 +916,22 @@ impl BuildStep for UbuntuRelease {
}

#[cfg(feature="containers")]
mod build {
use std::io::BufRead;
pub mod build {
use std::os::unix::fs::PermissionsExt;

use unshare::Command;
use crate::builder::distrib::parse_release_file;

use crate::capsule::download::download_file;

use super::*;

pub fn read_ubuntu_codename() -> Result<String, String>
{
let lsb_release_path = "/vagga/root/etc/lsb-release";
let lsb_release_file = BufReader::new(
try_msg!(File::open(&Path::new(lsb_release_path)),
"Error reading /etc/lsb-release: {err}"));

for line in lsb_release_file.lines() {
let line = try_msg!(line, "Error reading lsb file: {err}");
if let Some(equals_pos) = line.find('=') {
let key = line[..equals_pos].trim();

if key == "DISTRIB_CODENAME" {
let value = line[(equals_pos + 1)..].trim();
return Ok(value.to_string());
}
}
}

Err(format!("Coudn't read codename from '{lsb_release_path}'",
lsb_release_path=lsb_release_path))
let release_vars = parse_release_file("/vagga/root/etc/lsb-release")?;
release_vars.get("DISTRIB_CODENAME")
.map(|v| v.clone())
.ok_or(format!("Missing DISTRIB_CODENAME variable"))
}

pub fn fetch_ubuntu_core(ctx: &mut Context, rel: &UbuntuRelease)
Expand Down Expand Up @@ -1103,7 +1088,7 @@ mod build {
pub fn configure(guard: &mut Guard, config: UbuntuRelease)
-> Result<(), StepError>
{
guard.distro.set(Distro {
let distro = Distro {
eatmydata: if config.eatmydata { EatMyData::Need } else { EatMyData::No },
config,
codename: None, // unknown yet
Expand All @@ -1112,8 +1097,10 @@ mod build {
apt_hkps: AptHkps::No,
has_indices: false,
has_universe: false,
})?;
configure_common(&mut guard.ctx)
};
guard.distro.set(distro)?;
configure_common(&mut guard.ctx)?;
Ok(())
}

pub fn configure_common(ctx: &mut Context) -> Result<(), StepError> {
Expand Down
32 changes: 32 additions & 0 deletions src/builder/distrib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

use mopa::{Any, mopafy};

use crate::builder::commands::alpine;
Expand Down Expand Up @@ -102,3 +107,30 @@ impl DistroBox for Box<dyn Distribution> {
Ok(())
}
}

pub fn parse_release_file(
path: impl AsRef<Path>
) -> Result<HashMap<String, String>, String> {
let release_path = path.as_ref();
let release_file = BufReader::new(
try_msg!(
File::open(release_path),
"Error opening release file {path:?}: {err}", path=release_path
)
);

let mut vars = HashMap::new();
for line in release_file.lines() {
let line = try_msg!(
line,
"Error reading release file {path:?}: {err}", path=release_path
);
if let Some(equals_pos) = line.find('=') {
let key = line[..equals_pos].trim();
let value = line[(equals_pos + 1)..].trim();
vars.insert(key.to_string(), value.to_string());
}
}

Ok(vars)
}
18 changes: 18 additions & 0 deletions tests/docker.bats
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ setup() {
assert_line "Hello from Docker!"
}

@test "docker: detect ubuntu" {
run vagga _build ubuntu
assert_success

run vagga _run ubuntu sh -c 'echo 21*2 | bc'
assert_success
assert_output 42
}

@test "docker: detect alpine" {
run vagga _build alpine
assert_success

run vagga _run alpine sh -c 'echo 21*2 | bc'
assert_success
assert_output 42
}

@test "docker: python" {
run vagga _build python
assert_success
Expand Down
10 changes: 10 additions & 0 deletions tests/docker/vagga.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ containers:
- !DockerImage
image: library/hello-world

ubuntu:
setup:
- !DockerImage ubuntu:focal
- !Install [bc]

alpine:
setup:
- !DockerImage alpine:3.15
- !Install [bc]

python:
setup:
- !DockerImage
Expand Down

0 comments on commit f5ef9fa

Please sign in to comment.