Skip to content

Commit 984bc74

Browse files
authored
Merge pull request #1408 from dhiltgen/fix_panic
[18.09] Fix panic in display only case for license
2 parents 3e1a0bd + 9293264 commit 984bc74

File tree

5 files changed

+106
-23
lines changed

5 files changed

+106
-23
lines changed

cli/command/engine/activate.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,21 @@ import (
1616
)
1717

1818
type activateOptions struct {
19-
licenseFile string
20-
version string
21-
registryPrefix string
22-
format string
23-
image string
24-
quiet bool
25-
displayOnly bool
26-
sockPath string
19+
licenseFile string
20+
version string
21+
registryPrefix string
22+
format string
23+
image string
24+
quiet bool
25+
displayOnly bool
26+
sockPath string
27+
licenseLoginFunc func(ctx context.Context, authConfig *types.AuthConfig) (licenseutils.HubUser, error)
2728
}
2829

2930
// newActivateCommand creates a new `docker engine activate` command
3031
func newActivateCommand(dockerCli command.Cli) *cobra.Command {
3132
var options activateOptions
33+
options.licenseLoginFunc = licenseutils.Login
3234

3335
cmd := &cobra.Command{
3436
Use: "activate [OPTIONS]",
@@ -60,7 +62,7 @@ https://hub.docker.com/ then specify the file with the '--license' flag.
6062
flags.StringVar(&options.registryPrefix, "registry-prefix", clitypes.RegistryPrefix, "Override the default location where engine images are pulled")
6163
flags.StringVar(&options.image, "engine-image", "", "Specify engine image")
6264
flags.StringVar(&options.format, "format", "", "Pretty-print licenses using a Go template")
63-
flags.BoolVar(&options.displayOnly, "display-only", false, "only display the available licenses and exit")
65+
flags.BoolVar(&options.displayOnly, "display-only", false, "only display license information and exit")
6466
flags.BoolVar(&options.quiet, "quiet", false, "Only display available licenses by ID")
6567
flags.StringVar(&options.sockPath, "containerd", "", "override default location of containerd endpoint")
6668

@@ -90,6 +92,9 @@ func runActivate(cli command.Cli, options activateOptions) error {
9092
if license, err = getLicenses(ctx, authConfig, cli, options); err != nil {
9193
return err
9294
}
95+
if options.displayOnly {
96+
return nil
97+
}
9398
} else {
9499
if license, err = licenseutils.LoadLocalIssuedLicense(ctx, options.licenseFile); err != nil {
95100
return err
@@ -136,7 +141,7 @@ Restart docker with 'systemctl restart docker' to complete the activation.`)
136141
}
137142

138143
func getLicenses(ctx context.Context, authConfig *types.AuthConfig, cli command.Cli, options activateOptions) (*model.IssuedLicense, error) {
139-
user, err := licenseutils.Login(ctx, authConfig)
144+
user, err := options.licenseLoginFunc(ctx, authConfig)
140145
if err != nil {
141146
return nil, err
142147
}

cli/command/engine/activate_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package engine
22

33
import (
4+
"context"
45
"fmt"
56
"testing"
7+
"time"
68

9+
"github.com/docker/cli/internal/licenseutils"
710
"github.com/docker/cli/internal/test"
811
clitypes "github.com/docker/cli/types"
912
"github.com/docker/docker/api/types"
1013
"github.com/docker/docker/client"
14+
"github.com/docker/licensing"
15+
"github.com/docker/licensing/model"
1116
"gotest.tools/assert"
1217
"gotest.tools/fs"
1318
"gotest.tools/golden"
@@ -69,3 +74,73 @@ func TestActivateExpiredLicenseDryRun(t *testing.T) {
6974
assert.NilError(t, err)
7075
golden.Assert(t, c.OutBuffer().String(), "expired-license-display-only.golden")
7176
}
77+
78+
type mockLicenseClient struct{}
79+
80+
func (c mockLicenseClient) LoginViaAuth(ctx context.Context, username, password string) (authToken string, err error) {
81+
return "", fmt.Errorf("not implemented")
82+
}
83+
84+
func (c mockLicenseClient) GetHubUserOrgs(ctx context.Context, authToken string) (orgs []model.Org, err error) {
85+
return nil, fmt.Errorf("not implemented")
86+
}
87+
func (c mockLicenseClient) GetHubUserByName(ctx context.Context, username string) (user *model.User, err error) {
88+
return nil, fmt.Errorf("not implemented")
89+
}
90+
func (c mockLicenseClient) VerifyLicense(ctx context.Context, license model.IssuedLicense) (res *model.CheckResponse, err error) {
91+
return nil, fmt.Errorf("not implemented")
92+
}
93+
func (c mockLicenseClient) GenerateNewTrialSubscription(ctx context.Context, authToken, dockerID, email string) (subscriptionID string, err error) {
94+
return "", fmt.Errorf("not implemented")
95+
}
96+
func (c mockLicenseClient) ListSubscriptions(ctx context.Context, authToken, dockerID string) (response []*model.Subscription, err error) {
97+
expires := time.Date(2010, time.January, 1, 0, 0, 0, 0, time.UTC)
98+
return []*model.Subscription{
99+
{
100+
State: "active",
101+
Expires: &expires,
102+
},
103+
}, nil
104+
}
105+
func (c mockLicenseClient) ListSubscriptionsDetails(ctx context.Context, authToken, dockerID string) (response []*model.SubscriptionDetail, err error) {
106+
return nil, fmt.Errorf("not implemented")
107+
}
108+
func (c mockLicenseClient) DownloadLicenseFromHub(ctx context.Context, authToken, subscriptionID string) (license *model.IssuedLicense, err error) {
109+
return nil, fmt.Errorf("not implemented")
110+
}
111+
func (c mockLicenseClient) ParseLicense(license []byte) (parsedLicense *model.IssuedLicense, err error) {
112+
return nil, fmt.Errorf("not implemented")
113+
}
114+
func (c mockLicenseClient) StoreLicense(ctx context.Context, dclnt licensing.WrappedDockerClient, licenses *model.IssuedLicense, localRootDir string) error {
115+
return fmt.Errorf("not implemented")
116+
}
117+
func (c mockLicenseClient) LoadLocalLicense(ctx context.Context, dclnt licensing.WrappedDockerClient) (*model.Subscription, error) {
118+
return nil, fmt.Errorf("not implemented")
119+
}
120+
func (c mockLicenseClient) SummarizeLicense(res *model.CheckResponse, keyID string) *model.Subscription {
121+
return nil
122+
}
123+
func TestActivateDisplayOnlyHub(t *testing.T) {
124+
isRoot = func() bool { return true }
125+
c := test.NewFakeCli(&verClient{client.Client{}, types.Version{}, nil, types.Info{}, nil})
126+
c.SetContainerizedEngineClient(
127+
func(string) (clitypes.ContainerizedClient, error) {
128+
return &fakeContainerizedEngineClient{}, nil
129+
},
130+
)
131+
132+
hubUser := licenseutils.HubUser{
133+
Client: mockLicenseClient{},
134+
}
135+
options := activateOptions{
136+
licenseLoginFunc: func(ctx context.Context, authConfig *types.AuthConfig) (licenseutils.HubUser, error) {
137+
return hubUser, nil
138+
},
139+
displayOnly: true,
140+
}
141+
c.OutBuffer().Reset()
142+
err := runActivate(c, options)
143+
144+
assert.NilError(t, err)
145+
golden.Assert(t, c.OutBuffer().String(), "expired-hub-license-display-only.golden")
146+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Looking for existing licenses for ...
2+
NUM OWNER PRODUCT ID EXPIRES PRICING COMPONENTS
3+
0 2010-01-01 00:00:00 +0000 UTC

internal/licenseutils/utils.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
// HubUser wraps a licensing client and holds key information
2121
// for a user to avoid multiple lookups
2222
type HubUser struct {
23-
client licensing.Client
23+
Client licensing.Client
2424
token string
2525
User model.User
2626
Orgs []model.Org
@@ -73,7 +73,7 @@ func Login(ctx context.Context, authConfig *types.AuthConfig) (HubUser, error) {
7373
return HubUser{}, err
7474
}
7575
return HubUser{
76-
client: lclient,
76+
Client: lclient,
7777
token: token,
7878
User: *user,
7979
Orgs: orgs,
@@ -83,12 +83,12 @@ func Login(ctx context.Context, authConfig *types.AuthConfig) (HubUser, error) {
8383

8484
// GetAvailableLicenses finds all available licenses for a given account and their orgs
8585
func (u HubUser) GetAvailableLicenses(ctx context.Context) ([]LicenseDisplay, error) {
86-
subs, err := u.client.ListSubscriptions(ctx, u.token, u.User.ID)
86+
subs, err := u.Client.ListSubscriptions(ctx, u.token, u.User.ID)
8787
if err != nil {
8888
return nil, err
8989
}
9090
for _, org := range u.Orgs {
91-
orgSub, err := u.client.ListSubscriptions(ctx, u.token, org.ID)
91+
orgSub, err := u.Client.ListSubscriptions(ctx, u.token, org.ID)
9292
if err != nil {
9393
return nil, err
9494
}
@@ -134,16 +134,16 @@ func (u HubUser) GetAvailableLicenses(ctx context.Context) ([]LicenseDisplay, er
134134

135135
// GenerateTrialLicense will generate a new trial license for the specified user or org
136136
func (u HubUser) GenerateTrialLicense(ctx context.Context, targetID string) (*model.IssuedLicense, error) {
137-
subID, err := u.client.GenerateNewTrialSubscription(ctx, u.token, targetID, u.User.Email)
137+
subID, err := u.Client.GenerateNewTrialSubscription(ctx, u.token, targetID, u.User.Email)
138138
if err != nil {
139139
return nil, err
140140
}
141-
return u.client.DownloadLicenseFromHub(ctx, u.token, subID)
141+
return u.Client.DownloadLicenseFromHub(ctx, u.token, subID)
142142
}
143143

144144
// GetIssuedLicense will download a license by ID
145145
func (u HubUser) GetIssuedLicense(ctx context.Context, ID string) (*model.IssuedLicense, error) {
146-
return u.client.DownloadLicenseFromHub(ctx, u.token, ID)
146+
return u.Client.DownloadLicenseFromHub(ctx, u.token, ID)
147147
}
148148

149149
// LoadLocalIssuedLicense will load a local license file

internal/licenseutils/utils_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestGetOrgByID(t *testing.T) {
4343
func TestGetAvailableLicensesListFail(t *testing.T) {
4444
ctx := context.Background()
4545
user := HubUser{
46-
client: &fakeLicensingClient{
46+
Client: &fakeLicensingClient{
4747
listSubscriptionsFunc: func(ctx context.Context, authToken, dockerID string) (response []*model.Subscription, err error) {
4848
return nil, fmt.Errorf("list subscriptions error")
4949
},
@@ -59,7 +59,7 @@ func TestGetAvailableLicensesOrgFail(t *testing.T) {
5959
Orgs: []model.Org{
6060
{ID: "orgid"},
6161
},
62-
client: &fakeLicensingClient{
62+
Client: &fakeLicensingClient{
6363
listSubscriptionsFunc: func(ctx context.Context, authToken, dockerID string) (response []*model.Subscription, err error) {
6464
if dockerID == "orgid" {
6565
return nil, fmt.Errorf("list subscriptions org error")
@@ -86,7 +86,7 @@ func TestGetAvailableLicensesHappy(t *testing.T) {
8686
Orgname: "orgname",
8787
},
8888
},
89-
client: &fakeLicensingClient{
89+
Client: &fakeLicensingClient{
9090
listSubscriptionsFunc: func(ctx context.Context, authToken, dockerID string) (response []*model.Subscription, err error) {
9191
if dockerID == "orgid" {
9292
return []*model.Subscription{
@@ -146,7 +146,7 @@ func TestGetAvailableLicensesHappy(t *testing.T) {
146146
func TestGenerateTrialFail(t *testing.T) {
147147
ctx := context.Background()
148148
user := HubUser{
149-
client: &fakeLicensingClient{
149+
Client: &fakeLicensingClient{
150150
generateNewTrialSubscriptionFunc: func(ctx context.Context, authToken, dockerID, email string) (subscriptionID string, err error) {
151151
return "", fmt.Errorf("generate trial failure")
152152
},
@@ -160,7 +160,7 @@ func TestGenerateTrialFail(t *testing.T) {
160160
func TestGenerateTrialHappy(t *testing.T) {
161161
ctx := context.Background()
162162
user := HubUser{
163-
client: &fakeLicensingClient{
163+
Client: &fakeLicensingClient{
164164
generateNewTrialSubscriptionFunc: func(ctx context.Context, authToken, dockerID, email string) (subscriptionID string, err error) {
165165
return "subid", nil
166166
},
@@ -174,7 +174,7 @@ func TestGenerateTrialHappy(t *testing.T) {
174174
func TestGetIssuedLicense(t *testing.T) {
175175
ctx := context.Background()
176176
user := HubUser{
177-
client: &fakeLicensingClient{},
177+
Client: &fakeLicensingClient{},
178178
}
179179
id := "idgoeshere"
180180
_, err := user.GetIssuedLicense(ctx, id)

0 commit comments

Comments
 (0)