func step(client *http.Client, store *storage.Service, hostname string) { glog.Info("About to read package list.") // Read the old and new packages from their respective storage locations. serverList, err := packages.InstalledForServer(client, store, hostname) if err != nil { glog.Errorf("Failed to retrieve remote package list: %s", err) return } localList, err := packages.FromLocalFile(*installedPackagesFile) if err != nil { glog.Errorf("Failed to retrieve local package list: %s", err) return } // Install any new or updated packages. newPackages, installed := differences(serverList.Names, localList) glog.Infof("New: %v, Installed: %v", newPackages, installed) for _, name := range newPackages { // If just an appname appears w/o a package name then that means // that package hasn't been selected, so just skip it for now. if len(strings.Split(name, "/")) == 1 { continue } installed = append(installed, name) if err := packages.ToLocalFile(installed, *installedPackagesFile); err != nil { glog.Errorf("Failed to write local package list: %s", err) continue } if err := packages.Install(client, store, name); err != nil { glog.Errorf("Failed to install package %s: %s", name, err) // Pop last name from 'installed' then rewrite the file since the // install failed. installed = installed[:len(installed)-1] if err := packages.ToLocalFile(installed, *installedPackagesFile); err != nil { glog.Errorf("Failed to rewrite local package list after install failure for %s: %s", name, err) } continue } // The pull application is special in that it's not restarted by the // the postinstall script of the debian package, because that might kill // pullg while it was updating itself. Instead pulld will just exit when // it notices that it has been updated and count on systemd to restart it. if containsPulld(newPackages) { glog.Info("The pulld package has been updated, exiting to allow a restart.") glog.Flush() os.Exit(0) } } }
func step(client *http.Client, store *storage.Service, hostname string) { glog.Info("About to read package list.") // Read the old and new packages from their respective storage locations. serverList, err := packages.InstalledForServer(client, store, hostname) if err != nil { glog.Errorf("Failed to retrieve remote package list: %s", err) return } localList, err := packages.FromLocalFile(*installedPackagesFile) if err != nil { glog.Errorf("Failed to retrieve local package list: %s", err) return } // Install any new or updated packages. newPackages, installed := differences(serverList.Names, localList) glog.Infof("New: %v, Installed: %v", newPackages, installed) for _, name := range newPackages { // If just an appname appears w/o a package name then that means // that package hasn't been selected, so just skip it for now. if len(strings.Split(name, "/")) == 1 { continue } installed = append(installed, name) if err := packages.ToLocalFile(installed, *installedPackagesFile); err != nil { glog.Errorf("Failed to write local package list: %s", err) continue } if err := packages.Install(client, store, name); err != nil { glog.Errorf("Failed to install package %s: %s", name, err) // Pop last name from 'installed' then rewrite the file since the // install failed. installed = installed[:len(installed)-1] if err := packages.ToLocalFile(installed, *installedPackagesFile); err != nil { glog.Errorf("Failed to rewrite local package list after install failure for %s: %s", name, err) } continue } } }
// filterUnits fitlers down the units to only the interesting ones. func filterUnits(units []*systemd.UnitStatus) []*systemd.UnitStatus { units = serviceOnly(units) sort.Sort(UnitStatusSlice(units)) // Filter the list down to just services installed by push packages. installedPackages, err := packages.FromLocalFile(*installedPackagesFile) if err != nil { return units } allPackages, err := packages.AllAvailableByPackageName(store) if err != nil { return units } allServices := map[string]bool{} for _, p := range installedPackages { for _, name := range allPackages[p].Services { allServices[name] = true } } return filterService(units, allServices) }
func main() { if *hostname == "" { var err error *hostname, err = os.Hostname() if err != nil { // Never call glog before common.Init*. os.Exit(1) } } common.InitWithMetrics("pull."+*hostname, graphiteServer) glog.Infof("Running with hostname: %s", *hostname) client, err := auth.NewClient(*doOauth, *oauthCacheFile, storage.DevstorageFull_controlScope, compute.ComputeReadonlyScope) if err != nil { glog.Fatalf("Failed to create authenticated HTTP client: %s", err) } glog.Info("Got authenticated client.") store, err := storage.New(client) if err != nil { glog.Fatalf("Failed to create storage service client: %s", err) } for _ = range time.Tick(time.Second * 15) { before, err := filepath.Glob("/etc/monit/conf.d/*") if err != nil { glog.Errorf("Failed to list all monit config files: %s", err) continue } glog.Info("About to read package list.") // Read the old and new packages from their respective storage locations. serverList, err := packages.InstalledForServer(client, store, *hostname) if err != nil { glog.Errorf("Failed to retrieve remote package list: %s", err) continue } localList, err := packages.FromLocalFile(*installedPackagesFile) if err != nil { glog.Errorf("Failed to retrieve local package list: %s", err) continue } glog.Info("Comparing against currently installed packages.") // Install any new or updated packages. newPackages, installedPackages := differences(serverList.Names, localList) for _, p := range newPackages { glog.Infof("New Package:%s", p) } for _, p := range installedPackages { glog.Infof("Installed Package:%s", p) } save := false for _, name := range newPackages { // If just an appname appears w/o a packge name then that means // that package hasn't been selected, so just skip it for now. if len(strings.Split(name, "/")) == 1 { continue } if err := packages.Install(client, store, name); err != nil { glog.Errorf("Failed to install package %s: %s", name, err) continue } installedPackages = append(installedPackages, name) save = true } // Only write out the file if any new packages were installed. if !save { continue } if err := packages.ToLocalFile(installedPackages, *installedPackagesFile); err != nil { glog.Errorf("Failed to write local package list: %s", err) } after, err := filepath.Glob("/etc/monit/conf.d/*") if err != nil { glog.Errorf("Failed to list all monit config files: %s", err) continue } // Tell monit to reload if the name or number of files under /etc/monit/conf.d have changed. if !util.SSliceEqual(before, after) { cmd := exec.Command("sudo", "monit", "reload") var out bytes.Buffer cmd.Stdout = &out if err := cmd.Run(); err != nil { glog.Errorf("Failed to reload monit: %s", err) glog.Errorf("Failed to reload monit (stdout): %s", out.String()) break } } // The pull application is special and not monitored by monit to restart on // timestamp changes because that might kill pull while it was updating // itself. Instead pull will just exit when it notices that it has been // updated and count on monit to restart pull. if containsPull(newPackages) { glog.Info("The pull package has been updated, exiting to allow a restart.") os.Exit(0) } } }