Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // pulld is an application that monitors and pulls down new Debian packages and installs them. | |
| 2 // | |
| 3 // It presumes each package is monitored via systemd and not monit, so there's | |
| 4 // no monitoring of monit config files is done. | |
| 5 // | |
| 6 // Note that it is safe for pulld to install pulld since the list of installed | |
| 7 // packages is written out before 'dpkg -i' is called. | |
| 8 package main | |
| 9 | |
| 10 import ( | |
| 11 "flag" | |
| 12 "os" | |
| 13 "strings" | |
| 14 "time" | |
| 15 | |
| 16 "code.google.com/p/google-api-go-client/storage/v1" | |
| 17 "github.com/skia-dev/glog" | |
| 18 "go.skia.org/infra/go/common" | |
| 19 "go.skia.org/infra/go/util" | |
| 20 "go.skia.org/infra/push/go/gsauth" | |
| 21 "go.skia.org/infra/push/go/packages" | |
| 22 ) | |
| 23 | |
| 24 var ( | |
| 25 graphiteServer = flag.String("graphite_server", "skia-monitoring: 2003", "Where is Graphite metrics ingestion server running.") | |
| 26 doOauth = flag.Bool("oauth", true, "Run through the OAuth 2.0 flow on startup, otherwise use a GCE service account.") | |
| 27 oauthCacheFile = flag.String("oauth_cache_file", "google_storage_ token.data", "Path to the file where to cache cache the oauth credentials.") | |
| 28 installedPackagesFile = flag.String("installed_packages_file", "installe d_packages.json", "Path to the file where to cache the list of installed debs.") | |
| 29 ) | |
| 30 | |
| 31 // differences returns all strings that appear in server but not local. | |
| 32 func differences(server, local []string) ([]string, []string) { | |
| 33 newPackages := []string{} | |
| 34 installedPackages := []string{} | |
| 35 for _, s := range server { | |
| 36 if util.In(s, local) { | |
| 37 installedPackages = append(installedPackages, s) | |
| 38 } else { | |
| 39 newPackages = append(newPackages, s) | |
| 40 } | |
| 41 } | |
| 42 return newPackages, installedPackages | |
| 43 } | |
| 44 | |
| 45 func main() { | |
| 46 hostname, err := os.Hostname() | |
| 47 if err != nil { | |
| 48 // Never call glog before common.Init*. | |
| 49 os.Exit(1) | |
| 50 } | |
| 51 common.InitWithMetrics("pulld."+hostname, graphiteServer) | |
| 52 glog.Infof("Running with hostname: %s", hostname) | |
| 53 | |
| 54 client, err := gsauth.NewClient(*doOauth, *oauthCacheFile) | |
| 55 if err != nil { | |
| 56 glog.Fatalf("Failed to create authenticated HTTP client: %s", er r) | |
| 57 } | |
| 58 glog.Info("Got authenticated client.") | |
| 59 | |
| 60 store, err := storage.New(client) | |
| 61 if err != nil { | |
| 62 glog.Fatalf("Failed to create storage service client: %s", err) | |
| 63 } | |
| 64 | |
| 65 for _ = range time.Tick(time.Second * 15) { | |
| 66 glog.Info("About to read package list.") | |
| 67 // Read the old and new packages from their respective storage l ocations. | |
| 68 serverList, err := packages.InstalledForServer(client, store, ho stname) | |
| 69 if err != nil { | |
| 70 glog.Errorf("Failed to retrieve remote package list: %s" , err) | |
| 71 continue | |
| 72 } | |
| 73 localList, err := packages.FromLocalFile(*installedPackagesFile) | |
| 74 if err != nil { | |
| 75 glog.Errorf("Failed to retrieve local package list: %s", err) | |
| 76 continue | |
| 77 } | |
| 78 | |
| 79 // Install any new or updated packages. | |
| 80 newPackages, installed := differences(serverList.Names, localLis t) | |
| 81 glog.Infof("New: %v, Installed: %v", newPackages, installed) | |
| 82 | |
| 83 for _, name := range newPackages { | |
| 84 // If just an appname appears w/o a packge name then tha t means | |
|
rmistry
2015/05/18 20:42:44
"package"
jcgregorio
2015/05/19 19:19:04
Done.
| |
| 85 // that package hasn't been selected, so just skip it fo r now. | |
| 86 if len(strings.Split(name, "/")) == 1 { | |
| 87 continue | |
| 88 } | |
| 89 installed = append(installed, name) | |
| 90 if err := packages.ToLocalFile(installed, *installedPack agesFile); err != nil { | |
| 91 glog.Errorf("Failed to write local package list: %s", err) | |
| 92 continue | |
| 93 } | |
| 94 if err := packages.Install(client, store, name); err != nil { | |
| 95 glog.Errorf("Failed to install package %s: %s", name, err) | |
| 96 // Pop last name from 'installed' then rewrite t he file since the | |
| 97 // install failed. | |
| 98 installed = installed[:len(installed)-1] | |
| 99 if err := packages.ToLocalFile(installed, *insta lledPackagesFile); err != nil { | |
| 100 glog.Errorf("Failed to rewrite local pac kage list after install failure for %s: %s", name, err) | |
| 101 } | |
| 102 continue | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 } | |
| OLD | NEW |