|
|
|
@ -53,6 +53,8 @@ func NewState(o Output) State {
|
|
|
|
|
// States are immutable, and all operations return a new state linked to the previous one.
|
|
|
|
|
// State is the core type of the LLB API and is used to build a graph of operations.
|
|
|
|
|
// The graph is then marshaled into a definition that can be executed by a backend (such as buildkitd).
|
|
|
|
|
//
|
|
|
|
|
// Operations performed on a State are executed lazily after the entire state graph is marshalled and sent to the backend.
|
|
|
|
|
type State struct {
|
|
|
|
|
out Output
|
|
|
|
|
prev *State
|
|
|
|
@ -127,6 +129,7 @@ func (s State) SetMarshalDefaults(co ...ConstraintsOpt) State {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Marshal marshals the state and all its parents into a [Definition].
|
|
|
|
|
func (s State) Marshal(ctx context.Context, co ...ConstraintsOpt) (*Definition, error) {
|
|
|
|
|
c := NewConstraints(append(s.opts, co...)...)
|
|
|
|
|
def := &Definition{
|
|
|
|
@ -212,10 +215,13 @@ func marshal(ctx context.Context, v Vertex, def *Definition, s *sourceMapCollect
|
|
|
|
|
return def, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate validates the state.
|
|
|
|
|
// This validation, unlike most other operations on [State], is not lazily performed.
|
|
|
|
|
func (s State) Validate(ctx context.Context, c *Constraints) error {
|
|
|
|
|
return s.Output().Vertex(ctx, c).Validate(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Output returns the output of the state.
|
|
|
|
|
func (s State) Output() Output {
|
|
|
|
|
if s.async != nil {
|
|
|
|
|
return s.async.Output()
|
|
|
|
@ -223,6 +229,7 @@ func (s State) Output() Output {
|
|
|
|
|
return s.out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WithOutput creats a new state with the output set to the given output.
|
|
|
|
|
func (s State) WithOutput(o Output) State {
|
|
|
|
|
prev := s
|
|
|
|
|
s = State{
|
|
|
|
@ -233,6 +240,7 @@ func (s State) WithOutput(o Output) State {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WithImageConfig adds the environment variables, working directory, and platform specified in the image config to the state.
|
|
|
|
|
func (s State) WithImageConfig(c []byte) (State, error) {
|
|
|
|
|
var img ocispecs.Image
|
|
|
|
|
if err := json.Unmarshal(c, &img); err != nil {
|
|
|
|
@ -259,6 +267,12 @@ func (s State) WithImageConfig(c []byte) (State, error) {
|
|
|
|
|
return s, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Run performs the command specified by the arguments within the contexst of the current [State].
|
|
|
|
|
// The command is executed as a container with the [State]'s filesystem as the root filesystem.
|
|
|
|
|
// As such any command you run must be present in the [State]'s filesystem.
|
|
|
|
|
// Constraints such as [State.Ulimit], [State.ParentCgroup], [State.Network], etc. are applied to the container.
|
|
|
|
|
//
|
|
|
|
|
// Run is useful when none of the LLB ops are sufficient for the operation that you want to perform.
|
|
|
|
|
func (s State) Run(ro ...RunOption) ExecState {
|
|
|
|
|
ei := &ExecInfo{State: s}
|
|
|
|
|
for _, o := range ro {
|
|
|
|
@ -277,6 +291,8 @@ func (s State) Run(ro ...RunOption) ExecState {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// File performs a file operation on the current state.
|
|
|
|
|
// See [FileAction] for details on the operations that can be performed.
|
|
|
|
|
func (s State) File(a *FileAction, opts ...ConstraintsOpt) State {
|
|
|
|
|
var c Constraints
|
|
|
|
|
for _, o := range opts {
|
|
|
|
@ -286,21 +302,29 @@ func (s State) File(a *FileAction, opts ...ConstraintsOpt) State {
|
|
|
|
|
return s.WithOutput(NewFileOp(s, a, c).Output())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddEnv returns a new [State] with the provided environment variable set.
|
|
|
|
|
// See [AddEnv]
|
|
|
|
|
func (s State) AddEnv(key, value string) State {
|
|
|
|
|
return AddEnv(key, value)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddEnvf is the same as [State.AddEnv] but with a format string.
|
|
|
|
|
func (s State) AddEnvf(key, value string, v ...interface{}) State {
|
|
|
|
|
return AddEnvf(key, value, v...)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Dir returns a new [State] with the provided working directory set.
|
|
|
|
|
// See [Dir]
|
|
|
|
|
func (s State) Dir(str string) State {
|
|
|
|
|
return Dir(str)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Dirf is the same as [State.Dir] but with a format string.
|
|
|
|
|
func (s State) Dirf(str string, v ...interface{}) State {
|
|
|
|
|
return Dirf(str, v...)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetEnv returns the value of the environment variable with the provided key.
|
|
|
|
|
func (s State) GetEnv(ctx context.Context, key string, co ...ConstraintsOpt) (string, bool, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -314,6 +338,8 @@ func (s State) GetEnv(ctx context.Context, key string, co ...ConstraintsOpt) (st
|
|
|
|
|
return v, ok, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Env returns a new [State] with the provided environment variable set.
|
|
|
|
|
// See [Env]
|
|
|
|
|
func (s State) Env(ctx context.Context, co ...ConstraintsOpt) ([]string, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -326,6 +352,7 @@ func (s State) Env(ctx context.Context, co ...ConstraintsOpt) ([]string, error)
|
|
|
|
|
return env.ToArray(), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetDir returns the current working directory for the state.
|
|
|
|
|
func (s State) GetDir(ctx context.Context, co ...ConstraintsOpt) (string, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -342,18 +369,28 @@ func (s State) GetArgs(ctx context.Context, co ...ConstraintsOpt) ([]string, err
|
|
|
|
|
return getArgs(s)(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset is used to return a new [State] with all of the current state and the
|
|
|
|
|
// provided [State] as the parent. In effect you can think of this as creating
|
|
|
|
|
// a new state with all the output from the current state but reparented to the
|
|
|
|
|
// provided state. See [Reset] for more details.
|
|
|
|
|
func (s State) Reset(s2 State) State {
|
|
|
|
|
return Reset(s2)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// User sets the user for this state.
|
|
|
|
|
// See [User] for more details.
|
|
|
|
|
func (s State) User(v string) State {
|
|
|
|
|
return User(v)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hostname sets the hostname for this state.
|
|
|
|
|
// See [Hostname] for more details.
|
|
|
|
|
func (s State) Hostname(v string) State {
|
|
|
|
|
return Hostname(v)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetHostname returns the hostname set on the state.
|
|
|
|
|
// See [Hostname] for more details.
|
|
|
|
|
func (s State) GetHostname(ctx context.Context, co ...ConstraintsOpt) (string, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -362,10 +399,14 @@ func (s State) GetHostname(ctx context.Context, co ...ConstraintsOpt) (string, e
|
|
|
|
|
return getHostname(s)(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Platform sets the platform for the state. Platforms are used to determine
|
|
|
|
|
// image variants to pull and run as well as the platform metadata to set on the
|
|
|
|
|
// image config.
|
|
|
|
|
func (s State) Platform(p ocispecs.Platform) State {
|
|
|
|
|
return platform(p)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPlatform returns the platform for the state.
|
|
|
|
|
func (s State) GetPlatform(ctx context.Context, co ...ConstraintsOpt) (*ocispecs.Platform, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -374,10 +415,14 @@ func (s State) GetPlatform(ctx context.Context, co ...ConstraintsOpt) (*ocispecs
|
|
|
|
|
return getPlatform(s)(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Network sets the network mode for the state.
|
|
|
|
|
// Network modes are used by [State.Run] to determine the network mode used when running the container.
|
|
|
|
|
// Network modes are not applied to image configs.
|
|
|
|
|
func (s State) Network(n pb.NetMode) State {
|
|
|
|
|
return Network(n)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetNetwork returns the network mode for the state.
|
|
|
|
|
func (s State) GetNetwork(ctx context.Context, co ...ConstraintsOpt) (pb.NetMode, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -385,10 +430,15 @@ func (s State) GetNetwork(ctx context.Context, co ...ConstraintsOpt) (pb.NetMode
|
|
|
|
|
}
|
|
|
|
|
return getNetwork(s)(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Security sets the security mode for the state.
|
|
|
|
|
// Security modes are used by [State.Run] to the privileges that processes in the container will run with.
|
|
|
|
|
// Security modes are not applied to image configs.
|
|
|
|
|
func (s State) Security(n pb.SecurityMode) State {
|
|
|
|
|
return Security(n)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetSecurity returns the security mode for the state.
|
|
|
|
|
func (s State) GetSecurity(ctx context.Context, co ...ConstraintsOpt) (pb.SecurityMode, error) {
|
|
|
|
|
c := &Constraints{}
|
|
|
|
|
for _, f := range co {
|
|
|
|
@ -397,6 +447,8 @@ func (s State) GetSecurity(ctx context.Context, co ...ConstraintsOpt) (pb.Securi
|
|
|
|
|
return getSecurity(s)(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// With applies [StateOption]s to the [State].
|
|
|
|
|
// Each applied [StateOption] creates a new [State] object with the previous as its parent.
|
|
|
|
|
func (s State) With(so ...StateOption) State {
|
|
|
|
|
for _, o := range so {
|
|
|
|
|
s = o(s)
|
|
|
|
@ -404,14 +456,23 @@ func (s State) With(so ...StateOption) State {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddExtraHost adds a host name to IP mapping to any containers created from this state.
|
|
|
|
|
func (s State) AddExtraHost(host string, ip net.IP) State {
|
|
|
|
|
return extraHost(host, ip)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddUlimit sets the hard/soft for the given ulimit.
|
|
|
|
|
// The ulimit is applied to containers created from this state.
|
|
|
|
|
// Ulimits are Linux specific and only applies to containers created from this state such as via `[State.Run]`
|
|
|
|
|
// Ulimits do not apply to image configs.
|
|
|
|
|
func (s State) AddUlimit(name UlimitName, soft int64, hard int64) State {
|
|
|
|
|
return ulimit(name, soft, hard)(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WithCgroupParent sets the parent cgroup for any containers created from this state.
|
|
|
|
|
// This is useful when you want to apply resource constraints to a group of containers.
|
|
|
|
|
// Cgroups are Linux specific and only applies to containers created from this state such as via `[State.Run]`
|
|
|
|
|
// Cgroups do not apply to image configs.
|
|
|
|
|
func (s State) WithCgroupParent(cp string) State {
|
|
|
|
|
return cgroupParent(cp)(s)
|
|
|
|
|
}
|
|
|
|
|