func (p *JujuProvisioner) Provision(app provision.App) error { var buf bytes.Buffer charms, err := config.GetString("juju:charms-path") if err != nil { return errors.New(`Setting "juju:charms-path" is not defined.`) } args := []string{ "deploy", "--repository", charms, "local:" + app.GetPlatform(), app.GetName(), } err = runCmd(false, &buf, &buf, args...) out := buf.String() if err != nil { app.Log("Failed to create machine: "+out, "tsuru") return cmdError(out, err, args) } setOption := []string{ "set", app.GetName(), "app-repo=" + repository.ReadOnlyURL(app.GetName()), } runCmd(true, &buf, &buf, setOption...) if p.elbSupport() { router, err := Router() if err != nil { return err } if err = router.AddBackend(app.GetName()); err != nil { return err } p.enqueueUnits(app.GetName()) } return nil }
func (s *S) TestDockerDeployRetries(c *gocheck.C) { var buf bytes.Buffer fexec := etesting.RetryExecutor{ Failures: 3, FakeExecutor: etesting.FakeExecutor{ Output: map[string][][]byte{"*": {[]byte("connection refused")}}, }, } setExecut(&fexec) defer setExecut(nil) container := container{Id: "c-01", Ip: "10.10.10.10", AppName: "myapp"} err := container.deploy(&buf) c.Assert(err, gocheck.IsNil) commands := fexec.GetCommands("ssh") c.Assert(commands, gocheck.HasLen, 5) deployArgs := []string{ "10.10.10.10", "-l", s.sshUser, "-o", "StrictHostKeyChecking no", "--", s.deployCmd, repository.ReadOnlyURL(container.AppName), } for _, cmd := range commands[:4] { c.Check(cmd.GetArgs(), gocheck.DeepEquals, deployArgs) } runArgs := []string{ "10.10.10.10", "-l", s.sshUser, "-o", "StrictHostKeyChecking no", "--", s.runBin, s.runArgs, } c.Assert(commands[4].GetArgs(), gocheck.DeepEquals, runArgs) }
func (s *S) TestDockerDeploy(c *gocheck.C) { var buf bytes.Buffer fexec := &etesting.FakeExecutor{ Output: map[string][][]byte{"*": {[]byte("success\n")}}, } setExecut(fexec) defer setExecut(nil) container := container{Id: "c-01", Ip: "10.10.10.10", AppName: "myapp"} err := container.deploy(&buf) c.Assert(err, gocheck.IsNil) c.Assert(buf.String(), gocheck.Equals, "success\n") appRepo := repository.ReadOnlyURL(container.AppName) deployArgs := []string{ "10.10.10.10", "-l", s.sshUser, "-o", "StrictHostKeyChecking no", "--", s.deployCmd, appRepo, } runArgs := []string{ "10.10.10.10", "-l", s.sshUser, "-o", "StrictHostKeyChecking no", "--", s.runBin, s.runArgs, } c.Assert(fexec.ExecutedCmd("ssh", deployArgs), gocheck.Equals, true) c.Assert(fexec.ExecutedCmd("ssh", runArgs), gocheck.Equals, true) cont, err := getContainer(container.Id) c.Assert(err, gocheck.IsNil) c.Assert(cont.Status, gocheck.Equals, "running") }
func (s *S) TestCloneRepository(c *gocheck.C) { p := testing.NewFakeProvisioner() p.PrepareOutput([]byte("something")) app := testing.NewFakeApp("your", "python", 1) out, err := clone(p, app) c.Assert(err, gocheck.IsNil) c.Assert(string(out), gocheck.Equals, "something") url := repository.ReadOnlyURL(app.GetName()) path, _ := repository.GetPath() expectedCommand := fmt.Sprintf("git clone %s %s --depth 1", url, path) c.Assert(p.GetCmds(expectedCommand, app), gocheck.HasLen, 1) }
// Clone runs a git clone to clone the app repository in an ap. func clone(p provision.Provisioner, app provision.App) ([]byte, error) { var buf bytes.Buffer path, err := repository.GetPath() if err != nil { return nil, fmt.Errorf("Tsuru is misconfigured: %s", err) } cmd := fmt.Sprintf("git clone %s %s --depth 1", repository.ReadOnlyURL(app.GetName()), path) err = p.ExecuteCommand(&buf, &buf, app, cmd) b := buf.Bytes() log.Printf(`"git clone" output: %s`, b) return b, err }
// deployCmds returns the commands that is used when provisioner // deploy an unit. func deployCmds(app provision.App, version string) ([]string, error) { deployCmd, err := config.GetString("docker:deploy-cmd") if err != nil { return nil, err } appRepo := repository.ReadOnlyURL(app.GetName()) user, err := config.GetString("docker:ssh:user") if err != nil { return nil, err } cmds := []string{"sudo", "-u", user, deployCmd, appRepo, version} return cmds, nil }
// deployCmds returns the commands that is used when provisioner // deploy an unit. func deployCmds(app provision.App, version string) ([]string, error) { deployCmd, err := config.GetString("docker:deploy-cmd") if err != nil { return nil, err } appRepo := repository.ReadOnlyURL(app.GetName()) var envs string for _, env := range app.Envs() { envs += fmt.Sprintf("%s='%s' ", env.Name, env.Value) } cmds := []string{deployCmd, appRepo, version, envs} return cmds, nil }
func (s *S) TestDeployCmds(c *gocheck.C) { app := testing.NewFakeApp("app-name", "python", 1) deployCmd, err := config.GetString("docker:deploy-cmd") c.Assert(err, gocheck.IsNil) version := "version" appRepo := repository.ReadOnlyURL(app.GetName()) user, err := config.GetString("docker:ssh:user") c.Assert(err, gocheck.IsNil) expected := []string{"sudo", "-u", user, deployCmd, appRepo} cmds, err := deployCmds(app, version) c.Assert(err, gocheck.IsNil) c.Assert(cmds, gocheck.DeepEquals, expected) }
func (s *S) TestDeployCmds(c *gocheck.C) { app := testing.NewFakeApp("app-name", "python", 1) env := bind.EnvVar{ Name: "http_proxy", Value: "http://theirproxy.com:3128/", Public: true, } app.SetEnv(env) deployCmd, err := config.GetString("docker:deploy-cmd") c.Assert(err, gocheck.IsNil) version := "version" appRepo := repository.ReadOnlyURL(app.GetName()) expected := []string{deployCmd, appRepo, version, `http_proxy='http://theirproxy.com:3128/' `} cmds, err := deployCmds(app, version) c.Assert(err, gocheck.IsNil) c.Assert(cmds, gocheck.DeepEquals, expected) }
func (s *S) TestDeployCmds(c *gocheck.C) { h := &testing.TestHandler{} gandalfServer := testing.StartGandalfTestServer(h) defer gandalfServer.Close() app := testing.NewFakeApp("app-name", "python", 1) env := bind.EnvVar{ Name: "http_proxy", Value: "[http://theirproxy.com:3128/, http://teste.com:3111]", Public: true, } app.SetEnv(env) deployCmd, err := config.GetString("docker:deploy-cmd") c.Assert(err, gocheck.IsNil) version := "version" appRepo := repository.ReadOnlyURL(app.GetName()) expected := []string{deployCmd, appRepo, version, `http_proxy=[http://theirproxy.com:3128/,http://teste.com:3111] `} cmds, err := deployCmds(app, version) c.Assert(err, gocheck.IsNil) c.Assert(cmds, gocheck.DeepEquals, expected) }
func (s *S) TestProvision(c *gocheck.C) { fexec := &etesting.FakeExecutor{} setExecut(fexec) defer setExecut(nil) config.Set("juju:charms-path", "/etc/juju/charms") defer config.Unset("juju:charms-path") config.Set("host", "somehost") defer config.Unset("host") app := testing.NewFakeApp("trace", "python", 0) p := JujuProvisioner{} err := p.Provision(app) c.Assert(err, gocheck.IsNil) args := []string{ "deploy", "--repository", "/etc/juju/charms", "local:python", "trace", } c.Assert(fexec.ExecutedCmd("juju", args), gocheck.Equals, true) args = []string{ "set", "trace", "app-repo=" + repository.ReadOnlyURL("trace"), } c.Assert(fexec.ExecutedCmd("juju", args), gocheck.Equals, true) }
func (c *container) deploy(w io.Writer) error { deployCmd, err := config.GetString("docker:deploy-cmd") if err != nil { c.setStatus("error") return err } runBin, err := config.GetString("docker:run-cmd:bin") if err != nil { c.setStatus("error") return err } runArgs, _ := config.GetString("docker:run-cmd:args") appRepo := repository.ReadOnlyURL(c.AppName) filter := filter{w: w, content: []byte("connection refused")} for { err = c.ssh(w, &filter, deployCmd, appRepo) if err == nil { break } if !filter.filtered { c.setStatus("error") return err } log.Printf("SSH to the container %q failed. Will retry.", c.Id) time.Sleep(100e6) filter.filtered = false } var buf bytes.Buffer err = c.ssh(&buf, &buf, runBin, strings.Fields(runArgs)...) if err != nil { log.Printf("Failed to start container: %s", err) log.Printf("Output of the command: %s", buf.String()) c.setStatus("error") return err } c.setStatus("running") return nil }