Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ dapr run --run-file /path/to/directory -k
SchedulerHostAddress: schedulerHostAddress,
DaprdInstallPath: daprRuntimePath,
}
output, err := runExec.NewOutput(&standalone.RunConfig{
runConfig := &standalone.RunConfig{
AppID: appID,
AppChannelAddress: appChannelAddress,
AppPort: appPort,
Expand All @@ -222,7 +222,8 @@ dapr run --run-file /path/to/directory -k
UnixDomainSocket: unixDomainSocket,
InternalGRPCPort: internalGRPCPort,
SharedRunConfig: *sharedRunConfig,
})
}
output, err := runExec.NewOutput(runConfig)
if err != nil {
print.FailureStatusEvent(os.Stderr, err.Error())
os.Exit(1)
Expand Down Expand Up @@ -464,6 +465,12 @@ dapr run --run-file /path/to/directory -k
}
}

// Cleanup temporary resources directory if it was created.
err = runConfig.CleanupTempResources()
if err != nil {
print.WarningStatusEvent(os.Stdout, "Failed to cleanup temporary resources: %s", err.Error())
}

if exitWithError {
os.Exit(1)
}
Expand Down Expand Up @@ -659,6 +666,11 @@ func gracefullyShutdownAppsAndCloseResources(runState []*runExec.RunExec, apps [
if err == nil && hasErr != nil {
err = hasErr
}
// Cleanup temporary resources for each app.
hasErr = app.RunConfig.CleanupTempResources()
if err == nil && hasErr != nil {
err = hasErr
}
}
return err
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/runexec/runexec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func assertCommonArgs(t *testing.T, basicConfig *standalone.RunConfig, output *R
assert.Equal(t, 8000, output.DaprHTTPPort)
assert.Equal(t, 50001, output.DaprGRPCPort)

daprPath, err := standalone.GetDaprRuntimePath("")
_, err := standalone.GetDaprRuntimePath("")
assert.NoError(t, err)

assert.Contains(t, output.DaprCMD.Args[0], "daprd")
Expand All @@ -119,7 +119,8 @@ func assertCommonArgs(t *testing.T, basicConfig *standalone.RunConfig, output *R
assertArgumentEqual(t, "app-max-concurrency", "-1", output.DaprCMD.Args)
assertArgumentEqual(t, "app-protocol", "http", output.DaprCMD.Args)
assertArgumentEqual(t, "app-port", "3000", output.DaprCMD.Args)
assertArgumentEqual(t, "components-path", standalone.GetDaprComponentsPath(daprPath), output.DaprCMD.Args)
// Note: components-path is now a processed temporary directory with template substitution
assertArgumentContains(t, "components-path", "dapr-resources", output.DaprCMD.Args)
assertArgumentEqual(t, "app-ssl", "", output.DaprCMD.Args)
assertArgumentEqual(t, "metrics-port", "9001", output.DaprCMD.Args)
assertArgumentEqual(t, "max-body-size", "-1", output.DaprCMD.Args)
Expand Down
67 changes: 60 additions & 7 deletions pkg/standalone/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"gopkg.in/yaml.v2"

"github.com/dapr/cli/pkg/print"
"github.com/dapr/cli/pkg/templateprocessor"
localloader "github.com/dapr/dapr/pkg/components/loader"
)

Expand Down Expand Up @@ -95,6 +96,8 @@ type SharedRunConfig struct {
DaprdLogDestination LogDestType `yaml:"daprdLogDestination"`
AppLogDestination LogDestType `yaml:"appLogDestination"`
SchedulerHostAddress string `arg:"scheduler-host-address" yaml:"schedulerHostAddress"`
// Internal field to track temporary directory for processed resources. Not exposed to user.
tempResourcesDir string
}

func (meta *DaprMeta) newAppID() string {
Expand All @@ -116,11 +119,33 @@ func (config *RunConfig) validateResourcesPaths() error {
return fmt.Errorf("error validating resources path %q : %w", dirPath, err)
}
}
localLoader := localloader.NewLocalLoader(config.AppID, dirPath)
err := localLoader.Validate(context.Background())

// Process resources with environment variable substitution.
// This creates a temporary directory with processed files.
processedResources, err := templateprocessor.ProcessResourcesWithEnvVars(dirPath)
if err != nil {
return fmt.Errorf("error processing resource templates: %w", err)
}

// Store temp directory for cleanup and use processed paths for validation.
config.tempResourcesDir = processedResources.TempDir
validationPaths := processedResources.ProcessedPaths

// Validate the processed resources.
localLoader := localloader.NewLocalLoader(config.AppID, validationPaths)
err = localLoader.Validate(context.Background())
if err != nil {
return fmt.Errorf("error validating components in resources path %q : %w", dirPath, err)
}

// Update ResourcesPaths to point to processed resources.
// This ensures daprd uses the processed files with substituted values.
if len(config.ResourcesPaths) > 0 {
config.ResourcesPaths = processedResources.ProcessedPaths
} else {
config.ComponentsPath = processedResources.ProcessedPaths[0]
}

return nil
}

Expand Down Expand Up @@ -380,8 +405,12 @@ func (config *RunConfig) getArgs() []string {
// This is needed because the config struct has embedded struct.
func getArgsFromSchema(schema reflect.Value, args []string) []string {
for i := range schema.NumField() {
valueField := schema.Field(i).Interface()
typeField := schema.Type().Field(i)
// Skip unexported fields.
if !typeField.IsExported() {
continue
}
valueField := schema.Field(i).Interface()
key := typeField.Tag.Get("arg")
if typeField.Type.Kind() == reflect.Struct {
args = getArgsFromSchema(schema.Field(i), args)
Expand Down Expand Up @@ -422,8 +451,12 @@ func (config *RunConfig) SetDefaultFromSchema() {

func (config *RunConfig) setDefaultFromSchemaRecursive(schema reflect.Value) {
for i := range schema.NumField() {
valueField := schema.Field(i)
typeField := schema.Type().Field(i)
// Skip unexported fields.
if !typeField.IsExported() {
continue
}
valueField := schema.Field(i)
if typeField.Type.Kind() == reflect.Struct {
config.setDefaultFromSchemaRecursive(valueField)
continue
Expand All @@ -448,8 +481,12 @@ func (config *RunConfig) getEnv() []string {
// Handle values from config that have an "env" tag.
schema := reflect.ValueOf(*config)
for i := range schema.NumField() {
valueField := schema.Field(i).Interface()
typeField := schema.Type().Field(i)
// Skip unexported fields.
if !typeField.IsExported() {
continue
}
valueField := schema.Field(i).Interface()
key := typeField.Tag.Get("env")
if len(key) == 0 {
continue
Expand Down Expand Up @@ -508,8 +545,12 @@ func (config *RunConfig) GetEnv() map[string]string {
env := map[string]string{}
schema := reflect.ValueOf(*config)
for i := range schema.NumField() {
valueField := schema.Field(i).Interface()
typeField := schema.Type().Field(i)
// Skip unexported fields.
if !typeField.IsExported() {
continue
}
valueField := schema.Field(i).Interface()
key := typeField.Tag.Get("env")
if len(key) == 0 {
continue
Expand All @@ -532,8 +573,12 @@ func (config *RunConfig) GetAnnotations() map[string]string {
annotations := map[string]string{}
schema := reflect.ValueOf(*config)
for i := range schema.NumField() {
valueField := schema.Field(i).Interface()
typeField := schema.Type().Field(i)
// Skip unexported fields.
if !typeField.IsExported() {
continue
}
valueField := schema.Field(i).Interface()
key := typeField.Tag.Get("annotation")
if len(key) == 0 {
continue
Expand Down Expand Up @@ -612,3 +657,11 @@ func (l LogDestType) IsValid() error {
}
return fmt.Errorf("invalid log destination type: %s", l)
}

// CleanupTempResources removes the temporary directory created for processed resources.
func (config *RunConfig) CleanupTempResources() error {
if config.tempResourcesDir == "" {
return nil
}
return templateprocessor.Cleanup(config.tempResourcesDir)
}
Loading
Loading