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 package name then th
at means |
| 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 |