Skip to content

Commit 6395c4f

Browse files
Merge pull request #72 from rendhalver/add-ocm-container
Add ocm-container to backplane-tools
2 parents ac896b3 + 48c1a68 commit 6395c4f

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package ocmcontainer
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
9+
gogithub "github.com/google/go-github/v51/github"
10+
11+
"github.com/openshift/backplane-tools/pkg/sources/github"
12+
"github.com/openshift/backplane-tools/pkg/tools/base"
13+
"github.com/openshift/backplane-tools/pkg/utils"
14+
)
15+
16+
const (
17+
toolChecksumAssetName = "sha256sum.txt"
18+
)
19+
20+
// Tool implements the interface to manage the 'ocm-container' binary
21+
type Tool struct {
22+
base.Github
23+
}
24+
25+
func New() *Tool {
26+
t := &Tool{
27+
Github: base.Github{
28+
Default: base.NewDefault("ocm-container"),
29+
Source: github.NewSource("openshift", "ocm-container"),
30+
},
31+
}
32+
return t
33+
}
34+
35+
func (t *Tool) Install() error {
36+
// Pull latest release from GH
37+
release, err := t.Source.FetchLatestRelease()
38+
if err != nil {
39+
return err
40+
}
41+
42+
matches := github.FindAssetsForArchAndOS(release.Assets)
43+
if len(matches) != 1 {
44+
return fmt.Errorf("unexpected number of assets found matching system spec: expected 1, got %d.\nMatching assets: %v", len(matches), matches)
45+
}
46+
toolArchiveAsset := matches[0]
47+
48+
matches = github.FindAssetsContaining([]string{toolChecksumAssetName}, release.Assets)
49+
if len(matches) != 1 {
50+
return fmt.Errorf("unexpected number of checksum assets found: expected 1, got %d.\nMatching assets: %v", len(matches), matches)
51+
}
52+
checksumAsset := matches[0]
53+
54+
// Download the arch- & os-specific assets
55+
toolDir := t.ToolDir()
56+
versionedDir := filepath.Join(toolDir, release.GetTagName())
57+
err = os.MkdirAll(versionedDir, os.FileMode(0o755))
58+
if err != nil {
59+
return fmt.Errorf("failed to create version-specific directory '%s': %w", versionedDir, err)
60+
}
61+
62+
err = t.Source.DownloadReleaseAssets([]*gogithub.ReleaseAsset{checksumAsset, toolArchiveAsset}, versionedDir)
63+
if err != nil {
64+
return fmt.Errorf("failed to download one or more assets: %w", err)
65+
}
66+
67+
// Verify checksum of downloaded assets
68+
toolArchiveFilepath := filepath.Join(versionedDir, toolArchiveAsset.GetName())
69+
binarySum, err := utils.Sha256sum(toolArchiveFilepath)
70+
if err != nil {
71+
return fmt.Errorf("failed to calculate checksum for '%s': %w", toolArchiveFilepath, err)
72+
}
73+
74+
checksumFilePath := filepath.Join(versionedDir, checksumAsset.GetName())
75+
checksumLine, err := utils.GetLineInFileMatchingKey(checksumFilePath, toolArchiveAsset.GetName())
76+
if err != nil {
77+
return fmt.Errorf("failed to retrieve checksum from file '%s': %w", checksumFilePath, err)
78+
}
79+
checksumTokens := strings.Fields(checksumLine)
80+
if len(checksumTokens) != 2 {
81+
return fmt.Errorf("the checksum file '%s' is invalid: expected 2 fields, got %d", checksumFilePath, len(checksumTokens))
82+
}
83+
actual := checksumTokens[0]
84+
85+
toolExecutable := t.ExecutableName()
86+
if strings.TrimSpace(binarySum) != strings.TrimSpace(actual) {
87+
return fmt.Errorf("warning: Checksum for '%s' does not match the calculated value. Please retry installation. If issue persists, this tool can be downloaded manually at %s", toolExecutable, toolArchiveAsset.GetBrowserDownloadURL())
88+
}
89+
90+
// Untar binary bundle
91+
err = utils.Unarchive(toolArchiveFilepath, versionedDir)
92+
if err != nil {
93+
return fmt.Errorf("failed to unarchive the '%s' asset file '%s': %w", toolExecutable, toolArchiveFilepath, err)
94+
}
95+
96+
// Link as latest
97+
latestFilePath := t.SymlinkPath()
98+
err = os.Remove(latestFilePath)
99+
if err != nil && !os.IsNotExist(err) {
100+
return fmt.Errorf("failed to remove existing '%s' binary at '%s': %w", toolExecutable, base.LatestDir, err)
101+
}
102+
103+
toolBinaryFilepath := filepath.Join(versionedDir, toolExecutable)
104+
err = os.Symlink(toolBinaryFilepath, latestFilePath)
105+
if err != nil {
106+
return fmt.Errorf("failed to link new '%s' binary to '%s': %w", toolExecutable, base.LatestDir, err)
107+
}
108+
return nil
109+
}

pkg/tools/tools.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/openshift/backplane-tools/pkg/tools/oc"
1414
"github.com/openshift/backplane-tools/pkg/tools/ocm"
1515
"github.com/openshift/backplane-tools/pkg/tools/ocmaddons"
16+
"github.com/openshift/backplane-tools/pkg/tools/ocmcontainer"
1617
"github.com/openshift/backplane-tools/pkg/tools/osdctl"
1718
"github.com/openshift/backplane-tools/pkg/tools/rosa"
1819
"github.com/openshift/backplane-tools/pkg/tools/self"
@@ -98,6 +99,9 @@ func initMap() {
9899

99100
serviceloggerTool := servicelogger.New()
100101
toolMap[serviceloggerTool.Name()] = serviceloggerTool
102+
103+
ocmContainerTool := ocmcontainer.New()
104+
toolMap[ocmContainerTool.Name()] = ocmContainerTool
101105
}
102106

103107
func GetMap() map[string]Tool {

0 commit comments

Comments
 (0)