Run runs the envbuilder. Logger is the logf to use for all operations. Filesystem is the filesystem to use for all operations. Defaults to the host filesystem. preExec are any functions that should be called before exec'ing the init command. This is useful for ensuring that defers get run.
(ctx context.Context, opts options.Options, preExec ...func())
| 87 | // preExec are any functions that should be called before exec'ing the init |
| 88 | // command. This is useful for ensuring that defers get run. |
| 89 | func Run(ctx context.Context, opts options.Options, preExec ...func()) error { |
| 90 | var args execArgsInfo |
| 91 | // Run in a separate function to ensure all defers run before we |
| 92 | // setuid or exec. |
| 93 | err := run(ctx, opts, &args) |
| 94 | if err != nil { |
| 95 | return err |
| 96 | } |
| 97 | |
| 98 | err = syscall.Setgid(args.UserInfo.gid) |
| 99 | if err != nil { |
| 100 | return fmt.Errorf("set gid: %w", err) |
| 101 | } |
| 102 | err = syscall.Setuid(args.UserInfo.uid) |
| 103 | if err != nil { |
| 104 | return fmt.Errorf("set uid: %w", err) |
| 105 | } |
| 106 | |
| 107 | opts.Logger(log.LevelInfo, "=== Running init command as user %q: %q", args.UserInfo.user.Username, append([]string{opts.InitCommand}, args.InitArgs...)) |
| 108 | for _, fn := range preExec { |
| 109 | fn() |
| 110 | } |
| 111 | |
| 112 | err = syscall.Exec(args.InitCommand, append([]string{args.InitCommand}, args.InitArgs...), args.Environ) |
| 113 | if err != nil { |
| 114 | return fmt.Errorf("exec init script: %w", err) |
| 115 | } |
| 116 | |
| 117 | return errors.New("exec failed") |
| 118 | } |
| 119 | |
| 120 | func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) error { |
| 121 | defer options.UnsetEnv() |