diff --git a/discovery/discovery.go b/discovery/discovery.go index 89c4d290..a1d8895d 100644 --- a/discovery/discovery.go +++ b/discovery/discovery.go @@ -49,10 +49,6 @@ type ACIEndpoints []ACIEndpoint type PublicKeys []string -const ( - defaultVersion = "latest" -) - var ( templateExpression = regexp.MustCompile(`{.*?}`) errEnough = errors.New("enough discovery information found") @@ -133,9 +129,6 @@ func createTemplateVars(app App) []string { func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecure InsecureOption) (*discoveryData, error) { app = *app.Copy() - if app.Labels["version"] == "" { - app.Labels["version"] = defaultVersion - } _, body, err := httpsOrHTTP(pre, hostHeaders, insecure) if err != nil { diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index 10d7901c..c98adcde 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -402,14 +402,43 @@ func TestDiscoverEndpoints(t *testing.T) { []string{"https://example.com/pubkeys.gpg"}, nil, }, - // Test missing labels. version label should default to - // "latest" and the first template should be rendered + // Test missing version label. Only one template should match { &mockHTTPDoer{ doer: fakeHTTPGet( []meta{ {"/myapp", - "meta05.html", + "meta07.html", + }, + }, + nil, + ), + }, + true, + true, + App{ + Name: "example.com/myapp", + Labels: map[types.ACIdentifier]string{ + "os": "linux", + "arch": "amd64", + }, + }, + []ACIEndpoint{ + ACIEndpoint{ + ACI: "https://storage.example.com/example.com/myapp-latest-linux-amd64.aci", + ASC: "https://storage.example.com/example.com/myapp-latest-linux-amd64.aci.asc", + }, + }, + []string{"https://example.com/pubkeys.gpg"}, + nil, + }, + // Test with required version label. Only one template should match + { + &mockHTTPDoer{ + doer: fakeHTTPGet( + []meta{ + {"/myapp", + "meta07.html", }, }, nil, @@ -418,18 +447,23 @@ func TestDiscoverEndpoints(t *testing.T) { true, true, App{ - Name: "example.com/myapp", - Labels: map[types.ACIdentifier]string{}, + Name: "example.com/myapp", + Labels: map[types.ACIdentifier]string{ + "version": "1.0.0", + "os": "linux", + "arch": "amd64", + }, }, []ACIEndpoint{ ACIEndpoint{ - ACI: "https://storage.example.com/example.com/myapp-latest.aci", - ASC: "https://storage.example.com/example.com/myapp-latest.aci.asc", + ACI: "https://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci", + ASC: "https://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci.asc", }, }, []string{"https://example.com/pubkeys.gpg"}, nil, }, + // Test with a label called "name". It should be ignored. { &mockHTTPDoer{ diff --git a/discovery/testdata/meta07.html b/discovery/testdata/meta07.html new file mode 100644 index 00000000..c08d1118 --- /dev/null +++ b/discovery/testdata/meta07.html @@ -0,0 +1,14 @@ + + + + + My app + + + + + + +

My App

+ + diff --git a/spec/discovery.md b/spec/discovery.md index 1a671c58..18a5e71f 100644 --- a/spec/discovery.md +++ b/spec/discovery.md @@ -106,3 +106,19 @@ Authentication during the discovery process is optional. If an attempt at fetching any resource (the initial discovery URL, an App Container Image, or signature) returns a `401 Unauthorized`, implementations should enact the authentication policy set by the operator. For example, some implementations might only perform HTTP basic authentication over HTTPS connections. + +### Examples + +#### Latest pattern + +If a client wants to retrieve the latest available ACI (without knowing its version) it can provide these meta tags: + +```html + + +``` + +When requiring a specific version, the first template will be rendered, when not requiring a _version_ label the second template will match. + +On the http server, the "latest" url should point to the current latest ACI. +