Add --bootc-disk-size option
It allows settings the disk size of the VM image that is generated from a bootc container image. Also improve the default disk size by basing it on the container image size. Signed-off-by: Alberto Faria <afaria@redhat.com>
This commit is contained in:
parent
1c63aee915
commit
5c399d6b43
|
|
@ -111,6 +111,10 @@ $ podman run \
|
|||
Internally, crun-vm generates a VM image from the bootable container and then
|
||||
boots it.
|
||||
|
||||
By default, the VM image is given a disk size roughly double the size of the
|
||||
bootc container image. To change this, use the `--bootc-disk-size <size>[KMGT]`
|
||||
option.
|
||||
|
||||
## First-boot customization
|
||||
|
||||
### cloud-init
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ engine=$1
|
|||
container_id=$2
|
||||
original_root=$3
|
||||
priv_dir=$4
|
||||
disk_size=$5
|
||||
|
||||
__step() {
|
||||
printf "\033[36m%s\033[0m\n" "$*"
|
||||
|
|
@ -79,7 +80,20 @@ else
|
|||
|
||||
# run bootc-install under krun
|
||||
|
||||
truncate --size 10G "$bootc_dir/image.raw" # TODO: allow adjusting disk size
|
||||
if [[ -z "$disk_size" ]]; then
|
||||
container_image_size=$(
|
||||
"$engine" image inspect --format '{{.VirtualSize}}' "$image_id"
|
||||
)
|
||||
|
||||
# use double the container image size to allow for in-place updates
|
||||
disk_size=$(( container_image_size * 2 ))
|
||||
|
||||
# round up to 1 MiB
|
||||
alignment=$(( 2**20 ))
|
||||
disk_size=$(( (disk_size + alignment - 1) / alignment * alignment ))
|
||||
fi
|
||||
|
||||
truncate --size "$disk_size" "$bootc_dir/image.raw"
|
||||
|
||||
trap 'krun delete --force "$container_name" >/dev/null 2>&1 || true' EXIT
|
||||
krun run --config "$bootc_dir/config.json" "$container_name" </dev/ptmx
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ pub struct CustomOptions {
|
|||
#[clap(long, help = "Use system emulation rather than KVM")]
|
||||
pub emulated: bool,
|
||||
|
||||
#[clap(long)]
|
||||
pub bootc_disk_size: Option<String>,
|
||||
|
||||
#[clap(long)]
|
||||
pub cloud_init: Option<Utf8PathBuf>,
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ use std::process::{Command, Stdio};
|
|||
|
||||
use anyhow::{anyhow, bail, ensure, Context, Result};
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use lazy_static::lazy_static;
|
||||
use nix::sys::stat::{major, makedev, minor, mknod, Mode, SFlag};
|
||||
use regex::Regex;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
use crate::commands::create::custom_opts::CustomOptions;
|
||||
|
|
@ -38,12 +40,7 @@ pub fn create(args: &liboci_cli::Create, raw_args: &[impl AsRef<OsStr>]) -> Resu
|
|||
|
||||
let engine = Engine::detect(&args.container_id, bundle_path, &spec, &original_root_path)?;
|
||||
let custom_options = CustomOptions::from_spec(&spec, engine)?;
|
||||
let is_bootc_container = is_bootc_container(&original_root_path, engine)?;
|
||||
|
||||
ensure!(
|
||||
!is_bootc_container || !custom_options.emulated,
|
||||
"--emulated is incompatible with bootable containers"
|
||||
);
|
||||
let is_bootc_container = is_bootc_container(&original_root_path, &custom_options, engine)?;
|
||||
|
||||
// We include container_id in our paths to ensure no overlap with the user container's contents.
|
||||
let priv_dir_path = original_root_path.join(format!("crun-vm-{}", args.container_id));
|
||||
|
|
@ -121,6 +118,7 @@ pub fn create(args: &liboci_cli::Create, raw_args: &[impl AsRef<OsStr>]) -> Resu
|
|||
.arg(&args.container_id)
|
||||
.arg(&original_root_path)
|
||||
.arg(&priv_dir_path)
|
||||
.arg(custom_options.bootc_disk_size.unwrap_or_default())
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
|
|
@ -152,7 +150,11 @@ fn ensure_unprivileged(spec: &oci_spec::runtime::Spec) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_bootc_container(original_root_path: &Utf8Path, engine: Engine) -> Result<bool> {
|
||||
fn is_bootc_container(
|
||||
original_root_path: &Utf8Path,
|
||||
custom_options: &CustomOptions,
|
||||
engine: Engine,
|
||||
) -> Result<bool> {
|
||||
let is_bootc_container = original_root_path.join("usr/lib/bootc/install").is_dir();
|
||||
|
||||
ensure!(
|
||||
|
|
@ -160,6 +162,31 @@ fn is_bootc_container(original_root_path: &Utf8Path, engine: Engine) -> Result<b
|
|||
"bootc containers are only supported with Podman and Docker"
|
||||
);
|
||||
|
||||
ensure!(
|
||||
!is_bootc_container || !custom_options.emulated,
|
||||
"--emulated is incompatible with bootable containers"
|
||||
);
|
||||
|
||||
if let Some(size) = &custom_options.bootc_disk_size {
|
||||
lazy_static! {
|
||||
static ref SIZE_PATTERN: Regex = Regex::new(r"^[0-9]+[KMGT]?$").unwrap();
|
||||
}
|
||||
|
||||
ensure!(
|
||||
SIZE_PATTERN.is_match(size),
|
||||
concat!(
|
||||
"--bootc-disk-size value must be a number followed by an optional suffix K",
|
||||
" (kilobyte, 1024), M (megabyte, 1024k), G (gigabyte, 1024M), or T (terabyte,",
|
||||
" 1024G)",
|
||||
)
|
||||
);
|
||||
|
||||
ensure!(
|
||||
is_bootc_container,
|
||||
"--bootc-disk-size only applies to bootable containers"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(is_bootc_container)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
image="${TEST_IMAGES[fedora-bootc]}"
|
||||
user="${TEST_IMAGES_DEFAULT_USER[fedora-bootc]}"
|
||||
|
||||
__run() {
|
||||
__engine run --detach --name bootc-disk-size "$image" --bootc-disk-size "$1"
|
||||
}
|
||||
|
||||
! RUST_LIB_BACKTRACE=0 __run 0
|
||||
__engine rm bootc-disk-size
|
||||
|
||||
for size in 1K 1M; do
|
||||
__run "$size"
|
||||
! __engine exec bootc-disk-size --as "$user"
|
||||
__engine rm --force bootc-disk-size
|
||||
done
|
||||
|
||||
for size in 1G 1T 1024T; do
|
||||
__run "$size"
|
||||
__engine exec bootc-disk-size --as "$user"
|
||||
__engine rm --force bootc-disk-size
|
||||
done
|
||||
Loading…
Reference in New Issue