mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package confutil
 | 
						|
 | 
						|
import (
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"path"
 | 
						|
 | 
						|
	"github.com/pelletier/go-toml"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	// DefaultBuildKitStateDir and DefaultBuildKitConfigDir are the location
 | 
						|
	// where buildkitd inside the container stores its state. Some drivers
 | 
						|
	// create a Linux container, so this should match the location for Linux,
 | 
						|
	// as defined in: https://github.com/moby/buildkit/blob/v0.9.0/util/appdefaults/appdefaults_unix.go#L11-L15
 | 
						|
	DefaultBuildKitStateDir  = "/var/lib/buildkit"
 | 
						|
	DefaultBuildKitConfigDir = "/etc/buildkit"
 | 
						|
)
 | 
						|
 | 
						|
// LoadConfigFiles creates a temp directory with BuildKit config and
 | 
						|
// registry certificates ready to be copied to a container.
 | 
						|
func LoadConfigFiles(bkconfig string) (string, error) {
 | 
						|
	if _, err := os.Stat(bkconfig); errors.Is(err, os.ErrNotExist) {
 | 
						|
		return "", errors.Wrapf(err, "buildkit configuration file not found: %s", bkconfig)
 | 
						|
	} else if err != nil {
 | 
						|
		return "", errors.Wrapf(err, "invalid buildkit configuration file: %s", bkconfig)
 | 
						|
	}
 | 
						|
 | 
						|
	// Load config tree
 | 
						|
	btoml, err := loadConfigTree(bkconfig)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	// Temp dir that will be copied to the container
 | 
						|
	tmpDir, err := os.MkdirTemp("", "buildkitd-config")
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	// Create BuildKit config folders
 | 
						|
	tmpBuildKitConfigDir := path.Join(tmpDir, DefaultBuildKitConfigDir)
 | 
						|
	tmpBuildKitCertsDir := path.Join(tmpBuildKitConfigDir, "certs")
 | 
						|
	if err := os.MkdirAll(tmpBuildKitCertsDir, 0700); err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	// Iterate through registry config to copy certs and update
 | 
						|
	// BuildKit config with the underlying certs' path in the container.
 | 
						|
	//
 | 
						|
	// The following BuildKit config:
 | 
						|
	//
 | 
						|
	// [registry."myregistry.io"]
 | 
						|
	//   ca=["/etc/config/myca.pem"]
 | 
						|
	//   [[registry."myregistry.io".keypair]]
 | 
						|
	//     key="/etc/config/key.pem"
 | 
						|
	//     cert="/etc/config/cert.pem"
 | 
						|
	//
 | 
						|
	// will be translated in the container as:
 | 
						|
	//
 | 
						|
	// [registry."myregistry.io"]
 | 
						|
	//   ca=["/etc/buildkit/certs/myregistry.io/myca.pem"]
 | 
						|
	//   [[registry."myregistry.io".keypair]]
 | 
						|
	//     key="/etc/buildkit/certs/myregistry.io/key.pem"
 | 
						|
	//     cert="/etc/buildkit/certs/myregistry.io/cert.pem"
 | 
						|
	if btoml.Has("registry") {
 | 
						|
		for regName := range btoml.GetArray("registry").(*toml.Tree).Values() {
 | 
						|
			regConf := btoml.GetPath([]string{"registry", regName}).(*toml.Tree)
 | 
						|
			if regConf == nil {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			regCertsDir := path.Join(tmpBuildKitCertsDir, regName)
 | 
						|
			if err := os.Mkdir(regCertsDir, 0755); err != nil {
 | 
						|
				return "", err
 | 
						|
			}
 | 
						|
			if regConf.Has("ca") {
 | 
						|
				regCAs := regConf.GetArray("ca").([]string)
 | 
						|
				if len(regCAs) > 0 {
 | 
						|
					var cas []string
 | 
						|
					for _, ca := range regCAs {
 | 
						|
						cas = append(cas, path.Join(DefaultBuildKitConfigDir, "certs", regName, path.Base(ca)))
 | 
						|
						if err := copyfile(ca, path.Join(regCertsDir, path.Base(ca))); err != nil {
 | 
						|
							return "", err
 | 
						|
						}
 | 
						|
					}
 | 
						|
					regConf.Set("ca", cas)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if regConf.Has("keypair") {
 | 
						|
				regKeyPairs := regConf.GetArray("keypair").([]*toml.Tree)
 | 
						|
				if len(regKeyPairs) == 0 {
 | 
						|
					continue
 | 
						|
				}
 | 
						|
				for _, kp := range regKeyPairs {
 | 
						|
					if kp == nil {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					key := kp.Get("key").(string)
 | 
						|
					if len(key) > 0 {
 | 
						|
						kp.Set("key", path.Join(DefaultBuildKitConfigDir, "certs", regName, path.Base(key)))
 | 
						|
						if err := copyfile(key, path.Join(regCertsDir, path.Base(key))); err != nil {
 | 
						|
							return "", err
 | 
						|
						}
 | 
						|
					}
 | 
						|
					cert := kp.Get("cert").(string)
 | 
						|
					if len(cert) > 0 {
 | 
						|
						kp.Set("cert", path.Join(DefaultBuildKitConfigDir, "certs", regName, path.Base(cert)))
 | 
						|
						if err := copyfile(cert, path.Join(regCertsDir, path.Base(cert))); err != nil {
 | 
						|
							return "", err
 | 
						|
						}
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Write BuildKit config
 | 
						|
	bkfile, err := os.OpenFile(path.Join(tmpBuildKitConfigDir, "buildkitd.toml"), os.O_CREATE|os.O_WRONLY, 0600)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	_, err = btoml.WriteTo(bkfile)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	return tmpDir, nil
 | 
						|
}
 | 
						|
 | 
						|
func copyfile(src string, dst string) error {
 | 
						|
	sf, err := os.Open(src)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	defer sf.Close()
 | 
						|
	df, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, 0600)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	defer df.Close()
 | 
						|
	_, err = io.Copy(df, sf)
 | 
						|
	return err
 | 
						|
}
 |