github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/client/allocrunner/network_hook.go (about) 1 package allocrunner 2 3 import ( 4 "context" 5 "fmt" 6 7 hclog "github.com/hashicorp/go-hclog" 8 "github.com/hashicorp/nomad/nomad/structs" 9 "github.com/hashicorp/nomad/plugins/drivers" 10 ) 11 12 type networkIsolationSetter interface { 13 SetNetworkIsolation(*drivers.NetworkIsolationSpec) 14 } 15 16 // allocNetworkIsolationSetter is a shim to allow the alloc network hook to 17 // set the alloc network isolation configuration without full access 18 // to the alloc runner 19 type allocNetworkIsolationSetter struct { 20 ar *allocRunner 21 } 22 23 func (a *allocNetworkIsolationSetter) SetNetworkIsolation(n *drivers.NetworkIsolationSpec) { 24 for _, tr := range a.ar.tasks { 25 tr.SetNetworkIsolation(n) 26 } 27 } 28 29 type networkStatusSetter interface { 30 SetNetworkStatus(*structs.AllocNetworkStatus) 31 } 32 33 // networkHook is an alloc lifecycle hook that manages the network namespace 34 // for an alloc 35 type networkHook struct { 36 // isolationSetter is a callback to set the network isolation spec when after the 37 // network is created 38 isolationSetter networkIsolationSetter 39 40 // statusSetter is a callback to the alloc runner to set the network status once 41 // network setup is complete 42 networkStatusSetter networkStatusSetter 43 44 // manager is used when creating the network namespace. This defaults to 45 // bind mounting a network namespace descritor under /var/run/netns but 46 // can be created by a driver if nessicary 47 manager drivers.DriverNetworkManager 48 49 // alloc should only be read from 50 alloc *structs.Allocation 51 52 // spec described the network namespace and is syncronized by specLock 53 spec *drivers.NetworkIsolationSpec 54 55 // networkConfigurator configures the network interfaces, routes, etc once 56 // the alloc network has been created 57 networkConfigurator NetworkConfigurator 58 59 logger hclog.Logger 60 } 61 62 func newNetworkHook(logger hclog.Logger, 63 ns networkIsolationSetter, 64 alloc *structs.Allocation, 65 netManager drivers.DriverNetworkManager, 66 netConfigurator NetworkConfigurator, 67 networkStatusSetter networkStatusSetter) *networkHook { 68 return &networkHook{ 69 isolationSetter: ns, 70 networkStatusSetter: networkStatusSetter, 71 alloc: alloc, 72 manager: netManager, 73 networkConfigurator: netConfigurator, 74 logger: logger, 75 } 76 } 77 78 func (h *networkHook) Name() string { 79 return "network" 80 } 81 82 func (h *networkHook) Prerun() error { 83 tg := h.alloc.Job.LookupTaskGroup(h.alloc.TaskGroup) 84 if len(tg.Networks) == 0 || tg.Networks[0].Mode == "host" || tg.Networks[0].Mode == "" { 85 return nil 86 } 87 88 if h.manager == nil || h.networkConfigurator == nil { 89 h.logger.Trace("shared network namespaces are not supported on this platform, skipping network hook") 90 return nil 91 } 92 93 spec, created, err := h.manager.CreateNetwork(h.alloc.ID) 94 95 if err != nil { 96 return fmt.Errorf("failed to create network for alloc: %v", err) 97 } 98 99 if spec != nil { 100 h.spec = spec 101 h.isolationSetter.SetNetworkIsolation(spec) 102 } 103 104 if created { 105 status, err := h.networkConfigurator.Setup(context.TODO(), h.alloc, spec) 106 if err != nil { 107 return fmt.Errorf("failed to configure networking for alloc: %v", err) 108 } 109 110 h.networkStatusSetter.SetNetworkStatus(status) 111 } 112 return nil 113 } 114 115 func (h *networkHook) Postrun() error { 116 if h.spec == nil { 117 return nil 118 } 119 120 if err := h.networkConfigurator.Teardown(context.TODO(), h.alloc, h.spec); err != nil { 121 h.logger.Error("failed to cleanup network for allocation, resources may have leaked", "alloc", h.alloc.ID, "error", err) 122 } 123 return h.manager.DestroyNetwork(h.alloc.ID, h.spec) 124 }