Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A series of fixes and small improvements #42

Merged
merged 8 commits into from
Apr 13, 2024
15 changes: 3 additions & 12 deletions docs/2-podman-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ this and do other first-boot customization, you can provide a [cloud-init]
NoCloud configuration to the VM by passing in the non-standard option
`--cloud-init` *after* the image specification:

> For this command to work with Docker, you must provide an absolute path to
> `--cloud-init`.

```console
$ ls examples/cloud-init/config/
meta-data user-data vendor-data
Expand All @@ -117,7 +114,7 @@ $ podman run \
--runtime crun-vm \
-it --rm \
quay.io/containerdisks/fedora:39 \
--cloud-init examples/cloud-init/config
--cloud-init ~/examples/cloud-init/config # path must be absolute
```

You should now be able to log in with the default `fedora` username and password
Expand All @@ -139,15 +136,12 @@ $ podman run \
Similarly, you can provide an [Ignition] configuration to the VM by passing in
the `--ignition` option:

> For this command to work with Docker, you must provide an absolute path to
> `--ignition`.

```console
$ podman run \
--runtime crun-vm \
-it --rm \
quay.io/crun-vm/example-fedora-coreos:39 \
--ignition examples/ignition/config.ign
--ignition ~/examples/ignition/config.ign # path must be absolute
```

You should now be able to log in with the default `core` username and password
Expand Down Expand Up @@ -312,16 +306,13 @@ option also allows you specify a regular file as the source, and the source may
be in any disk format known to QEMU (*e.g.*, raw, qcow2; when using `--device`,
raw format is assumed):

> For this command to work with Docker, you must provide absolute paths to
> `--blockdev`.

```console
$ podman run \
--runtime crun-vm \
-it --rm \
quay.io/containerdisks/fedora:39 \
--password pass \
--blockdev source=my-disk.qcow2,target=/home/fedora/my-disk,format=qcow2
--blockdev source=~/my-disk.qcow2,target=/home/fedora/my-disk,format=qcow2 # paths must be absolute
```

## Advanced options
Expand Down
3 changes: 3 additions & 0 deletions scripts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ virsh --connect "qemu+unix:///session?socket=$socket" "\$@"
EOF
chmod +x /crun-vm/virsh

# remove if present from previous boot
rm -f /crun-vm/ssh-successful

# launch VM

function __bg_ensure_tty() {
Expand Down
23 changes: 18 additions & 5 deletions scripts/exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,36 @@

set -e

timeout=$1
user=$2
command=( "${@:3}" )

__ssh() {
ssh \
-o LogLevel=ERROR \
-o StrictHostKeyChecking=no \
-l "$1" \
-o UserKnownHostsFile=/dev/null \
-l "$user" \
localhost \
"${@:2}"
"$@"
}

if [[ ! -e /crun-vm/ssh-successful ]]; then

# retry ssh for some time, ignoring some common errors

for (( i = 0; i < 60; ++i )); do
start_time=$( date +%s )
end_time=$(( start_time + timeout ))

while true; do

if (( timeout > 0 && $( date +%s ) >= end_time )); then
>&2 echo "exec timed out while attempting ssh"
exit 255
fi

set +e
output=$( __ssh "$1" -o BatchMode=yes </dev/null 2>&1 )
output=$( __ssh -o BatchMode=yes </dev/null 2>&1 )
exit_code=$?
set -e

Expand All @@ -43,4 +56,4 @@ if [[ ! -e /crun-vm/ssh-successful ]]; then

fi

__ssh "$1" -- "${@:2}"
__ssh -- "${command[@]}"
80 changes: 31 additions & 49 deletions src/commands/create/custom_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,57 +110,39 @@ impl CustomOptions {
Ok(path_in_host)
}

match env {
RuntimeEnv::Docker => {
// Docker doesn't run the runtime with the same working directory as the process
// that launched `docker-run`, so we require custom option paths to be absolute.
//
// TODO: There must be a better way...
ensure!(
all_are_absolute(options.blockdev.iter().flat_map(|b| [&b.source, &b.target]))
&& all_are_absolute(&options.cloud_init)
&& all_are_absolute(&options.ignition)
&& all_are_absolute(&options.merge_libvirt_xml),
concat!(
"paths specified using --blockdev, --cloud-init, --ignition, or",
" --merge-libvirt-xml must be absolute when using crun-vm as a Docker",
" runtime",
),
);
// Docker doesn't run the runtime with the same working directory as the process
// that launched `docker-run`. Similarly, custom option paths in Kubernetes refer to
// paths in the container/VM, and there isn't a reasonable notion of what the
// current directory is. We thus simply always require custom option paths to be
// absolute.
ensure!(
all_are_absolute(options.blockdev.iter().flat_map(|b| [&b.source, &b.target]))
&& all_are_absolute(&options.cloud_init)
&& all_are_absolute(&options.ignition)
&& all_are_absolute(&options.merge_libvirt_xml),
concat!(
"paths specified using --blockdev, --cloud-init, --ignition, or",
" --merge-libvirt-xml must be absolute",
),
);

if env == RuntimeEnv::Kubernetes {
for blockdev in &mut options.blockdev {
blockdev.source = path_in_container_into_path_in_host(spec, &blockdev.source)?;
blockdev.target = path_in_container_into_path_in_host(spec, &blockdev.target)?;
}

if let Some(path) = &mut options.cloud_init {
*path = path_in_container_into_path_in_host(spec, &path)?;
}
RuntimeEnv::Kubernetes => {
// Custom option paths in Kubernetes refer to paths in the container/VM, and there
// isn't a reasonable notion of what the current directory is.
ensure!(
all_are_absolute(options.blockdev.iter().flat_map(|b| [&b.source, &b.target]))
&& all_are_absolute(&options.cloud_init)
&& all_are_absolute(&options.ignition)
&& all_are_absolute(&options.merge_libvirt_xml),
concat!(
"paths specified using --blockdev, --cloud-init, --ignition, or",
" --merge-libvirt-xml must be absolute when using crun-vm as a",
" Kubernetes runtime",
),
);

for blockdev in &mut options.blockdev {
blockdev.source = path_in_container_into_path_in_host(spec, &blockdev.source)?;
blockdev.target = path_in_container_into_path_in_host(spec, &blockdev.target)?;
}

if let Some(path) = &mut options.cloud_init {
*path = path_in_container_into_path_in_host(spec, &path)?;
}

if let Some(path) = &mut options.ignition {
*path = path_in_container_into_path_in_host(spec, &path)?;
}

for path in &mut options.merge_libvirt_xml {
*path = path_in_container_into_path_in_host(spec, &path)?;
}

if let Some(path) = &mut options.ignition {
*path = path_in_container_into_path_in_host(spec, &path)?;
}

for path in &mut options.merge_libvirt_xml {
*path = path_in_container_into_path_in_host(spec, &path)?;
}
RuntimeEnv::Other => {}
}

Ok(options)
Expand Down
2 changes: 1 addition & 1 deletion src/commands/create/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn generate(
s(&mut w, "domain", &[("type", "kvm")], |w| {
st(w, "name", &[], "domain")?;

se(w, "cpu", &[("mode", "host-model")])?;
se(w, "cpu", &[("mode", "host-passthrough")])?;
let vcpus = get_vcpu_count(spec).to_string();
if let Some(cpu_set) = get_cpu_set(spec) {
st(w, "vcpu", &[("cpuset", cpu_set.as_str())], vcpus.as_str())?;
Expand Down
Loading