Example #1
0
func downloadManifest(artifact *ct.Artifact) error {
	verifier, err := verify.NewVerifier(artifact.Hashes, artifact.Size)
	if err != nil {
		return err
	}

	res, err := hh.RetryClient.Get(artifact.URI)
	if err != nil {
		return err
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected HTTP status: %s", res.Status)
	}

	r := verifier.Reader(res.Body)
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}

	if err := verifier.Verify(); err != nil {
		return err
	}

	artifact.RawManifest = data
	return nil
}
Example #2
0
func (l *LibcontainerBackend) mountSquashfs(m *host.Mountspec) (string, error) {
	// use the layerLoader to ensure only one caller downloads any
	// given layer ID
	path, err := l.layerLoader.Do(m.ID, func() (interface{}, error) {
		if vol := l.VolManager.GetVolume(m.ID); vol != nil {
			return vol.Location(), nil
		}

		if m.URL == "" {
			return "", fmt.Errorf("error getting squashfs layer %s: missing URL", m.ID)
		}

		verifier, err := verify.NewVerifier(m.Hashes, m.Size)
		if err != nil {
			return "", fmt.Errorf("error getting squashfs layer %s: %s", m.ID, err)
		}

		u, err := url.Parse(m.URL)
		if err != nil {
			return "", err
		}

		var layer io.ReadCloser
		switch u.Scheme {
		case "file":
			f, err := os.Open(u.Path)
			if err != nil {
				return "", fmt.Errorf("error getting squashfs layer %s: %s", m.URL, err)
			}
			layer = f
		case "http", "https":
			res, err := l.httpClient.Get(m.URL)
			if err != nil {
				return "", fmt.Errorf("error getting squashfs layer from %s: %s", m.URL, err)
			}
			if res.StatusCode != http.StatusOK {
				return "", fmt.Errorf("error getting squashfs layer from %s: unexpected HTTP status %s", m.URL, res.Status)
			}
			layer = res.Body
		default:
			return "", fmt.Errorf("unknown layer URI scheme: %s", u.Scheme)
		}
		defer layer.Close()

		// write the layer to a temp file and verify it has the
		// expected hashes
		tmp, err := ioutil.TempFile("", "flynn-layer-")
		if err != nil {
			return "", err
		}
		defer os.Remove(tmp.Name())
		defer tmp.Close()
		if _, err := io.Copy(tmp, verifier.Reader(layer)); err != nil {
			return "", fmt.Errorf("error getting squashfs layer from %s: %s", m.URL, err)
		}
		if err := verifier.Verify(); err != nil {
			return "", fmt.Errorf("error getting squashfs layer from %s: %s", m.URL, err)
		}

		if _, err := tmp.Seek(0, os.SEEK_SET); err != nil {
			return "", fmt.Errorf("error seeking squashfs layer temp file: %s", err)
		}
		vol, err := l.VolManager.ImportFilesystem("default", &volume.Filesystem{
			ID:         m.ID,
			Data:       tmp,
			Size:       m.Size,
			Type:       volume.VolumeTypeSquashfs,
			MountFlags: syscall.MS_RDONLY,
			Meta:       m.Meta,
		})
		if err != nil {
			return "", fmt.Errorf("error importing squashfs layer: %s", err)
		}

		return vol.Location(), nil
	})
	if err != nil {
		return "", err
	}
	return path.(string), nil
}