From d6576eb9b209d5fb75a70a858c06bda7d01b4747 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Sat, 27 Jun 2026 20:50:41 -0400 Subject: [PATCH] contract: neutralize asset-cache names + drop gVisor runsc_path (in-tree) Two in-tree cleanups to the atelet<->ateom contract; no package relocation. - 5a: rename the asset-cache symbols away from runsc (RunSCBinaryPath -> CachedAssetPath, ValidateRunscHash -> ValidateAssetHash) so the cache is named for what it holds (any backend's assets), not gVisor's runsc. - B4: drop the gVisor-specific runsc_path proto field + runscPathFor; gVisor reads runtime_asset_paths like every other backend, leaving the wire contract with zero backend-specific fields. The contract stays under internal/ (ateompb + ateompath). An earlier revision relocated it to pkg/ to publish a go-gettable SDK; that is dropped -- the ateom API is private (a first-party / in-repo seam), so a public out-of-tree contract is not wanted. In-repo backends import it from internal/ directly. --- cmd/atelet/main.go | 8 ++-- cmd/atelet/main_test.go | 6 +-- cmd/atelet/sandbox_assets.go | 8 +--- cmd/ateom-gvisor/main.go | 6 +-- internal/ateompath/ateompath.go | 7 +++- internal/proto/ateompb/ateom.pb.go | 64 ++++++++--------------------- internal/proto/ateompb/ateom.proto | 22 +++++----- internal/resources/validate.go | 18 ++++---- internal/resources/validate_test.go | 6 +-- 9 files changed, 56 insertions(+), 89 deletions(-) diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 50802d7d7..77b8d5789 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -249,13 +249,13 @@ func (s *AteomHerder) Run(ctx context.Context, req *ateletpb.RunRequest) (*atele return nil, err } - // Tell ateom to start the workload. gVisor uses RunscPath; the micro-VM - // runtime uses the full RuntimeAssetPaths set. + // Tell ateom to start the workload. Every backend reads the assets it needs + // from RuntimeAssetPaths (gVisor reads "runsc"; the micro-VM runtime reads its + // cloud-hypervisor/kata-* set). if _, err := client.RunWorkload(ctx, &ateompb.RunWorkloadRequest{ ActorTemplateNamespace: ns, ActorTemplateName: tmpl, ActorId: actorID, - RunscPath: runscPathFor(assetPaths), RuntimeAssetPaths: assetPaths, Spec: buildAteomWorkloadSpec(req.GetSpec()), }); err != nil { @@ -335,7 +335,6 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe ActorTemplateNamespace: ns, ActorTemplateName: tmpl, ActorId: actorID, - RunscPath: runscPathFor(assetPaths), RuntimeAssetPaths: assetPaths, Spec: buildAteomWorkloadSpec(req.GetSpec()), }) @@ -534,7 +533,6 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) ActorTemplateNamespace: ns, ActorTemplateName: tmpl, ActorId: actorID, - RunscPath: runscPathFor(assetPaths), RuntimeAssetPaths: assetPaths, Spec: buildAteomWorkloadSpec(req.GetSpec()), }); err != nil { diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index 6be78fa51..0c357b449 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -255,7 +255,7 @@ func TestFetchAssetRejectsBadHash(t *testing.T) { // Invalid (8 chars, not 64) but separator-free, so it resolves to a normal // filename inside the temp StaticFilesDir. const badHash = "deadbeef" - if err := os.WriteFile(ateompath.RunSCBinaryPath(badHash), []byte("planted"), 0o755); err != nil { + if err := os.WriteFile(ateompath.CachedAssetPath(badHash), []byte("planted"), 0o755); err != nil { t.Fatalf("planting cache file: %v", err) } @@ -313,7 +313,7 @@ func TestFetchAssetStreaming(t *testing.T) { if _, err := s.fetchAsset(context.Background(), assetEntry{URL: url, SHA256: goodHash}); err == nil { t.Fatal("fetchAsset accepted an over-cap asset") } - if _, err := os.Stat(ateompath.RunSCBinaryPath(goodHash)); !errors.Is(err, os.ErrNotExist) { + if _, err := os.Stat(ateompath.CachedAssetPath(goodHash)); !errors.Is(err, os.ErrNotExist) { t.Errorf("over-cap download left a file at the cache path (stat err = %v)", err) } }) @@ -326,7 +326,7 @@ func TestFetchAssetStreaming(t *testing.T) { if _, err := s.fetchAsset(context.Background(), assetEntry{URL: url, SHA256: wrongHash}); err == nil { t.Fatal("fetchAsset accepted a hash mismatch") } - if _, err := os.Stat(ateompath.RunSCBinaryPath(wrongHash)); !errors.Is(err, os.ErrNotExist) { + if _, err := os.Stat(ateompath.CachedAssetPath(wrongHash)); !errors.Is(err, os.ErrNotExist) { t.Errorf("mismatched download left a file at the cache path (stat err = %v)", err) } }) diff --git a/cmd/atelet/sandbox_assets.go b/cmd/atelet/sandbox_assets.go index 4ec0b54f7..ffa81c07b 100644 --- a/cmd/atelet/sandbox_assets.go +++ b/cmd/atelet/sandbox_assets.go @@ -107,19 +107,15 @@ func (s *AteomHerder) ensureSandboxAssets(ctx context.Context, rec *sandboxAsset return paths, nil } -// runscPathFor returns the local path of the gVisor "runsc" asset from a fetched -// asset-path map, or "" if the runtime has none (e.g. micro-VM). -func runscPathFor(paths map[string]string) string { return paths["runsc"] } - // fetchAsset downloads one content-addressed asset (verifying its sha256) into // the shared static-files cache and returns its local path. On a cache hit it // returns immediately. func (s *AteomHerder) fetchAsset(ctx context.Context, entry assetEntry) (string, error) { - if err := resources.ValidateRunscHash(entry.SHA256); err != nil { + if err := resources.ValidateAssetHash(entry.SHA256); err != nil { return "", status.Error(codes.InvalidArgument, err.Error()) } - localPath := ateompath.RunSCBinaryPath(entry.SHA256) + localPath := ateompath.CachedAssetPath(entry.SHA256) _, err := os.Stat(localPath) if err == nil { // EQUALS nil return localPath, nil diff --git a/cmd/ateom-gvisor/main.go b/cmd/ateom-gvisor/main.go index 7e543c7ac..2a9387808 100644 --- a/cmd/ateom-gvisor/main.go +++ b/cmd/ateom-gvisor/main.go @@ -197,7 +197,7 @@ func (s *AteomService) RunWorkload(ctx context.Context, req *ateompb.RunWorkload }() rcmd := &runsc{ - path: req.GetRunscPath(), + path: req.GetRuntimeAssetPaths()["runsc"], actorTemplateNamespace: req.GetActorTemplateNamespace(), actorTemplateName: req.GetActorTemplateName(), actorID: req.GetActorId(), @@ -244,7 +244,7 @@ func (s *AteomService) CheckpointWorkload(ctx context.Context, req *ateompb.Chec // * After we exit, atelet will tear down OCI bundles and reset the actor directory. rcmd := &runsc{ - path: req.GetRunscPath(), + path: req.GetRuntimeAssetPaths()["runsc"], actorTemplateNamespace: req.GetActorTemplateNamespace(), actorTemplateName: req.GetActorTemplateName(), actorID: req.GetActorId(), @@ -351,7 +351,7 @@ func (s *AteomService) RestoreWorkload(ctx context.Context, req *ateompb.Restore }() rcmd := &runsc{ - path: req.GetRunscPath(), + path: req.GetRuntimeAssetPaths()["runsc"], actorTemplateNamespace: req.GetActorTemplateNamespace(), actorTemplateName: req.GetActorTemplateName(), actorID: req.GetActorId(), diff --git a/internal/ateompath/ateompath.go b/internal/ateompath/ateompath.go index a779755c4..78d02599b 100644 --- a/internal/ateompath/ateompath.go +++ b/internal/ateompath/ateompath.go @@ -26,11 +26,14 @@ const ( ) var ( - // StaticFilesDir holds things like downloaded runsc binaries. + // StaticFilesDir holds downloaded, content-addressed sandbox assets. StaticFilesDir = filepath.Join(BasePath, "static-files") ) -func RunSCBinaryPath(sha256 string) string { +// CachedAssetPath returns the on-disk cache path for a content-addressed +// sandbox asset, keyed by its SHA-256 hash. The "runsc-" filename prefix is +// kept for backward compatibility — existing snapshots embed this absolute path. +func CachedAssetPath(sha256 string) string { return filepath.Join(StaticFilesDir, "runsc-"+sha256) } diff --git a/internal/proto/ateompb/ateom.pb.go b/internal/proto/ateompb/ateom.pb.go index c0183619c..142cdbd00 100644 --- a/internal/proto/ateompb/ateom.pb.go +++ b/internal/proto/ateompb/ateom.pb.go @@ -40,12 +40,11 @@ type RunWorkloadRequest struct { ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` - // runtime_asset_paths maps a runtime asset name (e.g. "cloud-hypervisor", - // "virtiofsd", "kata-kernel", "kata-image", "kata-config") - // to the local on-disk path atelet fetched it to (content-addressed, like - // runsc_path). Empty for the gVisor runtime, which uses runsc_path. + // runtime_asset_paths maps a runtime asset name to the local on-disk path + // atelet fetched it to (content-addressed). Each backend reads the names it + // needs: gVisor reads "runsc"; a micro-VM backend reads "cloud-hypervisor", + // "kata-kernel", "kata-image", "kata-config"; a custom ateom-* reads its own. RuntimeAssetPaths map[string]string `protobuf:"bytes,7,rep,name=runtime_asset_paths,json=runtimeAssetPaths,proto3" json:"runtime_asset_paths,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -102,13 +101,6 @@ func (x *RunWorkloadRequest) GetActorId() string { return "" } -func (x *RunWorkloadRequest) GetRunscPath() string { - if x != nil { - return x.RunscPath - } - return "" -} - func (x *RunWorkloadRequest) GetSpec() *WorkloadSpec { if x != nil { return x.Spec @@ -253,7 +245,6 @@ type CheckpointWorkloadRequest struct { ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // An object storage URI prefix below which the checkpoint data will be // stored. @@ -264,8 +255,8 @@ type CheckpointWorkloadRequest struct { // // For example: "gs://bucket/actors/1234/snapshots/5678/" SnapshotUriPrefix string `protobuf:"bytes,6,opt,name=snapshot_uri_prefix,json=snapshotUriPrefix,proto3" json:"snapshot_uri_prefix,omitempty"` - // runtime_asset_paths maps a runtime asset name to the local on-disk path - // atelet fetched it to (see RunWorkloadRequest). Empty for gVisor. + // runtime_asset_paths maps a runtime asset name to its local on-disk path + // (see RunWorkloadRequest). gVisor reads "runsc". RuntimeAssetPaths map[string]string `protobuf:"bytes,7,rep,name=runtime_asset_paths,json=runtimeAssetPaths,proto3" json:"runtime_asset_paths,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -322,13 +313,6 @@ func (x *CheckpointWorkloadRequest) GetActorId() string { return "" } -func (x *CheckpointWorkloadRequest) GetRunscPath() string { - if x != nil { - return x.RunscPath - } - return "" -} - func (x *CheckpointWorkloadRequest) GetSpec() *WorkloadSpec { if x != nil { return x.Spec @@ -402,12 +386,11 @@ type RestoreWorkloadRequest struct { ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // The object storage URI prefix of the snapshot to restore. SnapshotUriPrefix string `protobuf:"bytes,6,opt,name=snapshot_uri_prefix,json=snapshotUriPrefix,proto3" json:"snapshot_uri_prefix,omitempty"` - // runtime_asset_paths maps a runtime asset name to the local on-disk path - // atelet fetched it to (see RunWorkloadRequest). Empty for gVisor. + // runtime_asset_paths maps a runtime asset name to its local on-disk path + // (see RunWorkloadRequest). gVisor reads "runsc". RuntimeAssetPaths map[string]string `protobuf:"bytes,7,rep,name=runtime_asset_paths,json=runtimeAssetPaths,proto3" json:"runtime_asset_paths,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -464,13 +447,6 @@ func (x *RestoreWorkloadRequest) GetActorId() string { return "" } -func (x *RestoreWorkloadRequest) GetRunscPath() string { - if x != nil { - return x.RunscPath - } - return "" -} - func (x *RestoreWorkloadRequest) GetSpec() *WorkloadSpec { if x != nil { return x.Spec @@ -532,51 +508,45 @@ var File_ateom_proto protoreflect.FileDescriptor const file_ateom_proto_rawDesc = "" + "\n" + - "\vateom.proto\x12\x05ateom\"\x89\x03\n" + + "\vateom.proto\x12\x05ateom\"\xf0\x02\n" + "\x12RunWorkloadRequest\x128\n" + "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + - "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + - "\n" + - "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12'\n" + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12`\n" + "\x13runtime_asset_paths\x18\a \x03(\v20.ateom.RunWorkloadRequest.RuntimeAssetPathsEntryR\x11runtimeAssetPaths\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"@\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01J\x04\b\x04\x10\x05\"@\n" + "\fWorkloadSpec\x120\n" + "\n" + "containers\x18\x01 \x03(\v2\x10.ateom.ContainerR\n" + "containers\"\x1f\n" + "\tContainer\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"\x15\n" + - "\x13RunWorkloadResponse\"\xc7\x03\n" + + "\x13RunWorkloadResponse\"\xae\x03\n" + "\x19CheckpointWorkloadRequest\x128\n" + "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + - "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + - "\n" + - "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12'\n" + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12.\n" + "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefix\x12g\n" + "\x13runtime_asset_paths\x18\a \x03(\v27.ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntryR\x11runtimeAssetPaths\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"C\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01J\x04\b\x04\x10\x05\"C\n" + "\x1aCheckpointWorkloadResponse\x12%\n" + - "\x0esnapshot_files\x18\x01 \x03(\tR\rsnapshotFiles\"\xc1\x03\n" + + "\x0esnapshot_files\x18\x01 \x03(\tR\rsnapshotFiles\"\xa8\x03\n" + "\x16RestoreWorkloadRequest\x128\n" + "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + - "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + - "\n" + - "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12'\n" + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12.\n" + "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefix\x12d\n" + "\x13runtime_asset_paths\x18\a \x03(\v24.ateom.RestoreWorkloadRequest.RuntimeAssetPathsEntryR\x11runtimeAssetPaths\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x19\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01J\x04\b\x04\x10\x05\"\x19\n" + "\x17RestoreWorkloadResponse2\x80\x02\n" + "\x05Ateom\x12F\n" + "\vRunWorkload\x12\x19.ateom.RunWorkloadRequest\x1a\x1a.ateom.RunWorkloadResponse\"\x00\x12[\n" + diff --git a/internal/proto/ateompb/ateom.proto b/internal/proto/ateompb/ateom.proto index b367bec78..b0e7abd3b 100644 --- a/internal/proto/ateompb/ateom.proto +++ b/internal/proto/ateompb/ateom.proto @@ -52,14 +52,14 @@ message RunWorkloadRequest { string actor_template_name = 2; string actor_id = 3; - string runsc_path = 4; + reserved 4; // was runsc_path; backends now read runtime_asset_paths instead. WorkloadSpec spec = 5; - // runtime_asset_paths maps a runtime asset name (e.g. "cloud-hypervisor", - // "virtiofsd", "kata-kernel", "kata-image", "kata-config") - // to the local on-disk path atelet fetched it to (content-addressed, like - // runsc_path). Empty for the gVisor runtime, which uses runsc_path. + // runtime_asset_paths maps a runtime asset name to the local on-disk path + // atelet fetched it to (content-addressed). Each backend reads the names it + // needs: gVisor reads "runsc"; a micro-VM backend reads "cloud-hypervisor", + // "kata-kernel", "kata-image", "kata-config"; a custom ateom-* reads its own. map runtime_asset_paths = 7; } @@ -80,7 +80,7 @@ message CheckpointWorkloadRequest { string actor_template_name = 2; string actor_id = 3; - string runsc_path = 4; + reserved 4; // was runsc_path; backends now read runtime_asset_paths instead. WorkloadSpec spec = 5; @@ -94,8 +94,8 @@ message CheckpointWorkloadRequest { // For example: "gs://bucket/actors/1234/snapshots/5678/" string snapshot_uri_prefix = 6; - // runtime_asset_paths maps a runtime asset name to the local on-disk path - // atelet fetched it to (see RunWorkloadRequest). Empty for gVisor. + // runtime_asset_paths maps a runtime asset name to its local on-disk path + // (see RunWorkloadRequest). gVisor reads "runsc". map runtime_asset_paths = 7; } @@ -111,15 +111,15 @@ message RestoreWorkloadRequest { string actor_template_name = 2; string actor_id = 3; - string runsc_path = 4; + reserved 4; // was runsc_path; backends now read runtime_asset_paths instead. WorkloadSpec spec = 5; // The object storage URI prefix of the snapshot to restore. string snapshot_uri_prefix = 6; - // runtime_asset_paths maps a runtime asset name to the local on-disk path - // atelet fetched it to (see RunWorkloadRequest). Empty for gVisor. + // runtime_asset_paths maps a runtime asset name to its local on-disk path + // (see RunWorkloadRequest). gVisor reads "runsc". map runtime_asset_paths = 7; } diff --git a/internal/resources/validate.go b/internal/resources/validate.go index 3855fe856..c28f2145e 100644 --- a/internal/resources/validate.go +++ b/internal/resources/validate.go @@ -94,19 +94,19 @@ func ValidateContainerNames(names []string) error { return nil } -// ValidateRunscHash ensures the runsc SHA-256 hash is exactly 64 hex -// characters before it is used to build the on-disk binary path -// (static-files/runsc-) and, on a cache hit, returned for ateom to -// execute. Without this, a hash containing path separators or ".." could -// point the cache-hit early return (and the download target) at an arbitrary -// binary outside the static-files dir. -func ValidateRunscHash(sha256Hash string) error { +// ValidateAssetHash ensures a content-addressed asset's SHA-256 hash is exactly +// 64 hex characters before it is used to build the on-disk cache path +// (static-files/runsc-) and, on a cache hit, returned for ateom to use. +// Without this, a hash containing path separators or ".." could point the +// cache-hit early return (and the download target) at an arbitrary file outside +// the static-files dir. +func ValidateAssetHash(sha256Hash string) error { if len(sha256Hash) != 64 { - return fmt.Errorf("invalid runsc sha256 hash: want 64 hex chars, got %d", len(sha256Hash)) + return fmt.Errorf("invalid asset sha256 hash: want 64 hex chars, got %d", len(sha256Hash)) } // Same decoder atelet's digest comparison uses. if _, err := hex.DecodeString(sha256Hash); err != nil { - return fmt.Errorf("invalid runsc sha256 hash %q: must be hex", sha256Hash) + return fmt.Errorf("invalid asset sha256 hash %q: must be hex", sha256Hash) } return nil } diff --git a/internal/resources/validate_test.go b/internal/resources/validate_test.go index a525ae15f..2d28ac5cf 100644 --- a/internal/resources/validate_test.go +++ b/internal/resources/validate_test.go @@ -111,7 +111,7 @@ func TestValidateContainerNames(t *testing.T) { } } -func TestValidateRunscHash(t *testing.T) { +func TestValidateAssetHash(t *testing.T) { const valid = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" tests := []struct { @@ -129,8 +129,8 @@ func TestValidateRunscHash(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := ValidateRunscHash(tt.hash); (err != nil) != tt.wantErr { - t.Errorf("ValidateRunscHash(%q) err = %v, wantErr %v", tt.hash, err, tt.wantErr) + if err := ValidateAssetHash(tt.hash); (err != nil) != tt.wantErr { + t.Errorf("ValidateAssetHash(%q) err = %v, wantErr %v", tt.hash, err, tt.wantErr) } }) }