Skip to content

Commit 53efa31

Browse files
authored
fix(cas): return 404 error if artifact does not exist (#227)
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
1 parent 2e47bd8 commit 53efa31

File tree

9 files changed

+129
-89
lines changed

9 files changed

+129
-89
lines changed

Makefile

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
1-
VERSION=$(shell git describe --tags --always)
1+
include common.mk
22

3+
VERSION=$(shell git describe --tags --always)
34
API_PROTO_FILES=$(shell find api -name *.proto)
45

5-
.PHONY: init
6-
# init env
7-
init:
8-
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30.0
9-
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
10-
go install github.com/envoyproxy/protoc-gen-validate@v1.0.1
11-
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest
12-
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
13-
go install github.com/google/wire/cmd/wire@latest
14-
go install github.com/vektra/mockery/v2@v2.20.0
15-
go install ariga.io/atlas/cmd/atlas@v0.12.0
16-
go install github.com/bufbuild/buf/cmd/buf@v1.10.0
17-
186
.PHONY: api
197
# generate api proto
208
api:
@@ -54,22 +42,3 @@ lint:
5442
# All tests, both unit and integration
5543
test:
5644
go test ./...
57-
58-
# show help
59-
help:
60-
@echo ''
61-
@echo 'Usage:'
62-
@echo ' make [target]'
63-
@echo ''
64-
@echo 'Targets:'
65-
@awk '/^[a-zA-Z\-_0-9]+:/ { \
66-
helpMessage = match(lastLine, /^# (.*)/); \
67-
if (helpMessage) { \
68-
helpCommand = substr($$1, 0, index($$1, ":")-1); \
69-
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
70-
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
71-
} \
72-
} \
73-
{ lastLine = $$0 }' $(MAKEFILE_LIST)
74-
75-
.DEFAULT_GOAL := help

app/artifact-cas/Makefile

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
VERSION=$(shell git describe --tags --always)
1+
include ../../common.mk
22

33
.PHONY: config
44
# generate config proto
5-
config:
5+
config: check-buf-tool
66
cd ./internal/conf && buf generate
77

88
.PHONY: api
99
# generate api proto
10-
api:
10+
api: check-buf-tool
1111
cd ./api && buf generate
1212

1313
.PHONY: build
@@ -30,37 +30,18 @@ test:
3030

3131
.PHONY: lint
3232
# lint
33-
lint:
33+
lint: check-golangci-lint-tool check-buf-tool
3434
golangci-lint run
3535
buf lint api
3636
buf lint internal/conf
3737

3838
.PHONY: generate
3939
# generate
40-
generate:
40+
generate: check-wire-tool api config
4141
go generate ./...
4242

4343
.PHONY: all
4444
# generate all
4545
all:
4646
make config;
4747
make generate;
48-
49-
# show help
50-
help:
51-
@echo ''
52-
@echo 'Usage:'
53-
@echo ' make [target]'
54-
@echo ''
55-
@echo 'Targets:'
56-
@awk '/^[a-zA-Z\-_0-9]+:/ { \
57-
helpMessage = match(lastLine, /^# (.*)/); \
58-
if (helpMessage) { \
59-
helpCommand = substr($$1, 0, index($$1, ":")-1); \
60-
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
61-
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
62-
} \
63-
} \
64-
{ lastLine = $$0 }' $(MAKEFILE_LIST)
65-
66-
.DEFAULT_GOAL := help

app/artifact-cas/internal/service/resource.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
v1 "github.com/chainloop-dev/chainloop/app/artifact-cas/api/cas/v1"
2222
backend "github.com/chainloop-dev/chainloop/internal/blobmanager"
2323
sl "github.com/chainloop-dev/chainloop/internal/servicelogger"
24+
"github.com/go-kratos/kratos/v2/errors"
2425
)
2526

2627
type ResourceService struct {
@@ -41,13 +42,15 @@ func (s *ResourceService) Describe(ctx context.Context, req *v1.ResourceServiceD
4142
return nil, err
4243
}
4344

44-
backend, err := s.backendP.FromCredentials(ctx, info.StoredSecretID)
45+
b, err := s.backendP.FromCredentials(ctx, info.StoredSecretID)
4546
if err != nil {
4647
return nil, sl.LogAndMaskErr(err, s.log)
4748
}
4849

49-
res, err := backend.Describe(ctx, req.Digest)
50-
if err != nil {
50+
res, err := b.Describe(ctx, req.Digest)
51+
if err != nil && backend.IsNotFound(err) {
52+
return nil, errors.NotFound("not found", err.Error())
53+
} else if err != nil {
5154
return nil, sl.LogAndMaskErr(err, s.log)
5255
}
5356

app/cli/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func main() {
3838
}
3939
}
4040

41-
// handle predefinided errors and handle types so we can tailor the experience
41+
// handle predefined errors and handle types so we can tailor the experience
4242
func errorInfo(err error, logger zerolog.Logger) (string, int) {
4343
var msg string
4444
exitCode := 1

app/controlplane/Makefile

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
VERSION=$(shell git describe --tags --always)
1+
include ../../common.mk
22

33
.PHONY: config
44
# generate config proto bindings
5-
config:
5+
config: check-buf-tool
66
cd ./internal/conf && buf generate
77

88
.PHONY: api
99
# generate api proto bindings
10-
api:
10+
api: check-buf-tool
1111
cd ./api && buf generate
1212

1313
.PHONY: build
@@ -28,13 +28,13 @@ local_db = postgres://postgres:@localhost:5432/controlplane?sslmode=disable
2828

2929
.PHONY: migration_apply
3030
# run migrations against local db
31-
migration_apply:
31+
migration_apply: check-atlas-tool
3232
atlas migrate status --dir ${local_migrations_dir} --url ${local_db}
3333
atlas migrate apply --dir ${local_migrations_dir} --url ${local_db}
3434

3535
.PHONY: migration_new
3636
# generate new migration if needed from the current ent schema
37-
migration_new:
37+
migration_new: check-atlas-tool
3838
atlas migrate diff --dir ${local_migrations_dir} --to "ent://internal/data/ent/schema" --dev-url "docker://postgres/15/test?search_path=public"
3939

4040
.PHONY: test
@@ -49,14 +49,14 @@ test-unit:
4949

5050
.PHONY: lint
5151
# lint
52-
lint:
52+
lint: check-golangci-lint-tool check-buf-tool
5353
buf lint api
5454
buf lint internal/conf
5555
golangci-lint run
5656

5757
.PHONY: generate
5858
# generate proto bindings, wire injectors, and ent models
59-
generate: api config
59+
generate: check-wire-tool api config
6060
go generate ./...
6161

6262
.PHONY: all
@@ -69,22 +69,3 @@ all:
6969
# Visualize data model
7070
visualize-data-model:
7171
xdg-open internal/data/ent/schema-viz.html
72-
73-
# show help
74-
help:
75-
@echo ''
76-
@echo 'Usage:'
77-
@echo ' make [target]'
78-
@echo ''
79-
@echo 'Targets:'
80-
@awk '/^[a-zA-Z\-_0-9]+:/ { \
81-
helpMessage = match(lastLine, /^# (.*)/); \
82-
if (helpMessage) { \
83-
helpCommand = substr($$1, 0, index($$1, ":")-1); \
84-
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
85-
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
86-
} \
87-
} \
88-
{ lastLine = $$0 }' $(MAKEFILE_LIST)
89-
90-
.DEFAULT_GOAL := help

common.mk

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
VERSION=$(shell git describe --tags --always)
2+
3+
.PHONY: init
4+
# init env
5+
init:
6+
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30.0
7+
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
8+
go install github.com/envoyproxy/protoc-gen-validate@v1.0.1
9+
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest
10+
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
11+
go install github.com/google/wire/cmd/wire@latest
12+
go install github.com/vektra/mockery/v2@v2.20.0
13+
go install ariga.io/atlas/cmd/atlas@v0.12.0
14+
go install github.com/bufbuild/buf/cmd/buf@v1.10.0
15+
16+
# show help
17+
help:
18+
@echo ''
19+
@echo 'Usage:'
20+
@echo ' make [target]'
21+
@echo ''
22+
@echo 'Targets:'
23+
@awk '/^[a-zA-Z\-_0-9]+:/ { \
24+
helpMessage = match(lastLine, /^# (.*)/); \
25+
if (helpMessage) { \
26+
helpCommand = substr($$1, 0, index($$1, ":")-1); \
27+
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
28+
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
29+
} \
30+
} \
31+
{ lastLine = $$0 }' $(MAKEFILE_LIST)
32+
33+
.DEFAULT_GOAL := help
34+
35+
.PHONY: check-goreleaser-tool
36+
check-atlas-tool:
37+
@if ! command -v atlas >/dev/null 2>&1; then \
38+
echo "altas is not installed. Please run \"make init\" or install the tool manually."; \
39+
exit 1; \
40+
fi
41+
42+
.PHONY: check-wire-tool
43+
check-wire-tool:
44+
@if ! command -v wire >/dev/null 2>&1; then \
45+
echo "wire is not installed. Please run \"make init\" or install the tool manually."; \
46+
exit 1; \
47+
fi
48+
49+
.PHONY: check-golangci-lint-tool
50+
check-golangci-lint-tool:
51+
@if ! command -v golangci-lint >/dev/null 2>&1; then \
52+
echo "golangci-lint is not installed. Please run \"make init\" or install the tool manually."; \
53+
exit 1; \
54+
fi
55+
56+
.PHONY: check-buf-tool
57+
check-buf-tool:
58+
@if ! command -v buf >/dev/null 2>&1; then \
59+
echo "buf is not installed. Please run \"make init\" or install the tool manually."; \
60+
exit 1; \
61+
fi
62+

internal/blobmanager/errors.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// Copyright 2023 The Chainloop Authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package backend
17+
18+
import (
19+
"errors"
20+
"fmt"
21+
)
22+
23+
type ErrNotFound struct {
24+
entity string
25+
}
26+
27+
func NewErrNotFound(entity string) ErrNotFound {
28+
return ErrNotFound{entity}
29+
}
30+
31+
func (e ErrNotFound) Error() string {
32+
return fmt.Sprintf("%s not found", e.entity)
33+
}
34+
35+
func IsNotFound(err error) bool {
36+
return errors.As(err, &ErrNotFound{})
37+
}

internal/blobmanager/oci/backend.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ import (
2929
"github.com/google/go-containerregistry/pkg/v1/empty"
3030
"github.com/google/go-containerregistry/pkg/v1/mutate"
3131
"github.com/google/go-containerregistry/pkg/v1/remote"
32+
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
3233
"github.com/google/go-containerregistry/pkg/v1/static"
3334
"github.com/google/go-containerregistry/pkg/v1/types"
3435

3536
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
3637

3738
pb "github.com/chainloop-dev/chainloop/app/artifact-cas/api/cas/v1"
39+
backend "github.com/chainloop-dev/chainloop/internal/blobmanager"
3840
)
3941

4042
type Backend struct {
@@ -185,6 +187,11 @@ func (b *Backend) Describe(_ context.Context, digest string) (*pb.CASResource, e
185187

186188
img, err := remote.Image(ref, remote.WithAuthFromKeychain(b.keychain))
187189
if err != nil {
190+
var e *transport.Error
191+
if errors.As(err, &e) && e.StatusCode == http.StatusNotFound {
192+
return nil, backend.NewErrNotFound("image")
193+
}
194+
188195
return nil, fmt.Errorf("getting image: %w", err)
189196
}
190197

@@ -197,7 +204,7 @@ func (b *Backend) Describe(_ context.Context, digest string) (*pb.CASResource, e
197204
return nil, fmt.Errorf("extracting manifest: %w", err)
198205
}
199206

200-
// Valirate image already checked that the manifest has exactly one layer
207+
// Validate image already checked that the manifest has exactly one layer
201208
size := manifest.Layers[0].Size
202209

203210
filename, ok := manifest.Annotations[ocispec.AnnotationTitle]

internal/blobmanager/oci/backend_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ func (s *testSuite) TestDescribe() {
181181
name: "not found",
182182
digest: "deadbeef",
183183
wantErr: true,
184-
errMsg: "Unknown name",
184+
errMsg: "not found",
185185
},
186186
{
187187
name: "valid image",

0 commit comments

Comments
 (0)