diff --git a/pkg/goexec/io.go b/pkg/goexec/io.go index 1ce8400..d372119 100644 --- a/pkg/goexec/io.go +++ b/pkg/goexec/io.go @@ -47,6 +47,12 @@ type UploadConfirmer interface { ConfirmUpload(ctx context.Context) error } +// UploadRemover is an optional interface that InputProvider implementations +// can satisfy to remove a previously uploaded file from the remote filesystem. +type UploadRemover interface { + RemoveUploadedFile(ctx context.Context) error +} + type ExecutionInput struct { StageFile io.ReadCloser Executable string diff --git a/pkg/goexec/method.go b/pkg/goexec/method.go index 0ab0b94..bed980e 100644 --- a/pkg/goexec/method.go +++ b/pkg/goexec/method.go @@ -138,11 +138,22 @@ func ExecuteCleanMethod(ctx context.Context, module CleanExecutionMethod, execIO } // Execute (only if a command/executable was provided) + executed := false if execIO.Input != nil && (execIO.Input.Executable != "" || execIO.Input.Command != "" || execIO.Input.ExecutablePath != "") { if err = module.Execute(ctx, execIO); err != nil { log.Error().Err(err).Msg("Execution failed") return fmt.Errorf("execute: %w", err) } + executed = true + } + + // Remove uploaded file after execution (upload+execute mode only) + if executed && execIO.Upload != nil && execIO.Upload.Provider != nil { + if remover, ok := execIO.Upload.Provider.(UploadRemover); ok { + if removeErr := remover.RemoveUploadedFile(ctx); removeErr != nil { + log.Warn().Err(removeErr).Msg("Failed to remove uploaded file") + } + } } // Module cleanup diff --git a/pkg/goexec/smb/input.go b/pkg/goexec/smb/input.go index c02bed7..fe76e33 100644 --- a/pkg/goexec/smb/input.go +++ b/pkg/goexec/smb/input.go @@ -63,6 +63,23 @@ func (o *FileStager) Upload(ctx context.Context, reader io.Reader) (err error) { return } +// RemoveUploadedFile deletes the uploaded file from the remote filesystem. +// The share must already be mounted from a prior Upload call. +func (o *FileStager) RemoveUploadedFile(ctx context.Context) error { + log := zerolog.Ctx(ctx) + + if o.Client.mount == nil { + return fmt.Errorf("share not mounted") + } + + if err := o.Client.mount.Remove(o.relativePath); err != nil { + return fmt.Errorf("remove remote file: %w", err) + } + + log.Info().Str("path", o.File).Msg("Removed uploaded file") + return nil +} + // ConfirmUpload checks that the uploaded file exists on the remote filesystem // and logs the file path and size. The share must already be mounted from a // prior Upload call.