From 6670407c9ca1fcdace318080c112d2956ec13474 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Tue, 21 Nov 2023 00:13:17 -0500 Subject: [PATCH] engine: resources: Make net resource reversible This allows the net resource to be reversible if we want it to be. It only flips the network state from up to down or vice-versa. --- engine/resources/net.go | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/engine/resources/net.go b/engine/resources/net.go index 84115e48..0721dba4 100644 --- a/engine/resources/net.go +++ b/engine/resources/net.go @@ -129,10 +129,12 @@ const ( // of a network link. Configuration is also stored in a networkd configuration // file, so the network is available upon reboot. The name of the resource is // the string representing the network interface name. This could be "eth0" for -// example. +// example. It supports flipping the state if you ask for it to be reversible. type NetRes struct { traits.Base // add the base methods without re-implementation + traits.Reversible + init *engine.Init // State is the desired state of the interface. It can be "up", "down", @@ -655,6 +657,55 @@ func (obj *NetRes) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } +// Copy copies the resource. Don't call it directly, use engine.ResCopy instead. +// TODO: should this copy internal state? +func (obj *NetRes) Copy() engine.CopyableRes { + addrs := []string{} + for _, addr := range obj.Addrs { + addrs = append(addrs, addr) + } + var ipforward *bool + if obj.IPForward != nil { // copy the content, not the pointer... + b := *obj.IPForward + ipforward = &b + } + return &NetRes{ + State: obj.State, + Addrs: addrs, + Gateway: obj.Gateway, + IPForward: ipforward, + } +} + +// Reversed returns the "reverse" or "reciprocal" resource. This is used to +// "clean" up after a previously defined resource has been removed. +func (obj *NetRes) Reversed() (engine.ReversibleRes, error) { + cp, err := engine.ResCopy(obj) + if err != nil { + return nil, errwrap.Wrapf(err, "could not copy") + } + rev, ok := cp.(engine.ReversibleRes) + if !ok { + return nil, fmt.Errorf("not reversible") + } + rev.ReversibleMeta().Disabled = true // the reverse shouldn't run again + + res, ok := cp.(*NetRes) + if !ok { + return nil, fmt.Errorf("copied res was not our kind") + } + + // Only one field to reverse for now. It also removes the config file. + if obj.State == NetStateUp { + res.State = NetStateDown + } + if obj.State == NetStateDown { + res.State = NetStateUp + } + + return res, nil +} + // unitFileContents builds the unit file contents from the definition. func (obj *NetRes) unitFileContents() []byte { // build the unit file contents