blob: ae2585999d43a924cc06953db7893f6f45d57da4 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::env;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::str;
use sdk::{fuchsia_root, target_out_dir, TargetOptions};
use utils::is_mac;
error_chain!{
foreign_links {
Io(::std::io::Error);
}
links {
SDK(::sdk::Error, ::sdk::ErrorKind);
}
}
pub fn netaddr(verbose: bool) -> Result<String> {
let fuchsia_root = fuchsia_root()?;
let netaddr_binary = fuchsia_root.join("out/build-magenta/tools/netaddr");
let netaddr_result = Command::new(netaddr_binary).arg("--fuchsia")
.output()?;
let result = str::from_utf8(&netaddr_result.stdout).unwrap().trim().to_string();
if verbose {
println!("netaddr result = {}", result);
}
Ok(result)
}
pub fn scp_to_device(verbose: bool,
target_options: &TargetOptions,
netaddr: &str,
source_path: &PathBuf,
destination_path: &str)
-> Result<()> {
let destination_with_address = format!("[{}]:{}", netaddr, destination_path);
let ssh_config = target_out_dir(&target_options)?.join("ssh-keys/ssh_config");
if !ssh_config.exists() {
bail!("ssh config not found at {:?}", ssh_config);
}
if verbose {
println!("destination_with_address = {}", destination_with_address);
println!("ssh_config = {:?}", ssh_config);
}
let mut scp_command = Command::new("scp");
scp_command.arg(if verbose { "-v" } else { "-q" })
.arg("-F")
.arg(ssh_config)
.args(&["-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no"])
.arg(source_path)
.arg(destination_with_address);
if verbose {
println!("{:?}", scp_command);
}
let scp_result = scp_command.status()
.chain_err(|| "unable to run scp")?;
if !scp_result.success() {
bail!("scp failed with error {:?}", scp_result);
}
Ok(())
}
pub fn ssh(verbose: bool, target_options: &TargetOptions, command: &str) -> Result<()> {
let netaddr = netaddr(verbose)?;
let ssh_config = target_out_dir(&target_options)?.join("ssh-keys/ssh_config");
if !ssh_config.exists() {
bail!("ssh config not found at {:?}", ssh_config);
}
let ssh_result = Command::new("ssh").arg("-q")
.arg("-F")
.arg(ssh_config)
.args(&["-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no"])
.arg(netaddr)
.arg(command)
.status()
.chain_err(|| "unable to run ssh")?;
if !ssh_result.success() {
bail!("ssh failed: {}", ssh_result);
}
Ok(())
}
pub fn start_emulator(with_graphics: bool, target_options: &TargetOptions) -> Result<()> {
let fuchsia_root = fuchsia_root()?;
let run_magenta_script = fuchsia_root.join("scripts/run-magenta-x86-64");
if !run_magenta_script.exists() {
bail!("run magenta script not found at {:?}", run_magenta_script);
}
let user_bootfs = target_out_dir(&target_options)?.join("user.bootfs");
if !user_bootfs.exists() {
bail!("user.bootfs not found at {:?}", user_bootfs);
}
let user_bootfs_str = user_bootfs.to_str().unwrap();
let mut args = vec!["-N", "-x", user_bootfs_str];
if with_graphics {
args.push("-g");
}
let child = Command::new(run_magenta_script).args(&args)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.chain_err(|| "unable to run magenta")?;
println!("emulator started with process ID {}", child.id());
if is_mac() {
let user = env::var("USER").unwrap();
// TODO; Poll for /dev/tap0 as it can take a while for the emulator
// to create it.
println!("Calling sudo ifconfig to bring up tap0 interface; password may be required.");
let chown_status = Command::new("sudo").arg("chown")
.arg(user)
.arg("/dev/tap0")
.status()
.chain_err(|| "couldn't run chown")?;
if !chown_status.success() {
bail!("chown failed: {}", chown_status);
}
let ifconfig_status = Command::new("sudo").arg("ifconfig")
.arg("tap0")
.arg("inet6")
.arg("fc00::/7")
.arg("up")
.status()
.chain_err(|| "couldn't run ifconfig")?;
if !ifconfig_status.success() {
bail!("ifconfig failed: {}", chown_status);
}
println!("tap0 enabled");
Command::new("stty").arg("sane")
.status()
.chain_err(|| "couldn't run stty")?;
}
Ok(())
}
pub fn stop_emulator() -> Result<()> {
Command::new("killall").arg("qemu-system-x86_64")
.status()?;
Ok(())
}