1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! The `conductor up` command.

use command_runner::{Command, CommandRunner};
#[cfg(test)]
use command_runner::TestCommandRunner;
use ovr::Override;
use pod::PodType;
use project::Project;
use util::{Error, err};

/// We implement `conductor up` with a trait so we put it in its own module.
pub trait CommandUp {
    /// Up all the images associated with a project.
    fn up_all<CR>(&self, runner: &CR, ovr: &Override) -> Result<(), Error>
        where CR: CommandRunner;

    /// Up all the images in the specified pods.
    fn up<CR>(&self,
              runner: &CR,
              ovr: &Override,
              pod_names: &[&str])
              -> Result<(), Error>
        where CR: CommandRunner;
}

impl CommandUp for Project {
    fn up_all<CR>(&self, runner: &CR, ovr: &Override) -> Result<(), Error>
        where CR: CommandRunner
    {
        let pod_names: Vec<_> = self.pods().map(|p| p.name()).collect();
        self.up(runner, ovr, &pod_names)
    }

    fn up<CR>(&self,
              runner: &CR,
              ovr: &Override,
              pods_names: &[&str])
              -> Result<(), Error>
        where CR: CommandRunner
    {
        for pod_name in pods_names {
            let pod = try!(self.pod(pod_name)
                .ok_or_else(|| err!("Cannot find pod {}", pod_name)));
            if pod.pod_type() == PodType::Service && pod.enabled_in(ovr) {
                // We pass `-d` because we need to detach from each pod to
                // launch the next.  To avoid this, we'd need to use
                // multiple parallel threads and maybe some intelligent
                // output buffering.
                let status = try!(runner.build("docker-compose")
                    .args(&try!(pod.compose_args(self, ovr)))
                    .arg("up")
                    .arg("-d")
                    .status());
                if !status.success() {
                    return Err(err("Error running docker-compose"));
                }
            }
        }
        Ok(())
    }
}

#[test]
fn runs_docker_compose_up_on_all_pods() {
    use env_logger;
    let _ = env_logger::init();
    let proj = Project::from_example("hello").unwrap();
    let ovr = proj.ovr("development").unwrap();
    let runner = TestCommandRunner::new();
    proj.output(ovr).unwrap();
    proj.up_all(&runner, ovr).unwrap();
    assert_ran!(runner, {
        ["docker-compose",
         "-p",
         "hello",
         "-f",
         proj.output_dir().join("pods/frontend.yml"),
         "up",
         "-d"]
    });
    proj.remove_test_output().unwrap();
}

#[test]
fn runs_docker_compose_up_on_specified_pods() {
    use env_logger;
    let _ = env_logger::init();
    let proj = Project::from_example("rails_hello").unwrap();
    let ovr = proj.ovr("development").unwrap();
    let runner = TestCommandRunner::new();
    proj.output(ovr).unwrap();
    proj.up(&runner, ovr, &["db"]).unwrap();
    assert_ran!(runner, {
        ["docker-compose",
         "-p",
         "rails_hello",
         "-f",
         proj.output_dir().join("pods/db.yml"),
         "up",
         "-d"]
    });
    proj.remove_test_output().unwrap();
}

#[test]
fn runs_docker_compose_up_honors_only_in_overrides() {
    use env_logger;
    let _ = env_logger::init();
    let proj = Project::from_example("rails_hello").unwrap();
    let ovr = proj.ovr("production").unwrap();
    let runner = TestCommandRunner::new();
    proj.output(ovr).unwrap();
    proj.up_all(&runner, ovr).unwrap();
    assert_ran!(runner, {
        ["docker-compose",
         "-p",
         "rails_hello",
         "-f",
         proj.output_dir().join("pods/frontend.yml"),
         "up",
         "-d"]
    });
    proj.remove_test_output().unwrap();
}