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
34 changes: 24 additions & 10 deletions add.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/containers/buildah/define"
"github.com/containers/buildah/internal/tmpdir"
"github.com/containers/buildah/pkg/chrootuser"
"github.com/containers/buildah/pkg/download"
"github.com/docker/go-connections/tlsconfig"
"github.com/hashicorp/go-multierror"
"github.com/moby/sys/userns"
Expand Down Expand Up @@ -90,6 +91,10 @@ type AddAndCopyOptions struct {
CertPath string
// Allow downloading sources from HTTPS where TLS verification fails.
InsecureSkipTLSVerify types.OptionalBool
// If not nil, may contain TLS _algorithm_ options (e.g. TLS version, cipher suites, “curves”, etc.)
// The effect of setting any other options (cryptographic keys, InsecureSkipTLSVerify, callbacks, etc.) is UNDEFINED,
// may be inconsistent in various use cases, and may change over time.
BaseTLSConfig *tls.Config
// MaxRetries is the maximum number of attempts we'll make to retrieve
// contents from a remote location.
MaxRetries int
Expand Down Expand Up @@ -138,18 +143,27 @@ func sourceIsRemote(source string) bool {
}

// getURL writes a tar archive containing the named content
func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, writer io.Writer, chmod *os.FileMode, srcDigest digest.Digest, certPath string, insecureSkipTLSVerify types.OptionalBool, timestamp *time.Time) error {
//
// baseTLSConfig, if not nil, may contain TLS _algorithm_ options (e.g. TLS version, cipher suites, “curves”, etc.)
// The effect of setting any other options (cryptographic keys, InsecureSkipTLSVerify, callbacks, etc.) is UNDEFINED,
// may be inconsistent in various use cases, and may change over time.
func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, writer io.Writer, chmod *os.FileMode, srcDigest digest.Digest, certPath string, insecureSkipTLSVerify types.OptionalBool, baseTLSConfig *tls.Config, timestamp *time.Time) error {
url, err := url.Parse(src)
if err != nil {
return err
}
tlsClientConfig := &tls.Config{
// As of 2025-08, tlsconfig.ClientDefault() differs from Go 1.23 defaults only in CipherSuites;
// so, limit us to only using that value. If go-connections/tlsconfig changes its policy, we
// will want to consider that and make a decision whether to follow suit.
// There is some chance that eventually the Go default will be to require TLS 1.3, and that point
// we might want to drop the dependency on go-connections entirely.
CipherSuites: tlsconfig.ClientDefault().CipherSuites,
var tlsClientConfig *tls.Config
if baseTLSConfig != nil {
tlsClientConfig = baseTLSConfig.Clone()
} else {
tlsClientConfig = &tls.Config{
// As of 2025-08, tlsconfig.ClientDefault() differs from Go 1.23 defaults only in CipherSuites;
// so, limit us to only using that value. If go-connections/tlsconfig changes its policy, we
// will want to consider that and make a decision whether to follow suit.
// There is some chance that eventually the Go default will be to require TLS 1.3, and that point
// we might want to drop the dependency on go-connections entirely.
CipherSuites: tlsconfig.ClientDefault().CipherSuites,
}
}
if err := tlsclientconfig.SetupCertificates(certPath, tlsClientConfig); err != nil {
return err
Expand Down Expand Up @@ -605,7 +619,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
defer wg.Done()
defer pipeWriter.Close()
var cloneDir, subdir string
cloneDir, subdir, getErr = define.TempDirForURL(tmpdir.GetTempDir(), "", src)
cloneDir, subdir, getErr = download.TempDirForURL(tmpdir.GetTempDir(), "", src, options.BaseTLSConfig)
if getErr != nil {
return
}
Expand All @@ -630,7 +644,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
} else {
go func() {
getErr = retry.IfNecessary(context.TODO(), func() error {
return getURL(src, chownFiles, mountPoint, renameTarget, pipeWriter, chmodDirsFiles, srcDigest, options.CertPath, options.InsecureSkipTLSVerify, options.Timestamp)
return getURL(src, chownFiles, mountPoint, renameTarget, pipeWriter, chmodDirsFiles, srcDigest, options.CertPath, options.InsecureSkipTLSVerify, options.BaseTLSConfig, options.Timestamp)
}, &retry.Options{
MaxRetry: options.MaxRetries,
Delay: options.RetryDelay,
Expand Down
3 changes: 3 additions & 0 deletions cmd/buildah/addcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type addCopyResults struct {
signaturePolicy string
authfile string
creds string
tlsDetails string
tlsVerify bool
certDir string
retry int
Expand Down Expand Up @@ -90,6 +91,7 @@ func applyFlagVars(flags *pflag.FlagSet, opts *addCopyResults) {
flags.IntVar(&opts.retry, "retry", cli.MaxPullPushRetries, "number of times to retry in case of failure when performing pull")
flags.StringVar(&opts.retryDelay, "retry-delay", cli.PullPushRetryDelay.String(), "delay between retries in case of pull failures")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output a digest of the newly-added/copied content")
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing registries when pulling images, and when retrieving sources from HTTPS URLs. TLS verification cannot be used when talking to an insecure registry.")
flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pulling image")
if err := flags.MarkHidden("remove-signatures"); err != nil {
Expand Down Expand Up @@ -262,6 +264,7 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe
// with more generic-sounding names.
CertPath: systemContext.DockerCertPath,
InsecureSkipTLSVerify: systemContext.DockerInsecureSkipTLSVerify,
BaseTLSConfig: systemContext.BaseTLSConfig,
MaxRetries: iopts.retry,
Parents: iopts.parents,
Timestamp: timestamp,
Expand Down
2 changes: 2 additions & 0 deletions cmd/buildah/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type commitInputOptions struct {
signaturePolicy string
signBy string
squash bool
tlsDetails string
tlsVerify bool
identityLabel bool
encryptionKeys []string
Expand Down Expand Up @@ -190,6 +191,7 @@ func commitListFlagSet(cmd *cobra.Command, opts *commitInputOptions) {
}

flags.BoolVar(&opts.squash, "squash", false, "produce an image with only one layer")
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")

flags.StringSliceVar(&opts.unsetenvs, "unsetenv", nil, "unset env from final image")
Expand Down
11 changes: 7 additions & 4 deletions cmd/buildah/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"go.podman.io/common/pkg/auth"
"go.podman.io/image/v5/types"
)

type fromReply struct {
Expand All @@ -28,6 +29,7 @@ type fromReply struct {
pullNever bool
quiet bool
signaturePolicy string
tlsDetails string
tlsVerify bool
*cli.FromAndBudResults
*cli.UserNSResults
Expand Down Expand Up @@ -95,6 +97,7 @@ newer: only pull images when newer images exist on the registry than those in th
if err := flags.MarkHidden("signature-policy"); err != nil {
panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
}
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")

// Add in the common flags
Expand All @@ -109,7 +112,7 @@ newer: only pull images when newer images exist on the registry than those in th
rootCmd.AddCommand(fromCommand)
}

func onBuild(builder *buildah.Builder, quiet bool) error {
func onBuild(builder *buildah.Builder, systemContext *types.SystemContext, quiet bool) error {
ctr := 0
for _, onBuildSpec := range builder.OnBuild() {
ctr = ctr + 1
Expand All @@ -128,7 +131,7 @@ func onBuild(builder *buildah.Builder, quiet bool) error {
dest = args[size-1]
args = args[:size-1]
}
if err := builder.Add(dest, command == "ADD", buildah.AddAndCopyOptions{}, args...); err != nil {
if err := builder.Add(dest, command == "ADD", buildah.AddAndCopyOptions{BaseTLSConfig: systemContext.BaseTLSConfig}, args...); err != nil {
return err
}
case "ANNOTATION":
Expand Down Expand Up @@ -169,7 +172,7 @@ func onBuild(builder *buildah.Builder, quiet bool) error {
if quiet {
stdout = io.Discard
}
if err := builder.Run(args, buildah.RunOptions{Stdout: stdout}); err != nil {
if err := builder.Run(args, buildah.RunOptions{Stdout: stdout, SystemContext: systemContext}); err != nil {
return err
}
case "SHELL":
Expand Down Expand Up @@ -304,7 +307,7 @@ func fromCmd(c *cobra.Command, args []string, iopts fromReply) error {
return err
}

if err := onBuild(builder, iopts.quiet); err != nil {
if err := onBuild(builder, systemContext, iopts.quiet); err != nil {
return err
}

Expand Down
21 changes: 12 additions & 9 deletions cmd/buildah/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ type imageOutputParams struct {
}

type imageOptions struct {
all bool
digests bool
format string
json bool
noHeading bool
truncate bool
quiet bool
readOnly bool
history bool
all bool
digests bool
format string
json bool
noHeading bool
tlsDetails string
truncate bool
quiet bool
readOnly bool
history bool
}

type imageResults struct {
Expand Down Expand Up @@ -99,7 +100,9 @@ func imagesInit() {
flags.BoolVarP(&opts.noHeading, "noheading", "n", false, "do not print column headings")
// TODO needs alias here -- to `notruncate`
flags.BoolVar(&opts.truncate, "no-trunc", false, "do not truncate output")
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "display only image IDs")
// No --tls-details option because this really shouldn’t contact external servers.
flags.BoolVarP(&opts.history, "history", "", false, "display the image name history")

rootCmd.AddCommand(imagesCommand)
Expand Down
2 changes: 2 additions & 0 deletions cmd/buildah/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
type inspectResults struct {
format string
inspectType string
tlsDetails string
}

func inspectInit() {
Expand All @@ -49,6 +50,7 @@ func inspectInit() {
flags.SetInterspersed(false)
flags.StringVarP(&opts.format, "format", "f", "", "use `format` as a Go template to format the output")
flags.StringVarP(&opts.inspectType, "type", "t", inspectTypeContainer, "look at the item of the specified `type` (container or image) and name")
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")

rootCmd.AddCommand(inspectCommand)
}
Expand Down
8 changes: 5 additions & 3 deletions cmd/buildah/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

type loginReply struct {
loginOpts auth.LoginOptions
getLogin bool
tlsVerify bool
loginOpts auth.LoginOptions
getLogin bool
tlsDetails string
tlsVerify bool
}

func loginInit() {
Expand All @@ -39,6 +40,7 @@ func loginInit() {
loginCommand.SetUsageTemplate(UsageTemplate())

flags := loginCommand.Flags()
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")
flags.BoolVar(&opts.getLogin, "get-login", true, "return the current login user for the registry")
flags.AddFlagSet(auth.GetLoginFlags(&opts.loginOpts))
Expand Down
27 changes: 18 additions & 9 deletions cmd/buildah/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ import (
"go.podman.io/common/pkg/auth"
)

type logoutOptions struct {
logoutOpts auth.LogoutOptions
tlsDetails string
}

func logoutInit() {
var (
opts = auth.LogoutOptions{
Stdout: os.Stdout,
AcceptRepositories: true,
opts = logoutOptions{
logoutOpts: auth.LogoutOptions{
Stdout: os.Stdout,
AcceptRepositories: true,
},
}
logoutDescription = "Remove the cached username and password for the registry."
)
Expand All @@ -29,17 +36,19 @@ func logoutInit() {
}
logoutCommand.SetUsageTemplate(UsageTemplate())

flags := auth.GetLogoutFlags(&opts)
flags.SetInterspersed(false)
logoutCommand.Flags().AddFlagSet(flags)
flags := logoutCommand.Flags()
flags.StringVar(&opts.tlsDetails, "tls-details", "", "path to a containers-tls-details.yaml file")
logoutFlags := auth.GetLogoutFlags(&opts.logoutOpts)
logoutFlags.SetInterspersed(false)
flags.AddFlagSet(logoutFlags)
rootCmd.AddCommand(logoutCommand)
}

func logoutCmd(c *cobra.Command, args []string, iopts *auth.LogoutOptions) error {
func logoutCmd(c *cobra.Command, args []string, opts *logoutOptions) error {
if len(args) > 1 {
return errors.New("too many arguments, logout takes at most 1 argument")
}
if len(args) == 0 && !iopts.All {
if len(args) == 0 && !opts.logoutOpts.All {
return errors.New("registry must be given")
}

Expand All @@ -55,5 +64,5 @@ func logoutCmd(c *cobra.Command, args []string, iopts *auth.LogoutOptions) error
// that’s fair enough for reads, but incorrect for writes (the two files have incompatible formats),
// and it interferes with the auth.Logout’s own argument parsing.
systemContext.AuthFilePath = ""
return auth.Logout(systemContext, iopts, args)
return auth.Logout(systemContext, &opts.logoutOpts, args)
}
Loading
Loading