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 4d5d6041d..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.AddArgs(argsResolved...) + if p.prependArgs { + out.PrependArgs(argsResolved...) + } else { + out.AddArgs(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{