Skip to content

Commit 67f7e57

Browse files
authored
Merge pull request #107 from chmeliik/subscription-manager-refactoring
Refactor subscription-manager usage
2 parents 22ca59f + ac466c3 commit 67f7e57

7 files changed

Lines changed: 286 additions & 131 deletions

File tree

pkg/cliwrappers/cli_executor_test.go

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cliwrappers_test
22

33
import (
4-
"bytes"
54
"fmt"
65
"os"
76
"path/filepath"
@@ -10,33 +9,11 @@ import (
109
"testing"
1110

1211
. "github.com/onsi/gomega"
13-
"github.com/sirupsen/logrus"
1412

1513
"github.com/konflux-ci/konflux-build-cli/pkg/cliwrappers"
16-
l "github.com/konflux-ci/konflux-build-cli/pkg/logger"
14+
"github.com/konflux-ci/konflux-build-cli/testutil"
1715
)
1816

19-
func captureLogOutput(fn func()) string {
20-
origOut := l.Logger.Out
21-
origFormatter := l.Logger.Formatter
22-
origLevel := l.Logger.Level
23-
24-
var buf bytes.Buffer
25-
l.Logger.SetOutput(&buf)
26-
l.Logger.SetFormatter(&logrus.TextFormatter{DisableTimestamp: true})
27-
l.Logger.SetLevel(logrus.InfoLevel)
28-
29-
defer func() {
30-
l.Logger.SetOutput(origOut)
31-
l.Logger.SetFormatter(origFormatter)
32-
l.Logger.SetLevel(origLevel)
33-
}()
34-
35-
fn()
36-
37-
return buf.String()
38-
}
39-
4017
func TestNewCliExecutor(t *testing.T) {
4118
t.Run("should create new CLI executor instance", func(t *testing.T) {
4219
g := NewWithT(t)
@@ -203,7 +180,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
203180
var stdout, stderr string
204181
var exitCode int
205182
var err error
206-
logOutput := captureLogOutput(func() {
183+
logOutput := testutil.CaptureLogOutput(func() {
207184
cmd := cliwrappers.Command("echo", "test output")
208185
cmd.LogOutput = true
209186
stdout, stderr, exitCode, err = executor.Execute(cmd)
@@ -225,7 +202,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
225202
var stdout, stderr string
226203
var exitCode int
227204
var err error
228-
logOutput := captureLogOutput(func() {
205+
logOutput := testutil.CaptureLogOutput(func() {
229206
var cmd cliwrappers.Cmd
230207
if runtime.GOOS == "windows" {
231208
cmd = cliwrappers.Command("cmd", "/c", "echo stdout output & echo stderr output 1>&2")
@@ -262,7 +239,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
262239
var stdout, stderr string
263240
var exitCode int
264241
var err error
265-
logOutput := captureLogOutput(func() {
242+
logOutput := testutil.CaptureLogOutput(func() {
266243
var cmd cliwrappers.Cmd
267244
if runtime.GOOS == "windows" {
268245
cmd = cliwrappers.Command("cmd", "/c", "echo line1 & echo line2 & echo line3")
@@ -293,7 +270,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
293270
var stdout, stderr string
294271
var exitCode int
295272
var err error
296-
logOutput := captureLogOutput(func() {
273+
logOutput := testutil.CaptureLogOutput(func() {
297274
var cmd cliwrappers.Cmd
298275
if runtime.GOOS == "windows" {
299276
cmd = cliwrappers.Command("cmd", "/c", "echo output & exit 5")
@@ -320,7 +297,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
320297
var stdout, stderr string
321298
var exitCode int
322299
var err error
323-
logOutput := captureLogOutput(func() {
300+
logOutput := testutil.CaptureLogOutput(func() {
324301
cmd := cliwrappers.Command("echo", "%s", "hello")
325302
cmd.LogOutput = true
326303
cmd.NameInLogs = "printf"
@@ -366,7 +343,7 @@ func TestCliExecutor_ExecuteWithLogOutput(t *testing.T) {
366343

367344
var stdout, stderr string
368345
var exitCode int
369-
logOutput := captureLogOutput(func() {
346+
logOutput := testutil.CaptureLogOutput(func() {
370347
cmd := cliwrappers.Command("cat", longLineFile)
371348
cmd.LogOutput = true
372349
stdout, stderr, exitCode, err = executor.Execute(cmd)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package cliwrappers
2+
3+
import (
4+
"errors"
5+
6+
l "github.com/konflux-ci/konflux-build-cli/pkg/logger"
7+
)
8+
9+
var submanLog = l.Logger.WithField("logger", "SubscriptionManagerCli")
10+
11+
type SubscriptionManagerCliInterface interface {
12+
Register(params *SubscriptionManagerRegisterParams) error
13+
Unregister()
14+
}
15+
16+
type SubscriptionManagerRegisterParams struct {
17+
Org string
18+
ActivationKey string
19+
Force bool
20+
}
21+
22+
type SubscriptionManagerCli struct {
23+
Executor CliExecutorInterface
24+
}
25+
26+
func NewSubscriptionManagerCli(executor CliExecutorInterface) (*SubscriptionManagerCli, error) {
27+
available, err := CheckCliToolAvailable("subscription-manager")
28+
if err != nil {
29+
return nil, err
30+
}
31+
if !available {
32+
return nil, errors.New("subscription-manager CLI is not available")
33+
}
34+
return &SubscriptionManagerCli{Executor: executor}, nil
35+
}
36+
37+
// Register the system with Red Hat Subscription Manager.
38+
func (sm *SubscriptionManagerCli) Register(params *SubscriptionManagerRegisterParams) error {
39+
args := []string{"register"}
40+
if params.Force {
41+
args = append(args, "--force")
42+
}
43+
args = append(args, "--org", params.Org, "--activationkey", params.ActivationKey)
44+
45+
command := func() (string, string, int, error) {
46+
return sm.Executor.Execute(Cmd{Name: "subscription-manager", Args: args})
47+
}
48+
49+
retryer := NewRetryer(command).StopIfOutputContains("unauthorized")
50+
_, stderr, _, err := retryer.Run()
51+
if err != nil {
52+
submanLog.Errorf("subscription-manager register failed: %s", err.Error())
53+
if stderr != "" {
54+
submanLog.Errorf("stderr:\n%s", stderr)
55+
}
56+
return err
57+
}
58+
return nil
59+
}
60+
61+
// Unregister the system from Red Hat Subscription Manager (best-effort).
62+
func (sm *SubscriptionManagerCli) Unregister() {
63+
_, stderr, _, err := sm.Executor.Execute(Cmd{Name: "subscription-manager", Args: []string{"unregister"}})
64+
if err != nil {
65+
submanLog.Warn("subscription-manager unregister command failed")
66+
if stderr != "" {
67+
submanLog.Warnf("stderr:\n%s", stderr)
68+
}
69+
}
70+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package cliwrappers_test
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
. "github.com/onsi/gomega"
8+
9+
"github.com/konflux-ci/konflux-build-cli/pkg/cliwrappers"
10+
"github.com/konflux-ci/konflux-build-cli/testutil"
11+
)
12+
13+
func setupSubscriptionManagerCli() (*cliwrappers.SubscriptionManagerCli, *mockExecutor) {
14+
executor := &mockExecutor{}
15+
smCli := &cliwrappers.SubscriptionManagerCli{Executor: executor}
16+
return smCli, executor
17+
}
18+
19+
func TestSubscriptionManagerCli_Register(t *testing.T) {
20+
g := NewWithT(t)
21+
ensureRetryerDisabled(t)
22+
23+
t.Run("should register with org and activation key", func(t *testing.T) {
24+
smCli, executor := setupSubscriptionManagerCli()
25+
var capturedArgs []string
26+
executor.executeFunc = func(cmd cliwrappers.Cmd) (string, string, int, error) {
27+
g.Expect(cmd.Name).To(Equal("subscription-manager"))
28+
capturedArgs = cmd.Args
29+
return "", "", 0, nil
30+
}
31+
32+
params := &cliwrappers.SubscriptionManagerRegisterParams{
33+
Org: "my-org",
34+
ActivationKey: "my-key",
35+
}
36+
37+
err := smCli.Register(params)
38+
39+
g.Expect(err).ToNot(HaveOccurred())
40+
g.Expect(capturedArgs).To(Equal([]string{
41+
"register", "--org", "my-org", "--activationkey", "my-key",
42+
}))
43+
})
44+
45+
t.Run("should include --force when Force is true", func(t *testing.T) {
46+
smCli, executor := setupSubscriptionManagerCli()
47+
var capturedArgs []string
48+
executor.executeFunc = func(cmd cliwrappers.Cmd) (string, string, int, error) {
49+
capturedArgs = cmd.Args
50+
return "", "", 0, nil
51+
}
52+
53+
params := &cliwrappers.SubscriptionManagerRegisterParams{
54+
Org: "my-org",
55+
ActivationKey: "my-key",
56+
Force: true,
57+
}
58+
59+
err := smCli.Register(params)
60+
61+
g.Expect(err).ToNot(HaveOccurred())
62+
g.Expect(capturedArgs).To(Equal([]string{
63+
"register", "--force", "--org", "my-org", "--activationkey", "my-key",
64+
}))
65+
})
66+
67+
t.Run("should return error when registration fails", func(t *testing.T) {
68+
smCli, executor := setupSubscriptionManagerCli()
69+
executor.executeFunc = func(cmd cliwrappers.Cmd) (string, string, int, error) {
70+
return "", "", 1, errors.New("command failed")
71+
}
72+
73+
params := &cliwrappers.SubscriptionManagerRegisterParams{
74+
Org: "my-org",
75+
ActivationKey: "my-key",
76+
}
77+
78+
err := smCli.Register(params)
79+
80+
g.Expect(err).To(HaveOccurred())
81+
g.Expect(err.Error()).To(Equal("command failed"))
82+
})
83+
}
84+
85+
func TestSubscriptionManagerCli_Unregister(t *testing.T) {
86+
g := NewWithT(t)
87+
88+
t.Run("should unregister", func(t *testing.T) {
89+
smCli, executor := setupSubscriptionManagerCli()
90+
var capturedArgs []string
91+
executor.executeFunc = func(cmd cliwrappers.Cmd) (string, string, int, error) {
92+
g.Expect(cmd.Name).To(Equal("subscription-manager"))
93+
capturedArgs = cmd.Args
94+
return "", "", 0, nil
95+
}
96+
97+
smCli.Unregister()
98+
99+
g.Expect(capturedArgs).To(Equal([]string{"unregister"}))
100+
})
101+
102+
t.Run("should log a warning on failure", func(t *testing.T) {
103+
smCli, executor := setupSubscriptionManagerCli()
104+
executor.executeFunc = func(cmd cliwrappers.Cmd) (string, string, int, error) {
105+
return "", "", 1, errors.New("unregister failed")
106+
}
107+
108+
logOutput := testutil.CaptureLogOutput(smCli.Unregister)
109+
g.Expect(logOutput).To(ContainSubstring("subscription-manager unregister command failed"))
110+
})
111+
}

pkg/commands/prefetch_dependencies/main.go

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package prefetch_dependencies
33
import (
44
"encoding/json"
55
"fmt"
6+
"os"
7+
"strings"
68

79
"github.com/konflux-ci/konflux-build-cli/pkg/cliwrappers"
810
"github.com/konflux-ci/konflux-build-cli/pkg/common"
@@ -15,8 +17,9 @@ import (
1517
var log = logger.Logger.WithField("logger", "PrefetchDependencies")
1618

1719
type PrefetchDependencies struct {
18-
Config *Params
19-
HermetoCli cliwrappers.HermetoCliInterface
20+
Config *Params
21+
HermetoCli cliwrappers.HermetoCliInterface
22+
SubscriptionManagerCli cliwrappers.SubscriptionManagerCliInterface
2023
}
2124

2225
func getPackageProxyConfiguration() ([]string, error) {
@@ -99,9 +102,15 @@ func (pd *PrefetchDependencies) Run() error {
99102

100103
decodedJSONInput := parseInput(pd.Config.Input)
101104
if containsRPM(decodedJSONInput) {
102-
defer unregisterSubscriptionManager()
105+
registerRHSM := pd.Config.RHSMOrg != "" && pd.Config.RHSMActivationKey != ""
106+
if registerRHSM {
107+
if err := pd.registerRHSM(); err != nil {
108+
return fmt.Errorf("failed to register with subscription-manager: %w", err)
109+
}
110+
defer pd.unregisterRHSM()
111+
}
103112

104-
modifiedInput, err := injectRPMInput(decodedJSONInput, pd.Config.RHSMOrg, pd.Config.RHSMActivationKey)
113+
modifiedInput, err := injectRPMInput(decodedJSONInput, registerRHSM)
105114
if err != nil {
106115
return fmt.Errorf("failed to inject RPM input: %w", err)
107116
}
@@ -152,3 +161,45 @@ func (pd *PrefetchDependencies) Run() error {
152161

153162
return nil
154163
}
164+
165+
func (pd *PrefetchDependencies) registerRHSM() error {
166+
if err := pd.initSubscriptionManager(); err != nil {
167+
return err
168+
}
169+
170+
org, err := os.ReadFile(pd.Config.RHSMOrg)
171+
if err != nil {
172+
return err
173+
}
174+
key, err := os.ReadFile(pd.Config.RHSMActivationKey)
175+
if err != nil {
176+
return err
177+
}
178+
179+
params := &cliwrappers.SubscriptionManagerRegisterParams{
180+
Org: strings.TrimSpace(string(org)),
181+
ActivationKey: strings.TrimSpace(string(key)),
182+
Force: true,
183+
}
184+
return pd.SubscriptionManagerCli.Register(params)
185+
}
186+
187+
func (pd *PrefetchDependencies) unregisterRHSM() {
188+
if err := pd.initSubscriptionManager(); err != nil {
189+
log.Warnf("Couldn't unregister with subscription-manager: %s", err)
190+
return
191+
}
192+
pd.SubscriptionManagerCli.Unregister()
193+
}
194+
195+
func (pd *PrefetchDependencies) initSubscriptionManager() error {
196+
if pd.SubscriptionManagerCli == nil {
197+
executor := cliwrappers.NewCliExecutor()
198+
smCli, err := cliwrappers.NewSubscriptionManagerCli(executor)
199+
if err != nil {
200+
return err
201+
}
202+
pd.SubscriptionManagerCli = smCli
203+
}
204+
return nil
205+
}

0 commit comments

Comments
 (0)