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 }
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 }