From 73da8fbc6cf410529e8d521a6a41f3ce4769b92c Mon Sep 17 00:00:00 2001 From: Tedi Mitiku Date: Wed, 27 Mar 2024 16:44:15 -0400 Subject: [PATCH 1/2] impl get_files_artifact --- .../startosis_engine/kurtosis_builtins.go | 2 + .../get_files_artifact/get_files_artifact.go | 103 ++++++++++++++++++ .../api-reference/starlark-reference/plan.md | 19 ++++ 3 files changed, 124 insertions(+) create mode 100644 core/server/api_container/server/startosis_engine/kurtosis_instruction/get_files_artifact/get_files_artifact.go diff --git a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go index fff8ac7756..4224f5e5bc 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go @@ -10,6 +10,7 @@ import ( "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/interpretation_time_value_store" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_files_artifact" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_service" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/kurtosis_print" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/remove_service" @@ -70,6 +71,7 @@ func KurtosisPlanInstructions( add_service.NewAddService(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions, interpretationTimeValueStore, imageDownloadMode), add_service.NewAddServices(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions, interpretationTimeValueStore, imageDownloadMode), get_service.NewGetService(interpretationTimeValueStore), + get_files_artifact.NewGetFilesArtifact(), verify.NewVerify(runtimeValueStore), exec.NewExec(serviceNetwork, runtimeValueStore), kurtosis_print.NewPrint(serviceNetwork, runtimeValueStore), diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_files_artifact/get_files_artifact.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_files_artifact/get_files_artifact.go new file mode 100644 index 0000000000..da3b565027 --- /dev/null +++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_files_artifact/get_files_artifact.go @@ -0,0 +1,103 @@ +package get_files_artifact + +import ( + "context" + "fmt" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/enclave_plan_persistence" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/enclave_structure" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/plan_yaml" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator" + "go.starlark.net/starlark" +) + +const ( + GetFilesArtifactBuiltinName = "get_files_artifact" + FilesArtifactName = "name" + + descriptionFormatStr = "Fetching files artifact '%v'" +) + +func NewGetFilesArtifact() *kurtosis_plan_instruction.KurtosisPlanInstruction { + return &kurtosis_plan_instruction.KurtosisPlanInstruction{ + KurtosisBaseBuiltin: &kurtosis_starlark_framework.KurtosisBaseBuiltin{ + Name: GetFilesArtifactBuiltinName, + Arguments: []*builtin_argument.BuiltinArgument{ + { + Name: FilesArtifactName, + IsOptional: false, + ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String], + Validator: func(value starlark.Value) *startosis_errors.InterpretationError { + return builtin_argument.NonEmptyString(value, FilesArtifactName) + }, + }, + }, + Deprecation: nil, + }, + Capabilities: func() kurtosis_plan_instruction.KurtosisPlanInstructionCapabilities { + return &GetFilesArtifactCapabilities{ + artifactName: "", // populated at interpretation time + description: "", // populated at interpretation time + } + }, + DefaultDisplayArguments: map[string]bool{ + FilesArtifactName: true, + }, + } +} + +type GetFilesArtifactCapabilities struct { + artifactName string + description string +} + +func (builtin *GetFilesArtifactCapabilities) Interpret(_ string, arguments *builtin_argument.ArgumentValuesSet) (starlark.Value, *startosis_errors.InterpretationError) { + artifactNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, FilesArtifactName) + if err != nil { + return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", FilesArtifactName) + } + artifactName := artifactNameArgumentValue.GoString() + builtin.artifactName = artifactName + builtin.description = builtin_argument.GetDescriptionOrFallBack(arguments, fmt.Sprintf(descriptionFormatStr, builtin.artifactName)) + + // while this instruction simply returns what the input argument was, the returned starlark value can be used to set the files artifact elsewhere + return starlark.String(artifactName), nil +} + +func (builtin *GetFilesArtifactCapabilities) Validate(_ *builtin_argument.ArgumentValuesSet, validatorEnvironment *startosis_validator.ValidatorEnvironment) *startosis_errors.ValidationError { + // as long as the files artifact exists in the environment, this instruction will evaluate to the files artifact + if exists := validatorEnvironment.DoesArtifactNameExist(builtin.artifactName); exists == startosis_validator.ComponentNotFound { + return startosis_errors.NewValidationError("Files artifact '%v' required by '%v' instruction doesn't exist", builtin.artifactName, GetFilesArtifactBuiltinName) + } + return nil +} + +func (builtin *GetFilesArtifactCapabilities) Execute(_ context.Context, _ *builtin_argument.ArgumentValuesSet) (string, error) { + // Note this is a no-op + return fmt.Sprintf("Fetched files artifact '%v'", builtin.artifactName), nil +} + +func (builtin *GetFilesArtifactCapabilities) TryResolveWith(instructionsAreEqual bool, _ *enclave_plan_persistence.EnclavePlanInstruction, enclaveComponents *enclave_structure.EnclaveComponents) enclave_structure.InstructionResolutionStatus { + if instructionsAreEqual && enclaveComponents.HasFilesArtifactBeenUpdated(builtin.artifactName) { + return enclave_structure.InstructionIsUpdate + } else if instructionsAreEqual { + return enclave_structure.InstructionIsEqual + } + return enclave_structure.InstructionIsUnknown +} + +func (builtin *GetFilesArtifactCapabilities) FillPersistableAttributes(builder *enclave_plan_persistence.EnclavePlanInstructionBuilder) { + builder.SetType(GetFilesArtifactBuiltinName).AddFilesArtifact(builtin.artifactName, nil) +} + +func (builtin *GetFilesArtifactCapabilities) UpdatePlan(planYaml *plan_yaml.PlanYaml) error { + // get files artifact does not affect the planYaml + return nil +} + +func (builtin *GetFilesArtifactCapabilities) Description() string { + return builtin.description +} diff --git a/docs/docs/api-reference/starlark-reference/plan.md b/docs/docs/api-reference/starlark-reference/plan.md index decdc7a2ab..5f925bf55c 100644 --- a/docs/docs/api-reference/starlark-reference/plan.md +++ b/docs/docs/api-reference/starlark-reference/plan.md @@ -125,6 +125,25 @@ service = plan.get_service( ) ``` +get_files_artifact +----------- + +The `get_files_artifact` instruction allows you to get a [Files Artifact][files-artifacts-reference] object from a files artifact name. This is +useful in situations if you don't have access to the instruction that produced the files artifact; perhaps you are in a different function or have imported and run another Kurtosis package. + +```python +# Returns a Files Artifact object +artifact = plan.get_files_artifact( + # The name of the files artifact to get + # MANDATORY + name = "config-artifact" + + # A human friendly description for the end user of the package + # OPTIONAL (Default: Fetching service 'ARTIFACT_NAME') + description = "gets you an artifact" +) +``` + verify ------ From fe7f6cc352e5fc479e6a66ea358f0ed514f7bba8 Mon Sep 17 00:00:00 2001 From: Tedi Mitiku Date: Fri, 29 Mar 2024 10:19:54 -0400 Subject: [PATCH 2/2] servce->files artifact --- docs/docs/api-reference/starlark-reference/plan.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api-reference/starlark-reference/plan.md b/docs/docs/api-reference/starlark-reference/plan.md index 5f925bf55c..47c2bdaef0 100644 --- a/docs/docs/api-reference/starlark-reference/plan.md +++ b/docs/docs/api-reference/starlark-reference/plan.md @@ -139,7 +139,7 @@ artifact = plan.get_files_artifact( name = "config-artifact" # A human friendly description for the end user of the package - # OPTIONAL (Default: Fetching service 'ARTIFACT_NAME') + # OPTIONAL (Default: Fetching files artifact 'ARTIFACT_NAME') description = "gets you an artifact" ) ```