versionsapi: change image path (#856)

Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
Paul Meyer 2023-01-04 17:07:16 +01:00 committed by GitHub
parent 3a359aea65
commit f9458950cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 49 additions and 53 deletions

View File

@ -151,7 +151,7 @@ jobs:
{
echo "imageVersion=${IMAGE_VERSION}"
echo "imageName=ref/${REF}/stream/${STREAM}/${IMAGE_VERSION}"
echo "imageApiBasePath=constellation/v1/ref/${REF}/stream/${STREAM}/image/${IMAGE_VERSION}"
echo "imageApiBasePath=constellation/v1/ref/${REF}/stream/${STREAM}/${IMAGE_VERSION}/image"
} >> "$GITHUB_OUTPUT"
if [[ "${REF}" = "-" ]] && [[ "${STREAM}" = "stable" ]]; then
@ -728,22 +728,14 @@ jobs:
echo -e "\`\`\`"
) >> "$GITHUB_STEP_SUMMARY"
- name: Checkout
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
with:
ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}
- name: Setup Go environment
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
with:
go-version: "1.19.4"
cache: true
- name: Add version to versionsapi
if: needs.build-settings.outputs.ref != '-'
uses: ./.github/workflows/versionsapi
with:
ref: ${{ needs.build-settings.outputs.ref }}
stream: ${{ inputs.stream }}
version: ${{ needs.build-settings.outputs.imageVersion }}
add_latest: true
add-version-to-versionsapi:
needs: [upload-image-lookup-table, build-settings]
name: "Add version to versionsapi"
if: needs.build-settings.outputs.ref != '-'
uses: ./.github/workflows/versionsapi.yml
with:
command: add
ref: ${{ needs.build-settings.outputs.ref }}
stream: ${{ inputs.stream }}
version: ${{ needs.build-settings.outputs.imageVersion }}
add_latest: true

View File

@ -50,7 +50,7 @@ jobs:
- name: Check if image definition from build pipeline exists
run: |
wget -O /dev/null "https://cdn.confidential.cloud/constellation/v1/ref/${{ steps.extract.outputs.ref }}/stream/${{ steps.extract.outputs.stream }}/image/${{ steps.extract.outputs.version }}/info.json"
wget -O /dev/null "https://cdn.confidential.cloud/constellation/v1/ref/${{ steps.extract.outputs.ref }}/stream/${{ steps.extract.outputs.stream }}/${{ steps.extract.outputs.version }}/image/info.json"
shell: bash
- name: Setup Go environment
@ -217,7 +217,7 @@ jobs:
- name: Download expected measurements from build pipeline for image
run: |
path="constellation/v1/ref/${ref}/stream/${stream}/image/${version}/csp/${{ matrix.provider }}/measurements.image.json"
path="constellation/v1/ref/${ref}/stream/${stream}/${version}/image/csp/${{ matrix.provider }}/measurements.image.json"
mkdir -p ${{ github.workspace }}/expected-measurements
wget -O ${{ github.workspace }}/expected-measurements/measurements.image.json "https://cdn.confidential.cloud/${path}"
cat ${{ github.workspace }}/expected-measurements/measurements.image.json
@ -319,7 +319,7 @@ jobs:
- name: Upload to S3
run: |
S3_PATH=s3://cdn-constellation-backend/constellation/v1/ref/${ref}/stream/${stream}/image/${version}/csp/${{ matrix.provider }}
S3_PATH=s3://cdn-constellation-backend/constellation/v1/ref/${ref}/stream/${stream}/${version}/image/csp/${{ matrix.provider }}
aws s3 cp "${{ github.workspace }}/generated-measurements/measurements-${{ matrix.provider }}.json" "${S3_PATH}/measurements.json"
aws s3 cp "${{ github.workspace }}/generated-measurements/measurements-${{ matrix.provider }}.json.sig" "${S3_PATH}/measurements.json.sig"
shell: bash

View File

@ -195,6 +195,6 @@ func measurementURL(provider cloudprovider.Provider, image, file string) (*url.U
if err != nil {
return nil, fmt.Errorf("parsing image version repository URL: %w", err)
}
url.Path = path.Join(constants.CDNAPIPrefix, "ref", ref, "stream", stream, "image", version, "csp", strings.ToLower(provider.String()), file)
url.Path = path.Join(constants.CDNAPIPrefix, "ref", ref, "stream", stream, version, "image", "csp", strings.ToLower(provider.String()), file)
return url, nil
}

View File

@ -110,8 +110,8 @@ func TestUpdateURLs(t *testing.T) {
},
},
flags: &fetchMeasurementsFlags{},
wantMeasurementsURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/image/someImageVersion/csp/gcp/measurements.json",
wantMeasurementsSigURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/image/someImageVersion/csp/gcp/measurements.json.sig",
wantMeasurementsURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/someImageVersion/image/csp/gcp/measurements.json",
wantMeasurementsSigURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/someImageVersion/image/csp/gcp/measurements.json.sig",
},
"both set by user": {
conf: &config.Config{},
@ -186,14 +186,14 @@ func TestConfigFetchMeasurements(t *testing.T) {
signature := "MEYCIQDRAQNK2NjHJBGrnw3HQAyBsXMCmVCptBdgA6VZ3IlyiAIhAPG42waF1aFZq7dnjP3b2jsMNUtaKYDQQSazW1AX8jgF"
client := newTestClient(func(req *http.Request) *http.Response {
if req.URL.Path == "/constellation/v1/ref/-/stream/stable/image/v999.999.999/csp/gcp/measurements.json" {
if req.URL.Path == "/constellation/v1/ref/-/stream/stable/v999.999.999/image/csp/gcp/measurements.json" {
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(measurements)),
Header: make(http.Header),
}
}
if req.URL.Path == "/constellation/v1/ref/-/stream/stable/image/v999.999.999/csp/gcp/measurements.json.sig" {
if req.URL.Path == "/constellation/v1/ref/-/stream/stable/v999.999.999/image/csp/gcp/measurements.json.sig" {
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(signature)),

View File

@ -171,6 +171,11 @@ func (c *Client) DeleteVersion(ctx context.Context, ver versionsapi.Version) err
retErr = multierr.Append(retErr, fmt.Errorf("updating latest version: %w", err))
}
c.log.Debugf("Deleting artifact path %s for %s", ver.ArtifactPath(), ver.Version)
if err := c.deletePath(ctx, ver.ArtifactPath()); err != nil {
retErr = multierr.Append(retErr, fmt.Errorf("deleting artifact path: %w", err))
}
return retErr
}

View File

@ -41,7 +41,8 @@ func (i ImageInfo) JSONPath() string {
constants.CDNAPIPrefix,
"ref", i.Ref,
"stream", i.Stream,
"image", i.Version,
i.Version,
"image",
"info.json",
)
}

View File

@ -24,7 +24,7 @@ func TestImageInfoJSONPath(t *testing.T) {
Stream: "nightly",
Version: "v1.0.0",
},
wantPath: constants.CDNAPIPrefix + "/ref/test-ref/stream/nightly/image/v1.0.0/info.json",
wantPath: constants.CDNAPIPrefix + "/ref/test-ref/stream/nightly/v1.0.0/image/info.json",
},
"image info release": {
info: ImageInfo{
@ -32,7 +32,7 @@ func TestImageInfoJSONPath(t *testing.T) {
Stream: "stable",
Version: "v1.0.0",
},
wantPath: constants.CDNAPIPrefix + "/ref/-/stream/stable/image/v1.0.0/info.json",
wantPath: constants.CDNAPIPrefix + "/ref/-/stream/stable/v1.0.0/image/info.json",
},
}
@ -55,7 +55,7 @@ func TestImageInfoURL(t *testing.T) {
Stream: "nightly",
Version: "v1.0.0",
},
wantURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/test-ref/stream/nightly/image/v1.0.0/info.json",
wantURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/test-ref/stream/nightly/v1.0.0/image/info.json",
},
"image info release": {
info: ImageInfo{
@ -63,7 +63,7 @@ func TestImageInfoURL(t *testing.T) {
Stream: "stable",
Version: "v1.0.0",
},
wantURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/image/v1.0.0/info.json",
wantURL: constants.CDNRepositoryURL + "/" + constants.CDNAPIPrefix + "/ref/-/stream/stable/v1.0.0/image/info.json",
},
}

View File

@ -143,16 +143,14 @@ func (v Version) ListPath(gran Granularity) string {
)
}
// ImagePath returns the path to the image specification of this version.
// ArtifactPath returns the path to the artifacts stored for this version.
// The path points to a directory and is intended to be used for deletion.
//
// TODO(katexochen): Refactor path and make this a unified path for all version kinds.
func (v Version) ImagePath() string {
func (v Version) ArtifactPath() string {
return path.Join(
constants.CDNAPIPrefix,
"ref", v.Ref,
"stream", v.Stream,
"image", v.Version,
v.Version,
)
}

View File

@ -373,7 +373,7 @@ func TestVersionListPathURL(t *testing.T) {
}
}
func TestVersionImagePath(t *testing.T) {
func TestVersionArtifactPath(t *testing.T) {
testCases := map[string]struct {
ver Version
wantPath string
@ -385,7 +385,7 @@ func TestVersionImagePath(t *testing.T) {
Version: "v9.9.9",
Kind: VersionKindImage,
},
wantPath: constants.CDNAPIPrefix + "/ref/" + ReleaseRef + "/stream/stable/image/v9.9.9",
wantPath: constants.CDNAPIPrefix + "/ref/" + ReleaseRef + "/stream/stable/v9.9.9",
},
"release debug stream": {
ver: Version{
@ -394,7 +394,7 @@ func TestVersionImagePath(t *testing.T) {
Version: "v9.9.9",
Kind: VersionKindImage,
},
wantPath: constants.CDNAPIPrefix + "/ref/" + ReleaseRef + "/stream/debug/image/v9.9.9",
wantPath: constants.CDNAPIPrefix + "/ref/" + ReleaseRef + "/stream/debug/v9.9.9",
},
"branch ref": {
ver: Version{
@ -403,7 +403,7 @@ func TestVersionImagePath(t *testing.T) {
Version: "v9.9.9",
Kind: VersionKindImage,
},
wantPath: constants.CDNAPIPrefix + "/ref/foo/stream/debug/image/v9.9.9",
wantPath: constants.CDNAPIPrefix + "/ref/foo/stream/debug/v9.9.9",
},
}
@ -411,7 +411,7 @@ func TestVersionImagePath(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
path := tc.ver.ImagePath()
path := tc.ver.ArtifactPath()
assert.Equal(tc.wantPath, path)
})
}

View File

@ -27,12 +27,12 @@ There may be more API groups in the future (e.g. `cli`)
- [`/constellation/v1/ref/<ref>/stream/<stream>/versions/latest/<kind>.json`](version-api.md#latest)
- [`/constellation/v1/ref/<ref>/stream/<stream>/versions/major/<base>/<kind>.json`](version-api.md#major-to-minor-version-list)
- [`/constellation/v1/ref/<ref>/stream/<stream>/versions/minor/<base>/<kind>.json`](version-api.md#minor-to-patch-version-list)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/info.json`](image-api.md#image-lookup-table)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/sbom.<format>.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/csp/<csp>/measurements.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/csp/<csp>/measurements.json.sig`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/csp/<csp>/measurements.image.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/image/<version>/csp/<csp>/image.raw`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/info.json`](image-api.md#image-lookup-table)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/sbom.<format>.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/csp/<csp>/measurements.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/csp/<csp>/measurements.json.sig`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/csp/<csp>/measurements.image.json`](image-api.md)
- [`/constellation/v1/ref/<ref>/stream/<stream>/<version>/image/csp/<csp>/image.raw`](image-api.md)
## API path identifiers `ref`, `stream` and `version`

View File

@ -71,7 +71,7 @@ Where applicable, the API uses the following CSP names:
The following HTTP endpoints are available:
- `GET /constellation/v1/ref/<REF>/stream/<STREAM>/image/<VERSION>/`
- `GET /constellation/v1/ref/<REF>/stream/<STREAM>/<VERSION>/image/`
- [`info.json` returns the lookup table for the given image version.](#image-lookup-table)
- `sbom.<format>.json` contains SBOM files for the given image version. The exact formats and file names are TBD.
- `GET /constellation/v1/ref/<REF>/stream/<STREAM>/<VERSION>/csp/<csp>/` contains files with measurements and signatures for the given image version and CSP.
@ -87,7 +87,7 @@ The following HTTP endpoints are available:
The image lookup table is a JSON file that maps the image name consisting of `ref`, `stream` and `version` to the CSP-specific image references:
```
/constellation/v1/ref/<REF>/stream/<STREAM>/image/<VERSION>/info.json
/constellation/v1/ref/<REF>/stream/<STREAM>/<VERSION>/image/info.json
```
```json
@ -108,7 +108,7 @@ The image lookup table is a JSON file that maps the image name consisting of `re
"sev-es": "gcp-image-123"
},
"qemu": {
"default": "https://cdn.confidential.cloud/constellation/v1/ref/<REF>/stream/<STREAM>/image/<VERSION>/csp/qemu/image.raw"
"default": "https://cdn.confidential.cloud/constellation/v1/ref/<REF>/stream/<STREAM>/<VERSION>/image/csp/qemu/image.raw"
}
}
```
@ -133,7 +133,7 @@ The `image` field is independent of the CSP and is a used to discover the CSP-sp
The CLI can find a CSP- and region specific image reference by looking up the image name in the following order:
- if a local file `<IMAGE NAME>.json` exists, use the lookup table in that file
- otherwise, load the image lookup table from a well known URL (e.g. `https://cdn.confidential.cloud/constellation/v1/ref/<REF>/stream/<STREAM>/image/<VERSION>/info.json`) and use the lookup table in that file
- otherwise, load the image lookup table from a well known URL (e.g. `https://cdn.confidential.cloud/constellation/v1/ref/<REF>/stream/<STREAM>/<VERSION>/image/info.json`) and use the lookup table in that file
- choose the CSP-specific image reference for the current region and security type:
- On AWS, use the AMI ID for the current region (e.g. `.aws.us-east-1`)
- On Azure, use the image ID for the security type (CVM or Trusted Launch) (e.g. `.azure.cvm`)