Skip to content

Commit 538487d

Browse files
authored
fix: Progressbar handling (#336)
Co-authored-by: Kemal Hadimli <[email protected]>
1 parent 709cff1 commit 538487d

File tree

5 files changed

+45
-20
lines changed

5 files changed

+45
-20
lines changed

managedplugin/docker.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func isDockerImageAvailable(ctx context.Context, imageName string) (bool, error)
9898
return len(images) > 0, nil
9999
}
100100

101-
func pullDockerImage(ctx context.Context, imageName string, authToken string, teamName string, dockerHubAuth string) error {
101+
func pullDockerImage(ctx context.Context, imageName string, authToken string, teamName string, dockerHubAuth string, dops DownloaderOptions) error {
102102
// Pull the image
103103
additionalHeaders := make(map[string]string)
104104
opts := image.PullOptions{}
@@ -143,6 +143,14 @@ func pullDockerImage(ctx context.Context, imageName string, authToken string, te
143143
}
144144
defer out.Close()
145145

146+
if dops.NoProgress {
147+
_, err = io.Copy(io.Discard, out)
148+
if err != nil {
149+
return fmt.Errorf("failed to copy image pull output: %v", err)
150+
}
151+
return nil
152+
}
153+
146154
// Create a progress reader to display the download progress
147155
pr := &dockerProgressReader{
148156
decoder: json.NewDecoder(out),

managedplugin/download.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,11 @@ type HubDownloadOptions struct {
127127
PluginName string
128128
PluginVersion string
129129
}
130+
type DownloaderOptions struct {
131+
NoProgress bool
132+
}
130133

131-
func DownloadPluginFromHub(ctx context.Context, c *cloudquery_api.ClientWithResponses, ops HubDownloadOptions) error {
134+
func DownloadPluginFromHub(ctx context.Context, c *cloudquery_api.ClientWithResponses, ops HubDownloadOptions, dops DownloaderOptions) error {
132135
downloadDir := filepath.Dir(ops.LocalPath)
133136
if _, err := os.Stat(ops.LocalPath); err == nil {
134137
return nil
@@ -162,7 +165,7 @@ func DownloadPluginFromHub(ctx context.Context, c *cloudquery_api.ClientWithResp
162165
return fmt.Errorf("failed to get plugin metadata from hub: empty location from response")
163166
}
164167
pluginZipPath := ops.LocalPath + ".zip"
165-
writtenChecksum, err := downloadFile(ctx, pluginZipPath, location)
168+
writtenChecksum, err := downloadFile(ctx, pluginZipPath, location, dops)
166169
if err != nil {
167170
return fmt.Errorf("failed to download plugin: %w", err)
168171
}
@@ -236,7 +239,7 @@ func downloadPluginAssetFromHub(ctx context.Context, c *cloudquery_api.ClientWit
236239
}
237240
}
238241

239-
func DownloadPluginFromGithub(ctx context.Context, logger zerolog.Logger, localPath string, org string, name string, version string, typ PluginType) error {
242+
func DownloadPluginFromGithub(ctx context.Context, logger zerolog.Logger, localPath string, org string, name string, version string, typ PluginType, dops DownloaderOptions) error {
240243
downloadDir := filepath.Dir(localPath)
241244
pluginZipPath := localPath + ".zip"
242245

@@ -253,7 +256,7 @@ func DownloadPluginFromGithub(ctx context.Context, logger zerolog.Logger, localP
253256
return fmt.Errorf("failed to get plugin url: %w", err)
254257
}
255258
logger.Debug().Msg(fmt.Sprintf("Downloading %s", downloadURL))
256-
if _, err := downloadFile(ctx, pluginZipPath, downloadURL); err != nil {
259+
if _, err := downloadFile(ctx, pluginZipPath, downloadURL, dops); err != nil {
257260
return fmt.Errorf("failed to download plugin: %w", err)
258261
}
259262

@@ -301,20 +304,16 @@ func DownloadPluginFromGithub(ctx context.Context, logger zerolog.Logger, localP
301304
return nil
302305
}
303306

304-
func downloadFile(ctx context.Context, localPath string, downloadURL string) (string, error) {
307+
func downloadFile(ctx context.Context, localPath string, downloadURL string, dops DownloaderOptions) (string, error) {
305308
// Create the file
306309
out, err := os.Create(localPath)
307310
if err != nil {
308311
return "", fmt.Errorf("failed to create file %s: %w", localPath, err)
309312
}
310313
defer out.Close()
311314

312-
return downloadFileFromURL(ctx, out, downloadURL)
313-
}
314-
315-
func downloadFileFromURL(ctx context.Context, out *os.File, downloadURL string) (string, error) {
316315
checksum := ""
317-
err := retry.Do(func() error {
316+
err = retry.Do(func() error {
318317
checksum = ""
319318
// Get the data
320319
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
@@ -344,11 +343,17 @@ func downloadFileFromURL(ctx context.Context, out *os.File, downloadURL string)
344343
urlForLog = parsedURL.String()
345344
}
346345
fmt.Printf("Downloading %s\n", urlForLog)
347-
bar := downloadProgressBar(resp.ContentLength, "Downloading")
348346

349347
s := sha256.New()
350-
// Writer the body to file
351-
_, err = io.Copy(io.MultiWriter(out, bar, s), resp.Body)
348+
writers := []io.Writer{out, s}
349+
350+
if !dops.NoProgress {
351+
bar := downloadProgressBar(resp.ContentLength, "Downloading")
352+
writers = append(writers, bar)
353+
}
354+
355+
// Write the body to file
356+
_, err = io.Copy(io.MultiWriter(writers...), resp.Body)
352357
if err != nil {
353358
return fmt.Errorf("failed to copy body to file %s: %w", out.Name(), err)
354359
}

managedplugin/download_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestDownloadPluginFromGithubIntegration(t *testing.T) {
2929
logger := zerolog.Logger{}
3030
for _, tc := range cases {
3131
t.Run(tc.name, func(t *testing.T) {
32-
err := DownloadPluginFromGithub(context.Background(), logger, path.Join(tmp, tc.name), tc.org, tc.plugin, tc.version, tc.typ)
32+
err := DownloadPluginFromGithub(context.Background(), logger, path.Join(tmp, tc.name), tc.org, tc.plugin, tc.version, tc.typ, DownloaderOptions{})
3333
if (err != nil) != tc.wantErr {
3434
t.Errorf("DownloadPluginFromGithub() error = %v, wantErr %v", err, tc.wantErr)
3535
return
@@ -64,7 +64,9 @@ func TestDownloadPluginFromCloudQueryHub(t *testing.T) {
6464
PluginKind: tc.typ.String(),
6565
PluginName: tc.plugin,
6666
PluginVersion: tc.version,
67-
})
67+
},
68+
DownloaderOptions{},
69+
)
6870
if (err != nil) != tc.wantErr {
6971
t.Errorf("TestDownloadPluginFromCloudQueryIntegration() error = %v, wantErr %v", err, tc.wantErr)
7072
return

managedplugin/options.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func WithNoExec() Option {
2828
}
2929
}
3030

31+
func WithNoProgress() Option {
32+
return func(c *Client) {
33+
c.noProgress = true
34+
}
35+
}
36+
3137
func WithOtelEndpoint(endpoint string) Option {
3238
return func(c *Client) {
3339
c.otelEndpoint = endpoint

managedplugin/plugin.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ type Client struct {
9090
config Config
9191
noSentry bool
9292
noExec bool
93+
noProgress bool
9394
cqDockerHost string
9495
otelEndpoint string
9596
otelEndpointInsecure bool
@@ -163,6 +164,9 @@ func NewClient(ctx context.Context, typ PluginType, config Config, opts ...Optio
163164
}
164165

165166
func (c *Client) downloadPlugin(ctx context.Context, typ PluginType) error {
167+
dops := DownloaderOptions{
168+
NoProgress: c.noProgress,
169+
}
166170
switch c.config.Registry {
167171
case RegistryGrpc:
168172
return nil // GRPC plugins are not downloaded
@@ -176,12 +180,12 @@ func (c *Client) downloadPlugin(ctx context.Context, typ PluginType) error {
176180
org, name := pathSplit[0], pathSplit[1]
177181
c.LocalPath = filepath.Join(c.directory, "plugins", typ.String(), org, name, c.config.Version, "plugin")
178182
c.LocalPath = WithBinarySuffix(c.LocalPath)
179-
return DownloadPluginFromGithub(ctx, c.logger, c.LocalPath, org, name, c.config.Version, typ)
183+
return DownloadPluginFromGithub(ctx, c.logger, c.LocalPath, org, name, c.config.Version, typ, dops)
180184
case RegistryDocker:
181185
if imageAvailable, err := isDockerImageAvailable(ctx, c.config.Path); err != nil {
182186
return err
183187
} else if !imageAvailable {
184-
return pullDockerImage(ctx, c.config.Path, c.authToken, c.teamName, c.dockerAuth)
188+
return pullDockerImage(ctx, c.config.Path, c.authToken, c.teamName, c.dockerAuth, dops)
185189
}
186190
return nil
187191
case RegistryCloudQuery:
@@ -217,11 +221,11 @@ func (c *Client) downloadPlugin(ctx context.Context, typ PluginType) error {
217221
if imageAvailable, err := isDockerImageAvailable(ctx, path); err != nil {
218222
return err
219223
} else if !imageAvailable {
220-
return pullDockerImage(ctx, path, c.authToken, c.teamName, "")
224+
return pullDockerImage(ctx, path, c.authToken, c.teamName, "", dops)
221225
}
222226
return nil
223227
}
224-
return DownloadPluginFromHub(ctx, hubClient, ops)
228+
return DownloadPluginFromHub(ctx, hubClient, ops, dops)
225229
default:
226230
return fmt.Errorf("unknown registry %s", c.config.Registry.String())
227231
}

0 commit comments

Comments
 (0)