Skip to content

Commit 619f4c1

Browse files
author
Antonio Salinas
committed
fix: require lookaside-uri or component
1 parent 81c7916 commit 619f4c1

File tree

5 files changed

+173
-153
lines changed

5 files changed

+173
-153
lines changed

docs/user/reference/cli/azldev_advanced_download-sources.md

Lines changed: 20 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/app/azldev/cmds/advanced/advanced.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ output but fully supported.`,
2424
}
2525

2626
app.AddTopLevelCommand(cmd)
27-
downloadSourcesOnAppInit(app, cmd)
27+
downloadsources.OnAppInit(app, cmd)
2828
mcpOnAppInit(app, cmd)
2929
mockOnAppInit(app, cmd)
3030
wgetOnAppInit(app, cmd)
3131
}
32-
33-
func downloadSourcesOnAppInit(app *azldev.App, parentCmd *cobra.Command) {
34-
downloadsources.OnAppInit(app, parentCmd)
35-
}

internal/app/azldev/cmds/downloadsources/downloadsources.go

Lines changed: 99 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import (
1010
"path/filepath"
1111

1212
"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev"
13+
"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/components"
14+
"github.com/microsoft/azure-linux-dev-tools/internal/providers/sourceproviders"
1315
"github.com/microsoft/azure-linux-dev-tools/internal/providers/sourceproviders/fedorasource"
1416
"github.com/microsoft/azure-linux-dev-tools/internal/utils/downloader"
15-
"github.com/microsoft/azure-linux-dev-tools/internal/utils/fileutils"
1617
"github.com/microsoft/azure-linux-dev-tools/internal/utils/retry"
1718
"github.com/spf13/cobra"
1819
)
@@ -22,7 +23,7 @@ type DownloadSourcesOptions struct {
2223
Directory string
2324
OutputDir string
2425
LookasideBaseURIs []string
25-
PackageName string
26+
ComponentName string
2627
LookasideDownloader fedorasource.FedoraSourceDownloader
2728
}
2829

@@ -45,28 +46,29 @@ The command reads the 'sources' file, resolves the lookaside cache URI from
4546
the distro configuration, and downloads each listed file into the directory.
4647
Files that already exist in the directory are skipped.
4748
48-
The package name is derived from the directory name and can be overridden
49-
with --package-name. The directory must contain a 'sources' file.
49+
Either --component or --lookaside-uri must be provided:
5050
51-
This command can run without project configuration by providing
52-
--lookaside-uri explicitly.`,
53-
Example: ` # Download sources in the current directory (package name derived from dir name)
54-
azldev advanced download-sources
51+
--component (-p) Uses the component's distro configuration to resolve
52+
the lookaside URI and package name.
53+
--lookaside-uri Provides the URI explicitly (no project config needed).
54+
Package name is derived from the directory name.`,
55+
Example: ` # Download sources for a component (uses component's distro config)
56+
azldev advanced download-sources -p curl
5557
56-
# Download sources from a specific directory
57-
azldev advanced download-sources -d ./path/to/curl/
58+
# Download sources using explicit lookaside URI (no config needed)
59+
azldev advanced download-sources \
60+
--lookaside-uri 'https://example.com/$pkg/$filename/$hashtype/$hash/$filename'
5861
59-
# Download sources to a different output directory
60-
azldev advanced download-sources -o /tmp/output
62+
# Specify a different source directory
63+
azldev advanced download-sources -p curl -d ./path/to/sources/
6164
62-
# Download sources using explicit lookaside URIs
63-
azldev advanced download-sources \\
64-
--lookaside-uri https://example.com/cache1 \\
65-
--lookaside-uri https://example.com/cache2
65+
# Download to a different output directory
66+
azldev advanced download-sources -p curl -o /tmp/output
6667
67-
# Download sources without project configuration
68-
azldev advanced download-sources \\
69-
--lookaside-uri https://example.com/cache -d ./curl`,
68+
# Try multiple lookaside URIs in order
69+
azldev advanced download-sources \
70+
--lookaside-uri 'https://cache1.example.com/$pkg/$filename/$hashtype/$hash/$filename' \
71+
--lookaside-uri 'https://cache2.example.com/$pkg/$filename/$hashtype/$hash/$filename'`,
7072
RunE: azldev.RunFuncWithoutRequiredConfig(func(env *azldev.Env) (interface{}, error) {
7173
if options.Directory == "" {
7274
options.Directory = "."
@@ -84,11 +86,15 @@ This command can run without project configuration by providing
8486
"output directory for downloaded files (defaults to source directory)")
8587
_ = cmd.MarkFlagDirname("output-dir")
8688

89+
cmd.Flags().StringVarP(&options.ComponentName, "component", "p", "",
90+
"component name to resolve distro and package name from")
91+
8792
cmd.Flags().StringArrayVar(&options.LookasideBaseURIs, "lookaside-uri", nil,
88-
"explicit lookaside base URI(s) to use instead of the distro configuration (can be specified multiple times)")
93+
"explicit lookaside base URI(s) to try in order, first success wins "+
94+
"(can be specified multiple times)")
8995

90-
cmd.Flags().StringVar(&options.PackageName, "package-name", "",
91-
"explicit package name to use instead of deriving from the directory name")
96+
cmd.MarkFlagsOneRequired("component", "lookaside-uri")
97+
cmd.MarkFlagsMutuallyExclusive("component", "lookaside-uri")
9298

9399
return cmd
94100
}
@@ -117,45 +123,40 @@ func DownloadSources(env *azldev.Env, options *DownloadSourcesOptions) error {
117123
extractOpts = append(extractOpts, fedorasource.WithOutputDir(options.OutputDir))
118124
}
119125

120-
// Verify the 'sources' file exists before attempting downloads.
121-
sourcesPath := filepath.Join(options.Directory, "sources")
122-
123-
sourcesExists, err := fileutils.Exists(env.FS(), sourcesPath)
124-
if err != nil {
125-
return fmt.Errorf("failed to check for sources file at %#q:\n%w", sourcesPath, err)
126-
}
127-
128-
if !sourcesExists {
129-
return fmt.Errorf("no 'sources' file found in %#q", options.Directory)
130-
}
131-
132126
// Try each lookaside base URI until one succeeds.
133127
var downloadErr error
134128

135129
for _, uri := range lookasideBaseURIs {
136130
slog.Info("Trying lookaside base URI", "uri", uri)
137131

138-
downloadErr = lookasideDownloader.ExtractSourcesFromRepo(
132+
uriErr := lookasideDownloader.ExtractSourcesFromRepo(
139133
env, options.Directory, packageName, uri, nil, extractOpts...,
140134
)
141-
if downloadErr == nil {
135+
if uriErr == nil {
142136
break
143137
}
144138

145139
slog.Warn("Failed to download sources from lookaside URI",
146-
"uri", uri, "error", downloadErr)
140+
"uri", uri, "error", uriErr)
141+
142+
downloadErr = errors.Join(downloadErr, uriErr)
147143
}
148144

149145
if downloadErr != nil {
150-
return fmt.Errorf("failed to download sources from any lookaside URI:\n%w", downloadErr)
146+
return fmt.Errorf("failed to download sources from any lookaside URI:\n%w",
147+
downloadErr)
151148
}
152149

153150
outputDir := options.Directory
154151
if options.OutputDir != "" {
155152
outputDir = options.OutputDir
156153
}
157154

158-
absOutputDir, _ := filepath.Abs(outputDir)
155+
absOutputDir, absErr := filepath.Abs(outputDir)
156+
if absErr != nil {
157+
absOutputDir = outputDir
158+
}
159+
159160
slog.Info("Sources downloaded successfully", "outputDir", absOutputDir)
160161

161162
return nil
@@ -185,72 +186,96 @@ func createLookasideDownloader(env *azldev.Env) (fedorasource.FedoraSourceDownlo
185186
}
186187

187188
// resolveDownloadParams determines the package name and lookaside URIs.
189+
// In component mode, both are resolved from the component's config.
190+
// In standalone mode, lookaside URIs come from the flag and the package name
191+
// is derived from the directory basename.
188192
func resolveDownloadParams(
189193
env *azldev.Env, options *DownloadSourcesOptions,
190194
) (packageName string, lookasideBaseURIs []string, err error) {
191-
packageName, err = resolvePackageName(options)
192-
if err != nil {
193-
return "", nil, err
195+
if len(options.LookasideBaseURIs) == 0 && options.ComponentName == "" {
196+
return "", nil, errors.New(
197+
"either --component or --lookaside-uri must be provided")
194198
}
195199

200+
// Standalone mode: --lookaside-uri provided.
196201
if len(options.LookasideBaseURIs) > 0 {
197-
return packageName, options.LookasideBaseURIs, nil
198-
}
202+
packageName, err = resolvePackageNameFromDir(options)
203+
if err != nil {
204+
return "", nil, err
205+
}
199206

200-
lookasideBaseURI, err := resolveLookasideURI(env)
201-
if err != nil {
202-
return "", nil, err
207+
return packageName, options.LookasideBaseURIs, nil
203208
}
204209

205-
return packageName, []string{lookasideBaseURI}, nil
210+
// Component mode: --component provided.
211+
return resolveFromComponent(env, options)
206212
}
207213

208-
// resolvePackageName determines the package name from the --package-name flag or directory name.
209-
func resolvePackageName(options *DownloadSourcesOptions) (string, error) {
210-
if options.PackageName != "" {
211-
return options.PackageName, nil
212-
}
213-
214+
// resolvePackageNameFromDir derives the package name from the directory basename.
215+
func resolvePackageNameFromDir(options *DownloadSourcesOptions) (string, error) {
214216
absDir, err := filepath.Abs(options.Directory)
215217
if err != nil {
216-
return "", fmt.Errorf("failed to resolve absolute path for %#q:\n%w", options.Directory, err)
218+
return "", fmt.Errorf(
219+
"failed to resolve absolute path for %#q:\n%w",
220+
options.Directory, err)
217221
}
218222

219223
packageName := filepath.Base(absDir)
220224

221-
slog.Debug("Derived package name from directory name", "name", packageName, "dir", options.Directory)
225+
slog.Debug("Derived package name from directory name",
226+
"name", packageName, "dir", options.Directory)
222227

223228
return packageName, nil
224229
}
225230

226-
// resolveLookasideURI finds the lookaside base URI by checking the default distro first,
227-
// then following the upstream distro reference if needed.
228-
func resolveLookasideURI(env *azldev.Env) (string, error) {
229-
distroDef, distroVersionDef, err := env.Distro()
231+
// resolveFromComponent resolves both the package name and lookaside URI
232+
// from a component's configuration.
233+
func resolveFromComponent(
234+
env *azldev.Env, options *DownloadSourcesOptions,
235+
) (packageName string, lookasideBaseURIs []string, err error) {
236+
resolver := components.NewResolver(env)
237+
238+
filter := &components.ComponentFilter{
239+
ComponentNamePatterns: []string{options.ComponentName},
240+
}
241+
242+
comps, err := resolver.FindComponents(filter)
230243
if err != nil {
231-
return "", fmt.Errorf("failed to resolve default distro:\n%w", err)
244+
return "", nil, fmt.Errorf("failed to resolve component %#q:\n%w",
245+
options.ComponentName, err)
232246
}
233247

234-
// If the default distro itself has a lookaside URI, use it directly.
235-
if distroDef.LookasideBaseURI != "" {
236-
return distroDef.LookasideBaseURI, nil
248+
if comps.Len() == 0 {
249+
return "", nil, fmt.Errorf("component %#q not found",
250+
options.ComponentName)
237251
}
238252

239-
// Otherwise, follow the upstream distro reference from the default component config.
240-
upstreamRef := distroVersionDef.DefaultComponentConfig.Spec.UpstreamDistro
241-
if upstreamRef.Name == "" {
242-
return "", errors.New("no lookaside base URI configured for the default distro, " +
243-
"and no upstream distro reference found; use --lookaside-uri to specify one")
253+
if comps.Len() != 1 {
254+
return "", nil, fmt.Errorf(
255+
"expected exactly one component for %#q, got %d",
256+
options.ComponentName, comps.Len())
257+
}
258+
259+
component := comps.Components()[0]
260+
261+
// Derive package name from the component's upstream-name or component name.
262+
packageName = component.GetName()
263+
if upstreamName := component.GetConfig().Spec.UpstreamName; upstreamName != "" {
264+
packageName = upstreamName
244265
}
245266

246-
upstreamDef, _, err := env.ResolveDistroRef(upstreamRef)
267+
distro, err := sourceproviders.ResolveDistro(env, component)
247268
if err != nil {
248-
return "", fmt.Errorf("failed to resolve upstream distro %#q:\n%w", upstreamRef.Name, err)
269+
return "", nil, fmt.Errorf(
270+
"failed to resolve distro for component %#q:\n%w",
271+
options.ComponentName, err)
249272
}
250273

251-
if upstreamDef.LookasideBaseURI == "" {
252-
return "", fmt.Errorf("no lookaside base URI configured for upstream distro %#q", upstreamRef.Name)
274+
if distro.Definition.LookasideBaseURI == "" {
275+
return "", nil, fmt.Errorf(
276+
"no lookaside base URI configured for distro %#q",
277+
distro.Ref.Name)
253278
}
254279

255-
return upstreamDef.LookasideBaseURI, nil
280+
return packageName, []string{distro.Definition.LookasideBaseURI}, nil
256281
}

0 commit comments

Comments
 (0)