Skip to content

Commit

Permalink
Merge pull request #36 from slp/macos-rosetta
Browse files Browse the repository at this point in the history
macos: add support for running x86 microVMs on ARM64
  • Loading branch information
slp authored Nov 7, 2022
2 parents e67d0ea + 242a740 commit 12dac81
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "krunvm"
version = "0.2.2"
version = "0.2.3"
authors = ["Sergio Lopez <[email protected]>"]
description = "Create microVMs from OCI images"
repository = "https://github.com/containers/krunvm"
Expand Down
52 changes: 51 additions & 1 deletion src/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

use std::fs;
use std::io::Write;
#[cfg(target_os = "macos")]
use std::path::Path;
use std::process::Command;

use super::utils::{
Expand All @@ -11,6 +13,9 @@ use super::utils::{
};
use crate::{ArgMatches, KrunvmConfig, VmConfig, APP_NAME};

#[cfg(target_os = "macos")]
const KRUNVM_ROSETTA_FILE: &str = ".krunvm-rosetta";

fn fix_resolv_conf(rootfs: &str, dns: &str) -> Result<(), std::io::Error> {
let resolvconf_dir = format!("{}/etc/", rootfs);
fs::create_dir_all(resolvconf_dir)?;
Expand Down Expand Up @@ -62,7 +67,7 @@ fn export_container_config(
}

pub fn create(cfg: &mut KrunvmConfig, matches: &ArgMatches) {
let cpus = match matches.value_of("cpus") {
let mut cpus = match matches.value_of("cpus") {
Some(c) => match c.parse::<u32>() {
Err(_) => {
println!("Invalid value for \"cpus\"");
Expand Down Expand Up @@ -114,6 +119,47 @@ pub fn create(cfg: &mut KrunvmConfig, matches: &ArgMatches) {
}

let mut args = get_buildah_args(cfg, BuildahCommand::From);

#[cfg(target_os = "macos")]
let force_x86 = matches.is_present("x86");

#[cfg(target_os = "macos")]
if force_x86 {
let home = match std::env::var("HOME") {
Err(e) => {
println!("Error reading \"HOME\" enviroment variable: {}", e);
std::process::exit(-1);
}
Ok(home) => home,
};

let path = format!("{}/{}", home, KRUNVM_ROSETTA_FILE);
if !Path::new(&path).is_file() {
println!(
"
To use Rosetta for Linux you need to create the file...
{}
...with the contents that the \"rosetta\" binary expects to be served from
its specific ioctl.
For more information, please refer to this post:
https://threedots.ovh/blog/2022/06/quick-look-at-rosetta-on-linux/
",
path
);
std::process::exit(-1);
}

if cpus != 1 {
println!("x86 microVMs on Aarch64 are restricted to 1 CPU");
cpus = 1;
}
args.push("--arch".to_string());
args.push("x86_64".to_string());
}

args.push(image.to_string());

let output = match Command::new("buildah")
Expand Down Expand Up @@ -161,6 +207,10 @@ pub fn create(cfg: &mut KrunvmConfig, matches: &ArgMatches) {
let rootfs = mount_container(cfg, &vmcfg).unwrap();
export_container_config(cfg, &rootfs, image).unwrap();
fix_resolv_conf(&rootfs, dns).unwrap();
#[cfg(target_os = "macos")]
if force_x86 {
_ = fs::create_dir(format!("{}/.rosetta", rootfs));
}
umount_container(cfg, &vmcfg).unwrap();

cfg.vmconfig_map.insert(name.clone(), vmcfg);
Expand Down
128 changes: 69 additions & 59 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,65 +246,6 @@ fn main() {
.takes_value(true),
),
)
.subcommand(
App::new("create")
.about("Create a new microVM")
.arg(
Arg::with_name("cpus")
.long("cpus")
.help("Number of vCPUs")
.takes_value(true),
)
.arg(
Arg::with_name("mem")
.long("mem")
.help("Amount of RAM in MiB")
.takes_value(true),
)
.arg(
Arg::with_name("dns")
.long("dns")
.help("DNS server to use in the microVM")
.takes_value(true),
)
.arg(
Arg::with_name("workdir")
.long("workdir")
.short("w")
.help("Working directory inside the microVM")
.takes_value(true)
.default_value(""),
)
.arg(
Arg::with_name("volume")
.long("volume")
.short("v")
.help("Volume in form \"host_path:guest_path\" to be exposed to the guest")
.takes_value(true)
.multiple(true)
.number_of_values(1),
)
.arg(
Arg::with_name("port")
.long("port")
.short("p")
.help("Port in format \"host_port:guest_port\" to be exposed to the host")
.takes_value(true)
.multiple(true)
.number_of_values(1),
)
.arg(
Arg::with_name("name")
.long("name")
.help("Assign a name to the VM")
.takes_value(true),
)
.arg(
Arg::with_name("IMAGE")
.help("OCI image to use as template")
.required(true),
),
)
.subcommand(
App::new("delete").about("Delete an existing microVM").arg(
Arg::with_name("NAME")
Expand Down Expand Up @@ -348,6 +289,75 @@ fn main() {
),
);

let mut create = App::new("create")
.about("Create a new microVM")
.arg(
Arg::with_name("cpus")
.long("cpus")
.help("Number of vCPUs")
.takes_value(true),
)
.arg(
Arg::with_name("mem")
.long("mem")
.help("Amount of RAM in MiB")
.takes_value(true),
)
.arg(
Arg::with_name("dns")
.long("dns")
.help("DNS server to use in the microVM")
.takes_value(true),
)
.arg(
Arg::with_name("workdir")
.long("workdir")
.short("w")
.help("Working directory inside the microVM")
.takes_value(true)
.default_value(""),
)
.arg(
Arg::with_name("volume")
.long("volume")
.short("v")
.help("Volume in form \"host_path:guest_path\" to be exposed to the guest")
.takes_value(true)
.multiple(true)
.number_of_values(1),
)
.arg(
Arg::with_name("port")
.long("port")
.short("p")
.help("Port in format \"host_port:guest_port\" to be exposed to the host")
.takes_value(true)
.multiple(true)
.number_of_values(1),
)
.arg(
Arg::with_name("name")
.long("name")
.help("Assign a name to the VM")
.takes_value(true),
)
.arg(
Arg::with_name("IMAGE")
.help("OCI image to use as template")
.required(true),
);

if cfg!(target_os = "macos") {
create = create.arg(
Arg::with_name("x86")
.long("x86")
.short("x")
.help("Create a x86_64 microVM even on an Aarch64 host"),
);
}

app = app.subcommand(create);

let matches = app.clone().get_matches();

#[cfg(target_os = "macos")]
Expand Down

0 comments on commit 12dac81

Please sign in to comment.