this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

modresolve: support special registry "none"

This enables a user to explicitly mark that there should be no
fallback registry and also, as a natural consequence, allows a user to
specify subsets of modules for which registry access is denied.

Fixes #2963

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: I8fdf7144b02fc61541bb28c8895c4cddf992f642
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1193289
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>

+116 -4
+15
cmd/cue/cmd/help.go
··· 255 255 CUE_REGISTRY=localhost:5000 256 256 CUE_REGISTRY='[::1]:5000' 257 257 258 + The special name "none" can be used to indicate that no registry 259 + should be used. 260 + 258 261 If a path is present too, all modules will be stored under that path. 259 262 260 263 For example: ··· 290 293 Note that the syntax above implies that the ordering of the elements in 291 294 CUE_REGISTRY isn't important because the resolution algorithm is 292 295 order-independent. 296 + 297 + To specify that no registry should be used for a given module prefix, 298 + the special name "none" can be used. 299 + 300 + For example: 301 + 302 + CUE_REGISTRY='foo.example/bar=none,myregistry.example' 303 + 304 + In the above example, any attempt to fetch a module under 305 + "foo.example/bar" will result in a failure. Note that this will not 306 + take effect if the module is already present in the on-disk cache, 307 + which is consulted before looking at CUE_REGISTRY. 293 308 294 309 295 310 Customizing Name Resolution
+21
cmd/cue/cmd/testdata/script/help_registryconfig.txtar
··· 23 23 CUE_REGISTRY=localhost:5000 24 24 CUE_REGISTRY='[::1]:5000' 25 25 26 + The special name "none" can be used to indicate that no registry 27 + should be used. 28 + 26 29 If a path is present too, all modules will be stored under that path. 27 30 28 31 For example: ··· 58 61 Note that the syntax above implies that the ordering of the elements in 59 62 CUE_REGISTRY isn't important because the resolution algorithm is 60 63 order-independent. 64 + 65 + To specify that no registry should be used for a given module prefix, 66 + the special name "none" can be used. 67 + 68 + For example: 69 + 70 + CUE_REGISTRY='foo.example/bar=none,myregistry.example' 71 + 72 + In the above example, any attempt to fetch a module under 73 + "foo.example/bar" will result in a failure. Note that this will not 74 + take effect if the module is already present in the on-disk cache, 75 + which is consulted before looking at CUE_REGISTRY. 61 76 62 77 63 78 Customizing Name Resolution ··· 125 140 // repoPrefix is used to determine the repository to use for a 126 141 // specific module. 127 142 // 143 + // As a special case, the registry may be "none", indicating 144 + // that there is no registry for its associated modules. 145 + // If a module resolves to a "none" registry, the resolver 146 + // will return an error. 147 + // 128 148 // Examples: 129 149 // "localhost:1234" 130 150 // "myregistry.example/my-modules+secure" 151 + // "none" 131 152 registry!: string 132 153 133 154 // pathEncoding specifies how module versions map to
+28
cmd/cue/cmd/testdata/script/registry_nofallback.txtar
··· 1 + # Check that we can explicitly avoid falling back to the default registry. 2 + env CUE_REGISTRY=foo.com=$CUE_REGISTRY1,none 3 + ! exec cue eval . 4 + cmp stderr expect-stderr 5 + 6 + -- expect-stderr -- 7 + import failed: cannot find package "example.com@v0": cannot fetch example.com@v0.0.1: cannot resolve example.com (version v0.0.1) to registry: 8 + ./main.cue:2:8 9 + -- cue.mod/module.cue -- 10 + module: "main.org@v0" 11 + language: version: "v0.8.0" 12 + deps: { 13 + "example.com@v0": { 14 + v: "v0.0.1" 15 + } 16 + } 17 + -- main.cue -- 18 + package main 19 + import "example.com@v0:main" 20 + 21 + main 22 + 23 + -- _registry1/example.com_v0.0.1/cue.mod/module.cue -- 24 + module: "example.com@v0" 25 + language: version: "v0.8.0" 26 + 27 + -- _registry1/example.com_v0.0.1/top.cue -- 28 + package main
+13 -3
internal/mod/modresolve/resolve.go
··· 134 134 StripPrefix bool `json:"stripPrefix,omitempty"` 135 135 136 136 // The following fields are filled in from Registry after parsing. 137 + none bool 137 138 host string 138 139 repository string 139 140 insecure bool ··· 144 145 if err != nil { 145 146 return err 146 147 } 147 - r.host, r.repository, r.insecure = r1.host, r1.repository, r1.insecure 148 + r.none, r.host, r.repository, r.insecure = r1.none, r1.host, r1.repository, r1.insecure 148 149 149 150 if r.PrefixForTags != "" { 150 151 if !ociref.IsValidTag(r.PrefixForTags) { ··· 348 349 func (r *resolver) initHosts() error { 349 350 hosts := make(map[string]bool) 350 351 addHost := func(reg *registryConfig) error { 352 + if reg.none { 353 + return nil 354 + } 351 355 if insecure, ok := hosts[reg.host]; ok { 352 356 if insecure != reg.insecure { 353 357 return fmt.Errorf("registry host %q is specified both as secure and insecure", reg.host) ··· 416 420 // It's a possible match but not necessarily the longest one. 417 421 bestMatch, bestMatchReg = pat, reg 418 422 } 419 - if bestMatchReg == nil { 423 + reg := bestMatchReg 424 + if reg == nil || reg.none { 420 425 return Location{}, false 421 426 } 422 - reg := bestMatchReg 423 427 loc := Location{ 424 428 Host: reg.host, 425 429 Insecure: reg.insecure, ··· 448 452 } 449 453 450 454 func parseRegistry(env0 string) (*registryConfig, error) { 455 + if env0 == "none" { 456 + return &registryConfig{ 457 + Registry: env0, 458 + none: true, 459 + }, nil 460 + } 451 461 env := env0 452 462 var suffix string 453 463 if i := strings.LastIndex(env, "+"); i > 0 {
+29
internal/mod/modresolve/resolve_test.go
··· 164 164 }, 165 165 }, 166 166 }, { 167 + testName: "PrefixWithCatchAllDefaultAndExplicitNoneFallback", 168 + in: "example.com=registry.example.com/offset,none", 169 + catchAllDefault: "registry.somewhere", 170 + wantAllHosts: []Host{{"registry.example.com", false}}, 171 + lookups: map[string]*Location{ 172 + "fruit.com/apple": nil, 173 + "example.com/blah": { 174 + Host: "registry.example.com", 175 + Repository: "offset/example.com/blah", 176 + }, 177 + }, 178 + }, { 179 + testName: "PrefixWithExplicitNone", 180 + in: "example.com=none", 181 + catchAllDefault: "registry.somewhere", 182 + wantAllHosts: []Host{{"registry.somewhere", false}}, 183 + lookups: map[string]*Location{ 184 + "fruit.com/apple": { 185 + Host: "registry.somewhere", 186 + Repository: "fruit.com/apple", 187 + }, 188 + "example.com/blah": nil, 189 + }, 190 + }, { 167 191 testName: "LocalhostIsInsecure", 168 192 in: "localhost:5000", 169 193 wantAllHosts: []Host{{"localhost:5000", true}}, ··· 330 354 registry: "r3.example/repo" 331 355 stripPrefix: true 332 356 } 357 + "badmodules.org": { 358 + registry: "none" 359 + } 333 360 } 334 361 `, 335 362 wantAllHosts: []Host{{ ··· 386 413 Repository: "repo", 387 414 Tag: "v0.0.1", 388 415 }, 416 + "badmodules.org/something v1.2.3": nil, 417 + "badmodules.org v1.2.3": nil, 389 418 }, 390 419 }, { 391 420 testName: "InvalidModulePath",
+6
internal/mod/modresolve/schema.cue
··· 65 65 // repoPrefix is used to determine the repository to use for a 66 66 // specific module. 67 67 // 68 + // As a special case, the registry may be "none", indicating 69 + // that there is no registry for its associated modules. 70 + // If a module resolves to a "none" registry, the resolver 71 + // will return an error. 72 + // 68 73 // Examples: 69 74 // "localhost:1234" 70 75 // "myregistry.example/my-modules+secure" 76 + // "none" 71 77 registry!: string 72 78 73 79 // pathEncoding specifies how module versions map to
+4 -1
mod/modconfig/modconfig.go
··· 156 156 func (r *Resolver) ResolveToRegistry(mpath string, version string) (modregistry.RegistryLocation, error) { 157 157 loc, ok := r.resolver.ResolveToLocation(mpath, version) 158 158 if !ok { 159 - // This can only happen when mpath is invalid, which should not 159 + // This can happen when mpath is invalid, which should not 160 160 // happen in practice, as the only caller is modregistry which 161 161 // vets module paths before calling Resolve. 162 + // 163 + // It can also happen when the user has explicitly configured a "none" 164 + // registry to avoid falling back to a default registry. 162 165 return modregistry.RegistryLocation{}, fmt.Errorf("cannot resolve %s (version %s) to registry", mpath, version) 163 166 } 164 167 r.mu.Lock()