func UpdateAllMachines(flags *UpdateFlags, log *logging.Logger) error { // Get all members members, err := flags.GetClusterMembers(log) if err != nil { return maskAny(err) } // Pull image on all machines log.Infof("Pulling gluon image on %d machines", len(members)) var pullGroup errgroup.Group for _, m := range members { m := m pullGroup.Go(func() error { return maskAny(pullImage(m, *flags, log)) }) } if err := pullGroup.Wait(); err != nil { return maskAny(err) } // Update all machines, one at a time for index, m := range members { if index > 0 { log.Infof("Waiting %s...", flags.MachineDelay) time.Sleep(flags.MachineDelay) } if err := updateMachine(m, *flags, log); err != nil { return maskAny(err) } } return nil }
func initMakefile(log *log.Logger, projectDir, projectType string) error { if projectType != ProjectTypeGo { return nil } path := filepath.Join(projectDir, makefilePath) if info, err := os.Stat(path); os.IsNotExist(err) { log.Infof("Creating %s", makefilePath) options := struct { GoVersion string }{ GoVersion: "1.7.3-alpine", } t, err := template.New("makefile").Parse(initialMakefile) if err != nil { return maskAny(err) } buffer := &bytes.Buffer{} if err := t.Execute(buffer, options); err != nil { return maskAny(err) } if err := ioutil.WriteFile(path, buffer.Bytes(), 0644); err != nil { return maskAny(err) } return nil } else if err != nil { return maskAny(err) } else if info.IsDir() { return maskAny(fmt.Errorf("%s must be a file", path)) } else { log.Debugf("%s already initialized in %s", gitIgnorePath, projectDir) return nil } }
func initGitIgnore(log *log.Logger, projectDir string) error { path := filepath.Join(projectDir, gitIgnorePath) if info, err := os.Stat(path); os.IsNotExist(err) { log.Infof("Creating %s", gitIgnorePath) if err := ioutil.WriteFile(path, []byte(initialGitIgnore), 0644); err != nil { return maskAny(err) } return nil } else if err != nil { return maskAny(err) } else if info.IsDir() { return maskAny(fmt.Errorf("%s must be a file", path)) } else { log.Debugf("%s already initialized in %s", gitIgnorePath, projectDir) return nil } }
func updateMachine(member service.ClusterMember, flags UpdateFlags, log *logging.Logger) error { askConfirmation := flags.AskConfirmation log.Infof("Updating %s...", member.ClusterIP) // Extract gluon binary cmd := fmt.Sprintf("docker run --rm -v /home/core/bin/:/destination/ %s", flags.GluonImage) if _, err := runRemoteCommand(member, flags.UserName, log, cmd, "", false); err != nil { return maskAny(err) } // Update image version on disk if _, err := runRemoteCommand(member, flags.UserName, log, "sudo tee /etc/pulcy/gluon-image", flags.GluonImage, false); err != nil { return maskAny(err) } // Setup new gluon version if _, err := runRemoteCommand(member, flags.UserName, log, "sudo systemctl restart gluon", "", false); err != nil { return maskAny(err) } // Reboot if needed if flags.Reboot { log.Infof("Rebooting %s...", member.ClusterIP) runRemoteCommand(member, flags.UserName, log, "sudo reboot -f", "", true) time.Sleep(time.Second * 15) if err := waitUntilMachineUp(member, flags, log); err != nil { return maskAny(err) } if !member.EtcdProxy { log.Warningf("Core machine %s is back up, check services", member.ClusterIP) askConfirmation = true } else { log.Infof("Machine %s is back up", member.ClusterIP) } } if askConfirmation { confirm("Can we continue?") } return nil }
// Get ensures that flags.Folder contains an up to date copy of flags.RepoUrl checked out to flags.Version. func Get(log *log.Logger, flags *Flags) error { // Get cache dir cachedir, cacheIsValid, err := cache.Dir(flags.RepoUrl, 0) if err != nil { return maskAny(err) } // Expand folder flags.Folder, err = filepath.Abs(flags.Folder) if err != nil { return maskAny(err) } // Get current folder wd, _ := os.Getwd() linked := false if flags.AllowLink { if info, err := util.ParseVCSURL(flags.RepoUrl); err == nil { siblingPath := filepath.Join(filepath.Dir(wd), info.Name) if _, err := os.Stat(siblingPath); err == nil { //log.Infof("Sibling folder %s exists", siblingPath) util.ExecuteInDir(siblingPath, func() error { remote, err := git.GetRemoteOriginUrl(nil) if err != nil { return maskAny(err) } if remote == flags.RepoUrl { if relPath, err := filepath.Rel(filepath.Dir(flags.Folder), siblingPath); err == nil { if err := os.Symlink(relPath, flags.Folder); err == nil { log.Infof("Linked -> %s", siblingPath) linked = true if vendorDir, err := golang.GetVendorDir(siblingPath); err != nil { return maskAny(err) } else { // Flatten sibling in copy-only mode if err := golang.Flatten(log, &golang.FlattenFlags{ VendorDir: vendorDir, NoRemove: true, }); err != nil { return maskAny(err) } } } } } return nil }) } } } if linked { return nil } // Fill cache if needed cloned := false if !cacheIsValid { // Clone repo into cachedir if err := git.Clone(log, flags.RepoUrl, cachedir); err != nil { return maskAny(err) } cloned = true } // Make sure a clone exists _, err = os.Stat(flags.Folder) if os.IsNotExist(err) { // Sync into target folder if err := os.MkdirAll(flags.Folder, 0777); err != nil { return maskAny(err) } if err := util.ExecPrintError(nil, "rsync", "-a", appendDirSep(cachedir), appendDirSep(flags.Folder)); err != nil { return maskAny(err) } } // Change dir to folder if err := os.Chdir(flags.Folder); err != nil { return maskAny(err) } // Specific version needed? if flags.Version == "" { // Get latest version if !cloned { localCommit, err := git.GetLatestLocalCommit(nil, flags.Folder, defaultGetBranch, false) if err != nil { return maskAny(err) } remoteCommit, err := git.GetLatestRemoteCommit(nil, flags.RepoUrl, defaultGetBranch) if err != nil { return maskAny(err) } if localCommit != remoteCommit { if err := git.Pull(log, "origin"); err != nil { return maskAny(err) } } else { log.Info(allGood("%s is up to date\n"), makeRel(wd, flags.Folder)) } } } else { // Get latest (local) version localVersion, err := git.GetLatestTag(nil, flags.Folder) if err != nil { return maskAny(err) } if localVersion != flags.Version { // Checkout requested version if cloned { log.Info(updating("Checking out version %s in %s.\n"), flags.Version, makeRel(wd, flags.Folder)) } else { log.Info(updating("Found version %s, wanted %s. Updating %s now.\n"), localVersion, flags.Version, makeRel(wd, flags.Folder)) } // Fetch latest changes if err := git.Fetch(log, "origin"); err != nil { return maskAny(err) } if err := git.FetchTags(log, "origin"); err != nil { return maskAny(err) } // Checkout intended version if err := git.Checkout(log, flags.Version); err != nil { return maskAny(err) } } else { log.Info(allGood("Found correct version. No changes needed in %s\n"), makeRel(wd, flags.Folder)) } // Get latest remote version remoteVersion, err := git.GetLatestRemoteTag(nil, flags.RepoUrl) if err != nil { return maskAny(err) } if remoteVersion != flags.Version { log.Warning(attention("Update available for %s: '%s' => '%s'\n"), makeRel(wd, flags.Folder), flags.Version, remoteVersion) } } return nil }