func cp(src, dst string) error { if strings.HasSuffix(dst, "/") && !strings.HasSuffix(src, "/") { n := src if strings.Contains(n, "/") { n = n[strings.LastIndex(n, "/")+1:] } dst = filepath.Join(dst, n) } snl, err := storage.ParseLocation(src) if err != nil { return err } dnl, err := storage.ParseLocation(dst) if err != nil { return err } source, err := storage.Get(snl) if err != nil { return err } defer source.Close() err = storage.Put(dnl, source) if err != nil { return err } return nil }
func rm(src string) error { loc, err := storage.ParseLocation(src) if err != nil { return err } return storage.Delete(loc) }
func watch(src string) error { loc, err := storage.ParseLocation(src) if err != nil { return err } watcher, err := sync.Watch(loc) if err != nil { return err } defer watcher.Stop() // TODO: a better approach here would be to use a channel to retry on, // then if you jacked up the config, it would pick up the change // in the middle of all the retries. As it stands now it would take a // minute to fix itself. eb := backoff.NewExponentialBackOff() eb.MaxElapsedTime = time.Minute for range watcher.C { log.Println("[watch] new version") backoff.Retry(func() error { err := apply(src) if err != nil { log.Printf("[watch] error installing: %v\n", err) } return err }, eb) } return nil }
func installGo() error { cmd := exec.Command(filepath.Join(goroot, "bin", "go"), "version") cmd.Env = []string{"GOROOT=" + goroot} goVersion, _ := cmd.CombinedOutput() if strings.TrimSpace(string(goVersion)) == "go version go1.5.1 linux/amd64" { return nil } log.Println("installing go") loc, err := storage.ParseLocation("https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz") if err != nil { return err } rc, err := storage.Get(loc) if err != nil { return err } defer rc.Close() err = archive.ExtractReader("/tmp", rc, "go.tar.gz") if err != nil { return err } dst := goroot os.RemoveAll(dst) os.Rename("/tmp/go", dst) return nil }
func installAppEngine() error { appEngineVersion, _ := exec.Command(filepath.Join(home, "dist", "go_appengine", "goapp"), "version").CombinedOutput() if strings.TrimSpace(string(appEngineVersion)) == "go version go1.4.2 (appengine-1.9.27) linux/amd64" { return nil } log.Println("installing app engine") url, err := storage.ParseLocation("https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.27.zip") if err != nil { return err } rc, err := storage.Get(url) if err != nil { return err } defer rc.Close() err = archive.ExtractReader("/tmp", rc, "appengine.zip") if err != nil { return err } dst := filepath.Join(home, "dist", "go_appengine") os.RemoveAll(dst) os.Rename("/tmp/go_appengine", dst) return nil }
func ls(dir string) error { loc, err := storage.ParseLocation(dir) if err != nil { return err } names, err := storage.List(loc) if err != nil { return err } for _, name := range names { fmt.Println(name) } return nil }
func installFish() error { fishVersion, _ := exec.Command(filepath.Join(home, "bin", "fish"), "--version").CombinedOutput() if strings.TrimSpace(string(fishVersion)) == "fish, version 2.2.0" { return nil } log.Println("installing fish") url, err := storage.ParseLocation("http://fishshell.com/files/2.2.0/fish-2.2.0.tar.gz") if err != nil { return err } rc, err := storage.Get(url) if err != nil { return err } defer rc.Close() err = archive.ExtractReader("/tmp", rc, "fish.tar.gz") if err != nil { return err } dst := filepath.Join(home, "dist", "fish") os.RemoveAll(dst) os.Rename("/tmp/fish-2.2.0", dst) cmd := exec.Command("bash", "-c", "./configure --prefix=$HOME && make && make install") cmd.Dir = dst cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return err } log.Println("setting fish as default shell") cmd = exec.Command("bash", "-c", "sudo chsh -s "+filepath.Join(home, "bin", "fish")+" vagrant") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return err } return nil }
func download(src, name, dst string) error { url, err := storage.ParseLocation(src) if err != nil { return err } rc, err := storage.Get(url) if err != nil { return err } defer rc.Close() err = archive.ExtractReader(dst, rc, name) if err != nil { return err } return nil }
func installRedis() error { redisVersion, _ := exec.Command(filepath.Join(home, "bin", "redis-server"), "--version").CombinedOutput() if strings.TrimSpace(string(redisVersion)) == "Redis server v=3.0.4 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=bbb5a106838ae534" { return nil } log.Println("installing redis") url, err := storage.ParseLocation("http://download.redis.io/releases/redis-3.0.4.tar.gz") if err != nil { return err } rc, err := storage.Get(url) if err != nil { return err } defer rc.Close() err = archive.ExtractReader("/tmp", rc, "redis.tar.gz") if err != nil { return err } dst := filepath.Join(home, "dist", "redis") os.RemoveAll(dst) os.Rename("/tmp/redis-3.0.4", dst) cmd := exec.Command("bash", "-c", "make && env PREFIX=$HOME make install") cmd.Dir = dst cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return err } return nil }
func apply(src string) error { pl := NewPortLock(49001) pl.Lock() defer pl.Unlock() loc, err := storage.ParseLocation(src) if err != nil { return err } rc, err := storage.Get(loc) if err != nil { return err } defer rc.Close() cfg, err := ParseConfig(rc) if err != nil { return err } prevCfg := ReadConfig() err = applySources(prevCfg, cfg) if err != nil { return fmt.Errorf("error processing sources: %v", err) } err = applyApplications(prevCfg, cfg) if err != nil { return fmt.Errorf("error processing applications: %v", err) } SaveConfig(cfg) return nil }