From 66899fafdd7d0c165affbdc0b319efc88466848d Mon Sep 17 00:00:00 2001 From: Damon Buckwalter Date: Thu, 30 Nov 2023 12:41:47 -0800 Subject: [PATCH 1/2] Prepend arg for defaults-file --- sdk/provision/file_provisioner.go | 2 +- sdk/provisioner.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sdk/provision/file_provisioner.go b/sdk/provision/file_provisioner.go index 4d5d6041d..ce24d898b 100644 --- a/sdk/provision/file_provisioner.go +++ b/sdk/provision/file_provisioner.go @@ -159,7 +159,7 @@ func (p FileProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, o argsResolved[i] = result.String() } - out.AddArgs(argsResolved...) + out.PrependArgs(argsResolved...) } } diff --git a/sdk/provisioner.go b/sdk/provisioner.go index 99883ffae..e3be7cc17 100644 --- a/sdk/provisioner.go +++ b/sdk/provisioner.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "path/filepath" + "slices" "time" ) @@ -107,6 +108,11 @@ func (out *ProvisionOutput) AddArgs(args ...string) { out.CommandLine = append(out.CommandLine, args...) } +// PrependArgs can be used to insert additional arguments at the beginning of the command line of the provision output. +func (out *ProvisionOutput) PrependArgs(args ...string) { + out.CommandLine = slices.Insert(out.CommandLine, 1, args...) +} + // AddSecretFile can be used to add a file containing secrets to the provision output. func (out *ProvisionOutput) AddSecretFile(path string, contents []byte) { out.AddFile(path, OutputFile{ From 12888bbf38582ff126a9590dfcc99bc5dd783627 Mon Sep 17 00:00:00 2001 From: Mordy Tikotzky Date: Thu, 29 Jan 2026 13:39:30 -0500 Subject: [PATCH 2/2] Make PrependArgs opt-in for MySQL only Add a PrependArgs FileOption that allows specific plugins to opt into prepending arguments instead of appending. This preserves the default AddArgs behavior for all other plugins while allowing MySQL to place --defaults-file first as required by the mysql CLI. --- plugins/mysql/database_credentials.go | 2 +- sdk/provision/file_provisioner.go | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/mysql/database_credentials.go b/plugins/mysql/database_credentials.go index 432d7c38e..4101af58d 100644 --- a/plugins/mysql/database_credentials.go +++ b/plugins/mysql/database_credentials.go @@ -43,7 +43,7 @@ func DatabaseCredentials() schema.CredentialType { Optional: true, }, }, - DefaultProvisioner: provision.TempFile(mysqlConfig, provision.Filename("my.cnf"), provision.AddArgs("--defaults-file={{ .Path }}")), + DefaultProvisioner: provision.TempFile(mysqlConfig, provision.Filename("my.cnf"), provision.PrependArgs("--defaults-file={{ .Path }}")), Importer: importer.TryAll( TryMySQLConfigFile("/etc/my.cnf"), TryMySQLConfigFile("/etc/mysql/my.cnf"), diff --git a/sdk/provision/file_provisioner.go b/sdk/provision/file_provisioner.go index ce24d898b..748d7682b 100644 --- a/sdk/provision/file_provisioner.go +++ b/sdk/provision/file_provisioner.go @@ -21,6 +21,7 @@ type FileProvisioner struct { outpathEnvVar string outdirEnvVar string setOutpathAsArg bool + prependArgs bool outpathArgTemplates []string } @@ -95,6 +96,19 @@ func AddArgs(argTemplates ...string) FileOption { } } +// PrependArgs can be used to prepend args to the command line, placing them before any user-provided arguments. +// This is useful for CLIs like mysql that require certain arguments (e.g., --defaults-file) to be the very first argument. +// The output path is available as "{{ .Path }}" in each arg. +// For example: +// * `PrependArgs("--defaults-file={{ .Path }}")` will result in `--defaults-file=/path/to/tempfile` being placed first. +func PrependArgs(argTemplates ...string) FileOption { + return func(p *FileProvisioner) { + p.setOutpathAsArg = true + p.prependArgs = true + p.outpathArgTemplates = argTemplates + } +} + func (p FileProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, out *sdk.ProvisionOutput) { contents, err := p.fileContents(in) if err != nil { @@ -159,7 +173,11 @@ func (p FileProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, o argsResolved[i] = result.String() } - out.PrependArgs(argsResolved...) + if p.prependArgs { + out.PrependArgs(argsResolved...) + } else { + out.AddArgs(argsResolved...) + } } }