Example #1
0
func downloadFile(url string, pbar progress.Meter) (fn string, err error) {
	name := "classic"

	w, err := ioutil.TempFile("", name)
	if err != nil {
		return "", err
	}
	defer func() {
		if err != nil {
			os.Remove(w.Name())
		}
	}()
	defer w.Close()

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", fmt.Errorf("failed to download %s: %v", url, resp.StatusCode)
	}

	if pbar != nil {
		pbar.Start(name, float64(resp.ContentLength))
		mw := io.MultiWriter(w, pbar)
		_, err = io.Copy(mw, resp.Body)
		pbar.Finished()
	} else {
		_, err = io.Copy(w, resp.Body)
	}

	return w.Name(), err
}
Example #2
0
// download writes an http.Request showing a progress.Meter
func download(name string, w io.Writer, req *http.Request, pbar progress.Meter) error {
	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return &ErrDownload{Code: resp.StatusCode, URL: req.URL}
	}

	if pbar != nil {
		pbar.Start(name, float64(resp.ContentLength))
		mw := io.MultiWriter(w, pbar)
		_, err = io.Copy(mw, resp.Body)
		pbar.Finished()
	} else {
		_, err = io.Copy(w, resp.Body)
	}

	return err
}
Example #3
0
// Install installs the snap
func (s *SystemImagePart) Install(pb progress.Meter, flags InstallFlags) (name string, err error) {
	if provisioning.IsSideLoaded(bootloaderDir()) {
		return "", ErrSideLoaded
	}

	if pb != nil {
		// ensure the progress finishes when we are done
		defer func() {
			pb.Finished()
		}()
	}

	// Ensure there is always a kernel + initrd to boot with, even
	// if the update does not provide new versions.
	if s.needsBootAssetSync() {
		if pb != nil {
			pb.Notify("Syncing boot files")
		}
		err = s.partition.SyncBootloaderFiles(bootAssetFilePaths())
		if err != nil {
			return "", err
		}
	}

	// find out what config file to use, the other partition may be
	// empty so we need to fallback to the current one if it is
	configFile := systemImageClientConfig
	err = s.partition.RunWithOther(partition.RO, func(otherRoot string) (err error) {
		// XXX: Note that systemImageDownloadUpdate() requires
		// the s-i _client_ config file whereas otherIsEmpty()
		// checks the s-i _channel_ config file.
		otherConfigFile := filepath.Join(dirs.GlobalRootDir, otherRoot, systemImageClientConfig)
		if !otherIsEmpty(otherRoot) && helpers.FileExists(otherConfigFile) {
			configFile = otherConfigFile
		}

		// NOTE: we need to pass the config dir here
		configDir := filepath.Dir(configFile)
		return systemImageDownloadUpdate(configDir, pb)
	})
	if err != nil {
		return "", err
	}

	// Check that the final system state is as expected.
	if err = s.verifyUpgradeWasApplied(); err != nil {
		return "", err
	}

	// XXX: ToggleNextBoot() calls handleAssets() (but not SyncBootloader
	//      files :/) - handleAssets() may copy kernel/initramfs to the
	//      sync mounted /boot/uboot, so its very slow, tell the user
	//      at least that something is going on
	if pb != nil {
		pb.Notify("Updating boot files")
	}
	if err = s.partition.ToggleNextBoot(); err != nil {
		return "", err
	}
	return SystemImagePartName, nil
}