mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	This reverts commit b195b80ddf.
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
		
	
		
			
				
	
	
		
			163 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package confutil
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/rand"
 | 
						|
	"encoding/hex"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"sync"
 | 
						|
 | 
						|
	"github.com/docker/cli/cli/command"
 | 
						|
	"github.com/docker/docker/pkg/ioutils"
 | 
						|
	"github.com/moby/buildkit/cmd/buildkitd/config"
 | 
						|
	"github.com/pelletier/go-toml"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	fs "github.com/tonistiigi/fsutil/copy"
 | 
						|
)
 | 
						|
 | 
						|
const defaultBuildKitConfigFile = "buildkitd.default.toml"
 | 
						|
 | 
						|
type Config struct {
 | 
						|
	dir     string
 | 
						|
	chowner *chowner
 | 
						|
}
 | 
						|
 | 
						|
type chowner struct {
 | 
						|
	uid int
 | 
						|
	gid int
 | 
						|
}
 | 
						|
 | 
						|
type ConfigOption func(*configOptions)
 | 
						|
 | 
						|
type configOptions struct {
 | 
						|
	dir string
 | 
						|
}
 | 
						|
 | 
						|
func WithDir(dir string) ConfigOption {
 | 
						|
	return func(o *configOptions) {
 | 
						|
		o.dir = dir
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func NewConfig(dockerCli command.Cli, opts ...ConfigOption) *Config {
 | 
						|
	co := configOptions{}
 | 
						|
	for _, opt := range opts {
 | 
						|
		opt(&co)
 | 
						|
	}
 | 
						|
 | 
						|
	configDir := co.dir
 | 
						|
	if configDir == "" {
 | 
						|
		configDir = os.Getenv("BUILDX_CONFIG")
 | 
						|
		if configDir == "" {
 | 
						|
			configDir = filepath.Join(filepath.Dir(dockerCli.ConfigFile().Filename), "buildx")
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return &Config{
 | 
						|
		dir:     configDir,
 | 
						|
		chowner: sudoer(configDir),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Dir will look for correct configuration store path;
 | 
						|
// if `$BUILDX_CONFIG` is set - use it, otherwise use parent directory
 | 
						|
// of Docker config file (i.e. `${DOCKER_CONFIG}/buildx`)
 | 
						|
func (c *Config) Dir() string {
 | 
						|
	return c.dir
 | 
						|
}
 | 
						|
 | 
						|
// BuildKitConfigFile returns the default BuildKit configuration file path
 | 
						|
func (c *Config) BuildKitConfigFile() (string, bool) {
 | 
						|
	f := filepath.Join(c.dir, defaultBuildKitConfigFile)
 | 
						|
	if _, err := os.Stat(f); err == nil {
 | 
						|
		return f, true
 | 
						|
	}
 | 
						|
	return "", false
 | 
						|
}
 | 
						|
 | 
						|
// MkdirAll creates a directory and all necessary parents within the config dir.
 | 
						|
func (c *Config) MkdirAll(dir string, perm os.FileMode) error {
 | 
						|
	var chown fs.Chowner
 | 
						|
	if c.chowner != nil {
 | 
						|
		chown = func(user *fs.User) (*fs.User, error) {
 | 
						|
			return &fs.User{UID: c.chowner.uid, GID: c.chowner.gid}, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	d := filepath.Join(c.dir, dir)
 | 
						|
	st, err := os.Stat(d)
 | 
						|
	if err != nil {
 | 
						|
		if os.IsNotExist(err) {
 | 
						|
			_, err := fs.MkdirAll(d, perm, chown, nil)
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	// if directory already exists, fix the owner if necessary
 | 
						|
	if c.chowner == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	currentOwner := fileOwner(st)
 | 
						|
	if currentOwner != nil && (currentOwner.uid != c.chowner.uid || currentOwner.gid != c.chowner.gid) {
 | 
						|
		return os.Chown(d, c.chowner.uid, c.chowner.gid)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// AtomicWriteFile writes data to a file within the config dir atomically
 | 
						|
func (c *Config) AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
 | 
						|
	f := filepath.Join(c.dir, filename)
 | 
						|
	if err := ioutils.AtomicWriteFile(f, data, perm); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if c.chowner == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return os.Chown(f, c.chowner.uid, c.chowner.gid)
 | 
						|
}
 | 
						|
 | 
						|
var nodeIdentifierMu sync.Mutex
 | 
						|
 | 
						|
func (c *Config) TryNodeIdentifier() (out string) {
 | 
						|
	nodeIdentifierMu.Lock()
 | 
						|
	defer nodeIdentifierMu.Unlock()
 | 
						|
	sessionFilename := ".buildNodeID"
 | 
						|
	sessionFilepath := filepath.Join(c.Dir(), sessionFilename)
 | 
						|
	if _, err := os.Lstat(sessionFilepath); err != nil {
 | 
						|
		if os.IsNotExist(err) { // create a new file with stored randomness
 | 
						|
			b := make([]byte, 8)
 | 
						|
			if _, err := rand.Read(b); err != nil {
 | 
						|
				return out
 | 
						|
			}
 | 
						|
			if err := c.AtomicWriteFile(sessionFilename, []byte(hex.EncodeToString(b)), 0600); err != nil {
 | 
						|
				return out
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	dt, err := os.ReadFile(sessionFilepath)
 | 
						|
	if err == nil {
 | 
						|
		return string(dt)
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// LoadConfigTree loads BuildKit config toml tree
 | 
						|
func LoadConfigTree(fp string) (*toml.Tree, error) {
 | 
						|
	f, err := os.Open(fp)
 | 
						|
	if err != nil {
 | 
						|
		if errors.Is(err, os.ErrNotExist) {
 | 
						|
			return nil, nil
 | 
						|
		}
 | 
						|
		return nil, errors.Wrapf(err, "failed to load config from %s", fp)
 | 
						|
	}
 | 
						|
	defer f.Close()
 | 
						|
	t, err := toml.LoadReader(f)
 | 
						|
	if err != nil {
 | 
						|
		return t, errors.Wrap(err, "failed to parse buildkit config")
 | 
						|
	}
 | 
						|
	var bkcfg config.Config
 | 
						|
	if err = t.Unmarshal(&bkcfg); err != nil {
 | 
						|
		return t, errors.Wrap(err, "failed to parse buildkit config")
 | 
						|
	}
 | 
						|
	return t, nil
 | 
						|
}
 |