func (c *Cluster) bootstrapFlynn() error { inst := c.instances[0] c.ControllerDomain = fmt.Sprintf("flynn-%s.local", util.RandomString(16)) c.ControllerKey = util.RandomString(16) rd, wr := io.Pipe() var cmdErr error go func() { command := fmt.Sprintf( "docker run -e=DISCOVERD=%s:1111 -e CONTROLLER_DOMAIN=%s -e CONTROLLER_KEY=%s flynn/bootstrap -json -min-hosts=%d /etc/manifest.json", inst.IP(), c.ControllerDomain, c.ControllerKey, len(c.instances), ) cmdErr = inst.Run(command, attempts, wr, os.Stderr) wr.Close() }() // grab the controller tls pin from the bootstrap output var cert controllerCert dec := json.NewDecoder(rd) for { var msg bootstrapMsg if err := dec.Decode(&msg); err == io.EOF { break } else if err != nil { return fmt.Errorf("failed to parse bootstrap JSON output: %s", err) } c.log("bootstrap ===>", msg.Id, msg.State) if msg.State == "error" { c.log(msg) } if msg.Id == "controller-cert" && msg.State == "done" { json.Unmarshal(msg.Data, &cert) } } if cmdErr != nil { return cmdErr } if cert.Pin == "" { return errors.New("could not determine controller cert from bootstrap output") } c.ControllerPin = cert.Pin // grab the strowger IP from discoverd discoverd.Connect(inst.IP() + ":1111") set, err := discoverd.NewServiceSet("strowger-api") if err != nil { return fmt.Errorf("could not detect strowger ip: %s", err) } defer set.Close() leader := set.Leader() if leader == nil { return errors.New("could not detect strowger ip: no strowger-api leader") } if err = setLocalDNS(c.ControllerDomain, leader.Host); err != nil { return fmt.Errorf("could not set strowger DNS entry:", err) } return nil }
func (s *BasicSuite) TestBasic(t *c.C) { name := util.RandomString(30) t.Assert(s.Flynn("create", name), Outputs, fmt.Sprintf("Created %s\n", name)) push := s.Git("push", "flynn", "master") t.Assert(push, OutputContains, "Node.js app detected") t.Assert(push, OutputContains, "Downloading and installing node") t.Assert(push, OutputContains, "Installing dependencies") t.Assert(push, OutputContains, "Procfile declares types -> web") t.Assert(push, OutputContains, "Creating release") t.Assert(push, OutputContains, "Application deployed") t.Assert(push, OutputContains, "* [new branch] master -> master") t.Assert(s.Flynn("scale", "web=3"), Succeeds) newRoute := s.Flynn("route-add-http", util.RandomString(32)+".dev") t.Assert(newRoute, Succeeds) t.Assert(s.Flynn("routes"), OutputContains, strings.TrimSpace(newRoute.Output)) // use Attempts to give the processes time to start if err := Attempts.Run(func() error { ps := s.Flynn("ps") if ps.Err != nil { return ps.Err } psLines := strings.Split(strings.TrimSpace(ps.Output), "\n") if len(psLines) != 4 { return fmt.Errorf("Expected 4 ps lines, got %d", len(psLines)) } for _, l := range psLines[1:] { idType := regexp.MustCompile(`\s+`).Split(l, 2) if idType[1] != "web" { return fmt.Errorf("Expected web type, got %s", idType[1]) } log := s.Flynn("log", idType[0]) if !strings.Contains(log.Output, "Listening on ") { return fmt.Errorf("Expected \"%s\" to contain \"Listening on \"", log.Output) } } return nil }); err != nil { t.Error(err) } // Make HTTP requests }
func (c *Cluster) setup() error { if _, err := os.Stat(c.bc.Kernel); os.IsNotExist(err) { return fmt.Errorf("cluster: not a kernel file: %s", c.bc.Kernel) } if c.bridge == nil { var err error name := "flynnbr." + util.RandomString(5) c.logf("creating network bridge %s\n", name) c.bridge, err = createBridge(name, c.bc.Network, c.bc.NatIface) if err != nil { return fmt.Errorf("could not create network bridge: %s", err) } } c.vm = NewVMManager(c.bridge) return nil }
func (r *Runner) save(b *Build) error { if b.Id == "" { b.Id = util.RandomString(8) } return r.db.Update(func(tx *bolt.Tx) error { bkt := tx.Bucket([]byte("pending-builds")) if b.State == "pending" { val, err := json.Marshal(b) if err != nil { return err } return bkt.Put([]byte(b.Id), val) } else { return bkt.Delete([]byte(b.Id)) } }) }
func (t *TapManager) NewTap(uid, gid int) (*Tap, error) { tap := &Tap{Name: "flynntap." + util.RandomString(5), bridge: t.bridge} if err := createTap(tap.Name, uid, gid); err != nil { return nil, err } var err error tap.LocalIP, err = ipallocator.RequestIP(t.bridge.ipNet, nil) if err != nil { tap.Close() return nil, err } tap.RemoteIP, err = ipallocator.RequestIP(t.bridge.ipNet, nil) if err != nil { tap.Close() return nil, err } iface, err := net.InterfaceByName(tap.Name) if err != nil { tap.Close() return nil, err } if err := netlink.NetworkLinkAddIp(iface, *tap.LocalIP, t.bridge.ipNet); err != nil { tap.Close() return nil, err } if err := netlink.NetworkLinkUp(iface); err != nil { tap.Close() return nil, err } if err := netlink.AddToBridge(iface, t.bridge.iface); err != nil { tap.Close() return nil, err } return tap, nil }