1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
package network
import (
"fmt"
"github.com/lxc/incus/v6/internal/server/cluster/request"
"github.com/lxc/incus/v6/internal/server/db"
"github.com/lxc/incus/v6/shared/api"
"github.com/lxc/incus/v6/shared/logger"
"github.com/lxc/incus/v6/shared/revert"
"github.com/lxc/incus/v6/shared/validate"
)
// sriov represents an sriov network.
type sriov struct {
common
}
// DBType returns the network type DB ID.
func (n *sriov) DBType() db.NetworkType {
return db.NetworkTypeSriov
}
// Validate network config.
func (n *sriov) Validate(config map[string]string, clientType request.ClientType) error {
rules := map[string]func(value string) error{
// gendoc:generate(entity=network_sriov, group=common, key=parent)
//
// ---
// type: string
// condition: -
// shortdesc: Parent interface to create `sriov` NICs on
"parent": validate.Required(validate.IsNotEmpty, validate.IsInterfaceName),
// gendoc:generate(entity=network_sriov, group=common, key=mtu)
//
// ---
// type: integer
// condition: -
// shortdesc: The MTU of the new interface
"mtu": validate.Optional(validate.IsNetworkMTU),
// gendoc:generate(entity=network_sriov, group=common, key=vlan)
//
// ---
// type: integer
// condition: -
// shortdesc: The VLAN ID to attach to
"vlan": validate.Optional(validate.IsNetworkVLAN),
// gendoc:generate(entity=network_sriov, group=common, key=user.*)
//
// ---
// type: string
// condition: -
// shortdesc: User-provided free-form key/value pairs
}
err := n.validate(config, rules)
if err != nil {
return err
}
return nil
}
// Delete deletes a network.
func (n *sriov) Delete(clientType request.ClientType) error {
n.logger.Debug("Delete", logger.Ctx{"clientType": clientType})
return n.common.delete(clientType)
}
// Rename renames a network.
func (n *sriov) Rename(newName string) error {
n.logger.Debug("Rename", logger.Ctx{"newName": newName})
// Rename common steps.
err := n.common.rename(newName)
if err != nil {
return err
}
return nil
}
// Start starts is a no-op.
func (n *sriov) Start() error {
n.logger.Debug("Start")
reverter := revert.New()
defer reverter.Fail()
reverter.Add(func() { n.setUnavailable() })
if !InterfaceExists(n.config["parent"]) {
return fmt.Errorf("Parent interface %q not found", n.config["parent"])
}
reverter.Success()
// Ensure network is marked as available now its started.
n.setAvailable()
return nil
}
// Stop stops is a no-op.
func (n *sriov) Stop() error {
n.logger.Debug("Stop")
return nil
}
// Update updates the network. Accepts notification boolean indicating if this update request is coming from a
// cluster notification, in which case do not update the database, just apply local changes needed.
func (n *sriov) Update(newNetwork api.NetworkPut, targetNode string, clientType request.ClientType) error {
n.logger.Debug("Update", logger.Ctx{"clientType": clientType, "newNetwork": newNetwork})
dbUpdateNeeded, _, oldNetwork, err := n.common.configChanged(newNetwork)
if err != nil {
return err
}
if !dbUpdateNeeded {
return nil // Nothing changed.
}
// If the network as a whole has not had any previous creation attempts, or the node itself is still
// pending, then don't apply the new settings to the node, just to the database record (ready for the
// actual global create request to be initiated).
if n.Status() == api.NetworkStatusPending || n.LocalStatus() == api.NetworkStatusPending {
return n.common.update(newNetwork, targetNode, clientType)
}
reverter := revert.New()
defer reverter.Fail()
// Define a function which reverts everything.
reverter.Add(func() {
// Reset changes to all nodes and database.
_ = n.common.update(oldNetwork, targetNode, clientType)
})
// Apply changes to all nodes and database.
err = n.common.update(newNetwork, targetNode, clientType)
if err != nil {
return err
}
reverter.Success()
return nil
}
|