| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package artifacts |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| "os" |
| "path/filepath" |
| |
| "fuchsia.googlesource.com/host_target_testing/packages" |
| "fuchsia.googlesource.com/host_target_testing/util" |
| ) |
| |
| type Build struct { |
| ID string |
| archive *Archive |
| packages *packages.Repository |
| snapshot *SystemSnapshot |
| } |
| |
| // GetPackageRepository returns a Repository for this build. |
| func (b *Build) GetPackageRepository() (*packages.Repository, error) { |
| if b.packages != nil { |
| return b.packages, nil |
| } |
| |
| path, err := b.archive.download(b.ID, "packages.tar.gz") |
| if err != nil { |
| return nil, fmt.Errorf("failed to download packages.tar.gz: %s", err) |
| } |
| |
| packagesDir := filepath.Join(b.archive.dir, b.ID, "packages") |
| |
| if err := os.MkdirAll(packagesDir, 0755); err != nil { |
| return nil, err |
| } |
| |
| p, err := packages.NewRepositoryFromTar(packagesDir, path) |
| if err != nil { |
| return nil, err |
| } |
| b.packages = p |
| |
| return b.packages, nil |
| } |
| |
| // GetBuildArchive downloads and extracts the build-artifacts.tgz from the |
| // build id `buildId`. Returns a path to the directory of the extracted files, |
| // or an error if it fails to download or extract. |
| func (b *Build) GetBuildArchive() (string, error) { |
| path, err := b.archive.download(b.ID, "build-archive.tgz") |
| if err != nil { |
| return "", fmt.Errorf("failed to download build-archive.tar.gz: %s", err) |
| } |
| |
| buildArchiveDir := filepath.Join(b.archive.dir, b.ID, "build-archive") |
| |
| if err := os.MkdirAll(buildArchiveDir, 0755); err != nil { |
| return "", err |
| } |
| |
| if err := util.Untar(buildArchiveDir, path); err != nil { |
| return "", fmt.Errorf("failed to extract packages: %s", err) |
| } |
| |
| return buildArchiveDir, nil |
| } |
| |
| // SystemSnapshot describes the data in the system.snapshot.json file. |
| type SystemSnapshot struct { |
| BuildID int `json:"build_id"` |
| Snapshot Snapshot `json:"snapshot"` |
| } |
| |
| // Snapshot describes all the packages and blobs in the package repository. |
| type Snapshot struct { |
| Packages map[string]PackageInfo `json:"packages"` |
| Blobs map[string]BlobInfo `json:"blobs"` |
| } |
| |
| // PackageInfo describes an individual package artifacts in the repository. |
| type PackageInfo struct { |
| Files map[string]string `json:"files"` |
| Tags []string `json:"tags"` |
| } |
| |
| // BlobInfo describes all the blobs in the repository. |
| type BlobInfo struct { |
| Size int `json:"size"` |
| } |
| |
| // GetSystemSnapshot downloads and returns the system snapshot for the build. |
| func (b *Build) GetSystemSnapshot() (*SystemSnapshot, error) { |
| if b.snapshot != nil { |
| return b.snapshot, nil |
| } |
| |
| path, err := b.archive.download(b.ID, "system.snapshot.json") |
| if err != nil { |
| return nil, fmt.Errorf("failed to download system.snapshot.json: %s", err) |
| } |
| |
| f, err := os.Open(path) |
| if err != nil { |
| return nil, fmt.Errorf("failed to open %q: %s", path, err) |
| } |
| defer f.Close() |
| |
| type systemSnapshot struct { |
| BuildID int `json:"build_id"` |
| Snapshot string `json:"snapshot"` |
| } |
| |
| var s systemSnapshot |
| if err := json.NewDecoder(f).Decode(&s); err != nil { |
| return nil, fmt.Errorf("failed to parse %q: %s", path, err) |
| } |
| |
| snapshot := &SystemSnapshot{BuildID: s.BuildID} |
| if err := json.Unmarshal([]byte(s.Snapshot), &snapshot.Snapshot); err != nil { |
| return nil, fmt.Errorf("failed to parse snapshot in %q: %s", path, err) |
| } |
| |
| b.snapshot = snapshot |
| |
| return b.snapshot, nil |
| } |