plans

package
v1.1.0-alpha20210811 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2021 License: MPL-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package plans contains the types that are used to represent Terraform plans.

A plan describes a set of changes that Terraform will make to update remote objects to match with changes to the configuration.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action rune
const (
	NoOp             Action = 0
	Create           Action = '+'
	Read             Action = '←'
	Update           Action = '~'
	DeleteThenCreate Action = '∓'
	CreateThenDelete Action = '±'
	Delete           Action = '-'
)

func (Action) IsReplace

func (a Action) IsReplace() bool

IsReplace returns true if the action is one of the two actions that represents replacing an existing object with a new object: DeleteThenCreate or CreateThenDelete.

func (Action) String

func (i Action) String() string

type Backend

type Backend struct {
	// Type is the type of backend that the plan will apply against.
	Type string

	// Config is the configuration of the backend, whose schema is decided by
	// the backend Type.
	Config DynamicValue

	// Workspace is the name of the workspace that was active when the plan
	// was created. It is illegal to apply a plan created for one workspace
	// to the state of another workspace.
	// (This constraint is already enforced by the statefile lineage mechanism,
	// but storing this explicitly allows us to return a better error message
	// in the situation where the user has the wrong workspace selected.)
	Workspace string
}

Backend represents the backend-related configuration and other data as it existed when a plan was created.

func NewBackend

func NewBackend(typeName string, config cty.Value, configSchema *configschema.Block, workspaceName string) (*Backend, error)

type Change

type Change struct {
	// Action defines what kind of change is being made.
	Action Action

	// Interpretation of Before and After depend on Action:
	//
	//     NoOp     Before and After are the same, unchanged value
	//     Create   Before is nil, and After is the expected value after create.
	//     Read     Before is any prior value (nil if no prior), and After is the
	//              value that was or will be read.
	//     Update   Before is the value prior to update, and After is the expected
	//              value after update.
	//     Replace  As with Update.
	//     Delete   Before is the value prior to delete, and After is always nil.
	//
	// Unknown values may appear anywhere within the Before and After values,
	// either as the values themselves or as nested elements within known
	// collections/structures.
	Before, After cty.Value
}

Change describes a single change with a given action.

func (*Change) Encode

func (c *Change) Encode(ty cty.Type) (*ChangeSrc, error)

Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file. Pass the type constraint that the values are expected to conform to; to properly decode the values later an identical type constraint must be provided at that time.

Where a Change is embedded in some other struct, it's generally better to call the corresponding Encode method of that struct rather than working directly with its embedded Change.

type ChangeSrc

type ChangeSrc struct {
	// Action defines what kind of change is being made.
	Action Action

	// Before and After correspond to the fields of the same name in Change,
	// but have not yet been decoded from the serialized value used for
	// storage.
	Before, After DynamicValue

	// BeforeValMarks and AfterValMarks are stored path+mark combinations
	// that might be discovered when encoding a change. Marks are removed
	// to enable encoding (marked values cannot be marshalled), and so storing
	// the path+mark combinations allow us to re-mark the value later
	// when, for example, displaying the diff to the UI.
	BeforeValMarks, AfterValMarks []cty.PathValueMarks
}

ChangeSrc is a not-yet-decoded Change.

func (*ChangeSrc) Decode

func (cs *ChangeSrc) Decode(ty cty.Type) (*Change, error)

Decode unmarshals the raw representations of the before and after values to produce a Change object. Pass the type constraint that the result must conform to.

Where a ChangeSrc is embedded in some other struct, it's generally better to call the corresponding Decode method of that struct rather than working directly with its embedded Change.

type Changes

type Changes struct {
	// Resources tracks planned changes to resource instance objects.
	Resources []*ResourceInstanceChangeSrc

	// Outputs tracks planned changes output values.
	//
	// Note that although an in-memory plan contains planned changes for
	// outputs throughout the configuration, a plan serialized
	// to disk retains only the root outputs because they are
	// externally-visible, while other outputs are implementation details and
	// can be easily re-calculated during the apply phase. Therefore only root
	// module outputs will survive a round-trip through a plan file.
	Outputs []*OutputChangeSrc
}

Changes describes various actions that Terraform will attempt to take if the corresponding plan is applied.

A Changes object can be rendered into a visual diff (by the caller, using code in another package) for display to the user.

func NewChanges

func NewChanges() *Changes

NewChanges returns a valid Changes object that describes no changes.

func (*Changes) Empty

func (c *Changes) Empty() bool

func (*Changes) InstancesForConfigResource

func (c *Changes) InstancesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc

InstancesForConfigResource returns the planned change for the current objects of the resource instances of the given address, if any. Returns nil if no changes are planned.

func (*Changes) OutputValue

func (c *Changes) OutputValue(addr addrs.AbsOutputValue) *OutputChangeSrc

OutputValue returns the planned change for the output value with the

given address, if any. Returns nil if no change is planned.

func (*Changes) OutputValues

func (c *Changes) OutputValues(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc

OutputValues returns planned changes for all outputs for all module instances that reside in the parent path. Returns nil if no changes are planned.

func (*Changes) PlannedState

func (c *Changes) PlannedState(prior *states.State) (*states.State, error)

PlannedState merges the set of changes described by the receiver into the given prior state to produce the planned result state.

The result is an approximation of the state as it would exist after applying these changes, omitting any values that cannot be determined until the changes are actually applied.

func (*Changes) ResourceInstance

func (c *Changes) ResourceInstance(addr addrs.AbsResourceInstance) *ResourceInstanceChangeSrc

ResourceInstance returns the planned change for the current object of the resource instance of the given address, if any. Returns nil if no change is planned.

func (*Changes) ResourceInstanceDeposed

func (c *Changes) ResourceInstanceDeposed(addr addrs.AbsResourceInstance, key states.DeposedKey) *ResourceInstanceChangeSrc

ResourceInstanceDeposed returns the plan change of a deposed object of the resource instance of the given address, if any. Returns nil if no change is planned.

func (*Changes) SyncWrapper

func (c *Changes) SyncWrapper() *ChangesSync

SyncWrapper returns a wrapper object around the receiver that can be used to make certain changes to the receiver in a concurrency-safe way, as long as all callers share the same wrapper object.

type ChangesSync

type ChangesSync struct {
	// contains filtered or unexported fields
}

ChangesSync is a wrapper around a Changes that provides a concurrency-safe interface to insert new changes and retrieve copies of existing changes.

Each ChangesSync is independent of all others, so all concurrent writers to a particular Changes must share a single ChangesSync. Behavior is undefined if any other caller makes changes to the underlying Changes object or its nested objects concurrently with any of the methods of a particular ChangesSync.

func (*ChangesSync) AppendOutputChange

func (cs *ChangesSync) AppendOutputChange(changeSrc *OutputChangeSrc)

AppendOutputChange records the given output value change in the set of planned value changes.

The caller must ensure that there are no concurrent writes to the given change while this method is running, but it is safe to resume mutating it after this method returns without affecting the saved change.

func (*ChangesSync) AppendResourceInstanceChange

func (cs *ChangesSync) AppendResourceInstanceChange(changeSrc *ResourceInstanceChangeSrc)

AppendResourceInstanceChange records the given resource instance change in the set of planned resource changes.

The caller must ensure that there are no concurrent writes to the given change while this method is running, but it is safe to resume mutating it after this method returns without affecting the saved change.

func (*ChangesSync) GetChangesForConfigResource

func (cs *ChangesSync) GetChangesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc

GetChangesForConfigResource searched the set of resource instance changes and returns all changes related to a given configuration address. This is be used to find possible changes related to a configuration reference.

If no such changes exist, nil is returned.

The returned objects are a deep copy of the change recorded in the plan, so callers may mutate them although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.

func (*ChangesSync) GetOutputChange

func (cs *ChangesSync) GetOutputChange(addr addrs.AbsOutputValue) *OutputChangeSrc

GetOutputChange searches the set of output value changes for one matching the given address, returning it if it exists.

If no such change exists, nil is returned.

The returned object is a deep copy of the change recorded in the plan, so callers may mutate it although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.

func (*ChangesSync) GetOutputChanges

func (cs *ChangesSync) GetOutputChanges(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc

GetOutputChanges searches the set of output changes for any that reside in module instances beneath the given module. If no changes exist, nil is returned.

The returned objects are a deep copy of the change recorded in the plan, so callers may mutate them although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.

func (*ChangesSync) GetResourceInstanceChange

func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) *ResourceInstanceChangeSrc

GetResourceInstanceChange searches the set of resource instance changes for one matching the given address and generation, returning it if it exists.

If no such change exists, nil is returned.

The returned object is a deep copy of the change recorded in the plan, so callers may mutate it although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.

func (*ChangesSync) IsFullDestroy

func (cs *ChangesSync) IsFullDestroy() bool

IsFullDestroy returns true if the set of changes indicates we are doing a destroy of all resources.

func (*ChangesSync) RemoveOutputChange

func (cs *ChangesSync) RemoveOutputChange(addr addrs.AbsOutputValue)

RemoveOutputChange searches the set of output value changes for one matching the given address, and removes it from the set if it exists.

func (*ChangesSync) RemoveResourceInstanceChange

func (cs *ChangesSync) RemoveResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation)

RemoveResourceInstanceChange searches the set of resource instance changes for one matching the given address and generation, and removes it from the set if it exists.

type DynamicValue

type DynamicValue []byte

DynamicValue is the representation in the plan of a value whose type cannot be determined at compile time, such as because it comes from a schema defined in a plugin.

This type is used as an indirection so that the overall plan structure can be decoded without schema available, and then the dynamic values accessed at a later time once the appropriate schema has been determined.

Internally, DynamicValue is a serialized version of a cty.Value created against a particular type constraint. Callers should not access directly the serialized form, whose format may change in future. Values of this type must always be created by calling NewDynamicValue.

The zero value of DynamicValue is nil, and represents the absense of a value within the Go type system. This is distinct from a cty.NullVal result, which represents the absense of a value within the cty type system.

func NewDynamicValue

func NewDynamicValue(val cty.Value, ty cty.Type) (DynamicValue, error)

NewDynamicValue creates a DynamicValue by serializing the given value against the given type constraint. The value must conform to the type constraint, or the result is undefined.

If the value to be encoded has no predefined schema (for example, for module output values and input variables), set the type constraint to cty.DynamicPseudoType in order to save type information as part of the value, and then also pass cty.DynamicPseudoType to method Decode to recover the original value.

cty.NilVal can be used to represent the absense of a value, but callers must be careful to distinguish values that are absent at the Go layer (cty.NilVal) vs. values that are absent at the cty layer (cty.NullVal results).

func (DynamicValue) Copy

func (v DynamicValue) Copy() DynamicValue

Copy produces a copy of the receiver with a distinct backing array.

func (DynamicValue) Decode

func (v DynamicValue) Decode(ty cty.Type) (cty.Value, error)

Decode retrieves the effective value from the receiever by interpreting the serialized form against the given type constraint. For correct results, the type constraint must match (or be consistent with) the one that was used to create the receiver.

A nil DynamicValue decodes to cty.NilVal, which is not a valid value and instead represents the absense of a value.

func (DynamicValue) ImpliedType

func (v DynamicValue) ImpliedType() (cty.Type, error)

ImpliedType returns the type implied by the serialized structure of the receiving value.

This will not necessarily be exactly the type that was given when the value was encoded, and in particular must not be used for values that were encoded with their static type given as cty.DynamicPseudoType. It is however safe to use this method for values that were encoded using their runtime type as the conforming type, with the result being semantically equivalent but with all lists and sets represented as tuples, and maps as objects, due to ambiguities of the serialization.

type Mode

type Mode rune

Mode represents the various mutually-exclusive modes for creating a plan.

const (
	// NormalMode is the default planning mode, which aims to synchronize the
	// prior state with remote objects and plan a set of actions intended to
	// make those remote objects better match the current configuration.
	NormalMode Mode = 0

	// DestroyMode is a special planning mode for situations where the goal
	// is to destroy all remote objects that are bound to instances in the
	// prior state, even if the configuration for those instances is still
	// present.
	//
	// This mode corresponds with the "-destroy" option to "terraform plan",
	// and with the plan created by the "terraform destroy" command.
	DestroyMode Mode = 'D'

	// RefreshOnlyMode is a special planning mode which only performs the
	// synchronization of prior state with remote objects, and skips any
	// effort to generate any change actions for resource instances even if
	// the configuration has changed relative to the state.
	//
	// This mode corresponds with the "-refresh-only" option to
	// "terraform plan".
	RefreshOnlyMode Mode = 'R'
)

func (Mode) String

func (i Mode) String() string

type OutputChange

type OutputChange struct {
	// Addr is the absolute address of the output value that the change
	// will apply to.
	Addr addrs.AbsOutputValue

	// Change is an embedded description of the change.
	//
	// For output value changes, the type constraint for the DynamicValue
	// instances is always cty.DynamicPseudoType.
	Change

	// Sensitive, if true, indicates that either the old or new value in the
	// change is sensitive and so a rendered version of the plan in the UI
	// should elide the actual values while still indicating the action of the
	// change.
	Sensitive bool
}

OutputChange describes a change to an output value.

func (*OutputChange) Encode

func (oc *OutputChange) Encode() (*OutputChangeSrc, error)

Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file.

type OutputChangeSrc

type OutputChangeSrc struct {
	// Addr is the absolute address of the output value that the change
	// will apply to.
	Addr addrs.AbsOutputValue

	// ChangeSrc is an embedded description of the not-yet-decoded change.
	//
	// For output value changes, the type constraint for the DynamicValue
	// instances is always cty.DynamicPseudoType.
	ChangeSrc

	// Sensitive, if true, indicates that either the old or new value in the
	// change is sensitive and so a rendered version of the plan in the UI
	// should elide the actual values while still indicating the action of the
	// change.
	Sensitive bool
}

OutputChangeSrc describes a change to an output value.

func (*OutputChangeSrc) Decode

func (ocs *OutputChangeSrc) Decode() (*OutputChange, error)

Decode unmarshals the raw representation of the output value being changed.

func (*OutputChangeSrc) DeepCopy

func (ocs *OutputChangeSrc) DeepCopy() *OutputChangeSrc

DeepCopy creates a copy of the receiver where any pointers to nested mutable values are also copied, thus ensuring that future mutations of the receiver will not affect the copy.

Some types used within a resource change are immutable by convention even though the Go language allows them to be mutated, such as the types from the addrs package. These are _not_ copied by this method, under the assumption that callers will behave themselves.

type Plan

type Plan struct {
	// Mode is the mode under which this plan was created.
	//
	// This is only recorded to allow for UI differences when presenting plans
	// to the end-user, and so it must not be used to influence apply-time
	// behavior. The actions during apply must be described entirely by
	// the Changes field, regardless of how the plan was created.
	UIMode Mode

	VariableValues    map[string]DynamicValue
	Changes           *Changes
	TargetAddrs       []addrs.Targetable
	ForceReplaceAddrs []addrs.AbsResourceInstance
	ProviderSHA256s   map[string][]byte
	Backend           Backend

	// PrevRunState and PriorState both describe the situation that the plan
	// was derived from:
	//
	// PrevRunState is a representation of the outcome of the previous
	// Terraform operation, without any updates from the remote system but
	// potentially including some changes that resulted from state upgrade
	// actions.
	//
	// PriorState is a representation of the current state of remote objects,
	// which will differ from PrevRunState if the "refresh" step returned
	// different data, which might reflect drift.
	//
	// PriorState is the main snapshot we use for actions during apply.
	// PrevRunState is only here so that we can diff PriorState against it in
	// order to report to the user any out-of-band changes we've detected.
	PrevRunState *states.State
	PriorState   *states.State
}

Plan is the top-level type representing a planned set of changes.

A plan is a summary of the set of changes required to move from a current state to a goal state derived from configuration. The described changes are not applied directly, but contain an approximation of the final result that will be completed during apply by resolving any values that cannot be predicted.

A plan must always be accompanied by the configuration it was built from, since the plan does not itself include all of the information required to make the changes indicated.

func (*Plan) CanApply

func (p *Plan) CanApply() bool

CanApply returns true if and only if the recieving plan includes content that would make sense to apply. If it returns false, the plan operation should indicate that there's nothing to do and Terraform should exit without prompting the user to confirm the changes.

This function represents our main business logic for making the decision about whether a given plan represents meaningful "changes", and so its exact definition may change over time; the intent is just to centralize the rules for that rather than duplicating different versions of it at various locations in the UI code.

func (*Plan) ProviderAddrs

func (p *Plan) ProviderAddrs() []addrs.AbsProviderConfig

ProviderAddrs returns a list of all of the provider configuration addresses referenced throughout the receiving plan.

The result is de-duplicated so that each distinct address appears only once.

type ResourceInstanceChange

type ResourceInstanceChange struct {
	// Addr is the absolute address of the resource instance that the change
	// will apply to.
	Addr addrs.AbsResourceInstance

	// DeposedKey is the identifier for a deposed object associated with the
	// given instance, or states.NotDeposed if this change applies to the
	// current object.
	//
	// A Replace change for a resource with create_before_destroy set will
	// create a new DeposedKey temporarily during replacement. In that case,
	// DeposedKey in the plan is always states.NotDeposed, representing that
	// the current object is being replaced with the deposed.
	DeposedKey states.DeposedKey

	// Provider is the address of the provider configuration that was used
	// to plan this change, and thus the configuration that must also be
	// used to apply it.
	ProviderAddr addrs.AbsProviderConfig

	// Change is an embedded description of the change.
	Change

	// ActionReason is an optional extra indication of why we chose the
	// action recorded in Change.Action for this particular resource instance.
	//
	// This is an approximate mechanism only for the purpose of explaining the
	// plan to end-users in the UI and is not to be used for any
	// decision-making during the apply step; if apply behavior needs to vary
	// depending on the "action reason" then the information for that decision
	// must be recorded more precisely elsewhere for that purpose.
	//
	// Sometimes there might be more than one reason for choosing a particular
	// action. In that case, it's up to the codepath making that decision to
	// decide which value would provide the most relevant explanation to the
	// end-user and return that. It's not a goal of this field to represent
	// fine details about the planning process.
	ActionReason ResourceInstanceChangeActionReason

	// RequiredReplace is a set of paths that caused the change action to be
	// Replace rather than Update. Always nil if the change action is not
	// Replace.
	//
	// This is retained only for UI-plan-rendering purposes and so it does not
	// currently survive a round-trip through a saved plan file.
	RequiredReplace cty.PathSet

	// Private allows a provider to stash any extra data that is opaque to
	// Terraform that relates to this change. Terraform will save this
	// byte-for-byte and return it to the provider in the apply call.
	Private []byte
}

ResourceInstanceChange describes a change to a particular resource instance object.

func (*ResourceInstanceChange) Encode

Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file. Pass the implied type of the corresponding resource type schema for correct operation.

func (*ResourceInstanceChange) Simplify

func (rc *ResourceInstanceChange) Simplify(destroying bool) *ResourceInstanceChange

Simplify will, where possible, produce a change with a simpler action than the receiever given a flag indicating whether the caller is dealing with a normal apply or a destroy. This flag deals with the fact that Terraform Core uses a specialized graph node type for destroying; only that specialized node should set "destroying" to true.

The following table shows the simplification behavior:

Action    Destroying?   New Action
--------+-------------+-----------
Create    true          NoOp
Delete    false         NoOp
Replace   true          Delete
Replace   false         Create

For any combination not in the above table, the Simplify just returns the receiver as-is.

type ResourceInstanceChangeActionReason

type ResourceInstanceChangeActionReason rune

ResourceInstanceChangeActionReason allows for some extra user-facing reasoning for why a particular change action was chosen for a particular resource instance.

This only represents sufficient detail to give a suitable explanation to an end-user, and mustn't be used for any real decision-making during the apply step.

const (
	// In most cases there's no special reason for choosing a particular
	// action, which is represented by ResourceInstanceChangeNoReason.
	ResourceInstanceChangeNoReason ResourceInstanceChangeActionReason = 0

	// ResourceInstanceReplaceBecauseTainted indicates that the resource
	// instance must be replaced because its existing current object is
	// marked as "tainted".
	ResourceInstanceReplaceBecauseTainted ResourceInstanceChangeActionReason = 'T'

	// ResourceInstanceReplaceByRequest indicates that the resource instance
	// is planned to be replaced because a caller specifically asked for it
	// to be using ReplaceAddrs. (On the command line, the -replace=...
	// planning option.)
	ResourceInstanceReplaceByRequest ResourceInstanceChangeActionReason = 'R'

	// ResourceInstanceReplaceBecauseCannotUpdate indicates that the resource
	// instance is planned to be replaced because the provider has indicated
	// that a requested change cannot be applied as an update.
	//
	// In this case, the RequiredReplace field will typically be populated on
	// the ResourceInstanceChange object to give information about specifically
	// which arguments changed in a non-updatable way.
	ResourceInstanceReplaceBecauseCannotUpdate ResourceInstanceChangeActionReason = 'F'
)

func (ResourceInstanceChangeActionReason) String

type ResourceInstanceChangeSrc

type ResourceInstanceChangeSrc struct {
	// Addr is the absolute address of the resource instance that the change
	// will apply to.
	Addr addrs.AbsResourceInstance

	// DeposedKey is the identifier for a deposed object associated with the
	// given instance, or states.NotDeposed if this change applies to the
	// current object.
	//
	// A Replace change for a resource with create_before_destroy set will
	// create a new DeposedKey temporarily during replacement. In that case,
	// DeposedKey in the plan is always states.NotDeposed, representing that
	// the current object is being replaced with the deposed.
	DeposedKey states.DeposedKey

	// Provider is the address of the provider configuration that was used
	// to plan this change, and thus the configuration that must also be
	// used to apply it.
	ProviderAddr addrs.AbsProviderConfig

	// ChangeSrc is an embedded description of the not-yet-decoded change.
	ChangeSrc

	// ActionReason is an optional extra indication of why we chose the
	// action recorded in Change.Action for this particular resource instance.
	//
	// This is an approximate mechanism only for the purpose of explaining the
	// plan to end-users in the UI and is not to be used for any
	// decision-making during the apply step; if apply behavior needs to vary
	// depending on the "action reason" then the information for that decision
	// must be recorded more precisely elsewhere for that purpose.
	//
	// See the field of the same name in ResourceInstanceChange for more
	// details.
	ActionReason ResourceInstanceChangeActionReason

	// RequiredReplace is a set of paths that caused the change action to be
	// Replace rather than Update. Always nil if the change action is not
	// Replace.
	RequiredReplace cty.PathSet

	// Private allows a provider to stash any extra data that is opaque to
	// Terraform that relates to this change. Terraform will save this
	// byte-for-byte and return it to the provider in the apply call.
	Private []byte
}

ResourceInstanceChangeSrc is a not-yet-decoded ResourceInstanceChange. Pass the associated resource type's schema type to method Decode to obtain a ResourceInstanceChange.

func (*ResourceInstanceChangeSrc) Decode

Decode unmarshals the raw representation of the instance object being changed. Pass the implied type of the corresponding resource type schema for correct operation.

func (*ResourceInstanceChangeSrc) DeepCopy

DeepCopy creates a copy of the receiver where any pointers to nested mutable values are also copied, thus ensuring that future mutations of the receiver will not affect the copy.

Some types used within a resource change are immutable by convention even though the Go language allows them to be mutated, such as the types from the addrs package. These are _not_ copied by this method, under the assumption that callers will behave themselves.

Directories

Path Synopsis
internal
planproto
Package planproto is home to the Go stubs generated from the tfplan protobuf schema.
Package planproto is home to the Go stubs generated from the tfplan protobuf schema.
Package objchange deals with the business logic of taking a prior state value and a config value and producing a proposed new merged value, along with other related rules in this domain.
Package objchange deals with the business logic of taking a prior state value and a config value and producing a proposed new merged value, along with other related rules in this domain.
Package planfile deals with the file format used to serialize plans to disk and then deserialize them back into memory later.
Package planfile deals with the file format used to serialize plans to disk and then deserialize them back into memory later.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL