Beispiel #1
0
func updateBinaryFile(url string, checksum []byte) {
	fmt.Println("Downloading updated binary")
	httpResp, err := http.Get(url)
	if err != nil {
		glog.Errorf("Cannot download binary: %s", err)
		os.Exit(1)
	}
	defer httpResp.Body.Close()

	binary := httpResp.Body
	if httpResp.ContentLength > 0 {
		bar := pb.New64(httpResp.ContentLength).SetUnits(pb.U_BYTES)
		bar.Start()
		binary = bar.NewProxyReader(binary)
		defer func() {
			<-time.After(bar.RefreshRate)
			fmt.Println()
		}()
	}
	err = update.Apply(binary, update.Options{
		Hash:     crypto.SHA256,
		Checksum: checksum,
	})
	if err != nil {
		glog.Errorf("Cannot apply binary update: %s", err)
		err := update.RollbackError(err)
		if err != nil {
			glog.Errorf("Failed to rollback update: %s", err)
		}
		os.Exit(1)
	}
}
Beispiel #2
0
func updateBinary(v semver.Version, downloadBinary, updateLinkPrefix, downloadLinkFormat string) {
	checksum, err := downloadChecksum(v, downloadBinary, downloadLinkFormat)
	if err != nil {
		glog.Errorf("Cannot download checksum: %s", err)
		os.Exit(1)
	}
	binary, err := http.Get(fmt.Sprintf(downloadLinkFormat, v, downloadBinary))
	if err != nil {
		glog.Errorf("Cannot download binary: %s", err)
		os.Exit(1)
	}
	defer binary.Body.Close()
	err = update.Apply(binary.Body, update.Options{
		Hash:     crypto.SHA256,
		Checksum: checksum,
	})
	if err != nil {
		glog.Errorf("Cannot apply binary update: %s", err)
		os.Exit(1)
	}

	env := os.Environ()
	args := os.Args
	currentBinary, err := osext.Executable()
	if err != nil {
		glog.Errorf("Cannot find current binary to exec: %s", err)
		os.Exit(1)
	}
	err = syscall.Exec(currentBinary, args, env)
	if err != nil {
		glog.Errorf("Failed to exec updated binary: %s", err)
		os.Exit(1)
	}
}
Beispiel #3
0
// SelfUpdate updates the zmon binary. It has several limitations:
//
// - It always performs updates, unconditionally.
//
// - It downloads the entire binary, not patches.
//
// - Binaries are not compressed.
//
// - There is no forced shutdown of old binaries.
func SelfUpdate() error {
	resp, err := http.Get(updateURL())
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if err := update.Apply(resp.Body, update.Options{}); err != nil {
		return fmt.Errorf("Update failed: %v\n", err)
	}
	log.Println("Update succeeded")
	return nil
}
Beispiel #4
0
func (u *Updater) updateBinary(url string, latest *version.Version) error {
	u.Log.Info("Current version: %s is old. Going to update to: %s", u.CurrentVersion, latest)

	self, err := osext.Executable()
	if err != nil {
		return err
	}

	u.Log.Info("Going to update binary at: %s", self)

	bin, err := u.fetch(url)
	if err != nil {
		return err
	}

	u.Wait.Add(1)
	defer u.Wait.Done()

	u.Log.Info("Replacing new binary with the old one.")

	if err = update.Apply(bytes.NewBuffer(bin), update.Options{}); err != nil {
		return err
	}

	env := os.Environ()

	// TODO: os.Args[1:] should come also from the endpoint if the new binary
	// has a different flag!
	args := []string{self}
	args = append(args, os.Args[1:]...)

	// we need to call it here now too, because syscall.Exec will prevent to
	// call the defer that we've defined in the beginning.

	u.Log.Info("Updating was successfull. Replacing current process with args: %v\n=====> RESTARTING...\n\n", args)

	execErr := syscall.Exec(self, args, env)
	if execErr != nil {
		return err
	}

	return nil
}