2019-05-21 04:11:48 +00:00
|
|
|
package allocrunner
|
|
|
|
|
|
|
|
import (
|
2019-09-04 20:33:25 +00:00
|
|
|
"context"
|
2019-05-21 04:11:48 +00:00
|
|
|
"fmt"
|
|
|
|
|
|
|
|
hclog "github.com/hashicorp/go-hclog"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
"github.com/hashicorp/nomad/plugins/drivers"
|
|
|
|
)
|
|
|
|
|
|
|
|
// networkHook is an alloc lifecycle hook that manages the network namespace
|
|
|
|
// for an alloc
|
|
|
|
type networkHook struct {
|
|
|
|
// setter is a callback to set the network isolation spec when after the
|
|
|
|
// network is created
|
|
|
|
setter networkIsolationSetter
|
|
|
|
|
|
|
|
// manager is used when creating the network namespace. This defaults to
|
|
|
|
// bind mounting a network namespace descritor under /var/run/netns but
|
|
|
|
// can be created by a driver if nessicary
|
|
|
|
manager drivers.DriverNetworkManager
|
|
|
|
|
|
|
|
// alloc should only be read from
|
|
|
|
alloc *structs.Allocation
|
|
|
|
|
|
|
|
// spec described the network namespace and is syncronized by specLock
|
|
|
|
spec *drivers.NetworkIsolationSpec
|
|
|
|
|
2019-06-14 03:05:57 +00:00
|
|
|
// networkConfigurator configures the network interfaces, routes, etc once
|
|
|
|
// the alloc network has been created
|
|
|
|
networkConfigurator NetworkConfigurator
|
|
|
|
|
2019-05-21 04:11:48 +00:00
|
|
|
logger hclog.Logger
|
|
|
|
}
|
|
|
|
|
2019-06-14 03:05:57 +00:00
|
|
|
func newNetworkHook(logger hclog.Logger, ns networkIsolationSetter,
|
|
|
|
alloc *structs.Allocation, netManager drivers.DriverNetworkManager,
|
|
|
|
netConfigurator NetworkConfigurator) *networkHook {
|
2019-05-21 04:11:48 +00:00
|
|
|
return &networkHook{
|
2019-06-14 03:05:57 +00:00
|
|
|
setter: ns,
|
|
|
|
alloc: alloc,
|
|
|
|
manager: netManager,
|
|
|
|
networkConfigurator: netConfigurator,
|
|
|
|
logger: logger,
|
2019-05-21 04:11:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *networkHook) Name() string {
|
|
|
|
return "network"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *networkHook) Prerun() error {
|
|
|
|
tg := h.alloc.Job.LookupTaskGroup(h.alloc.TaskGroup)
|
|
|
|
if len(tg.Networks) == 0 || tg.Networks[0].Mode == "host" || tg.Networks[0].Mode == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-06-14 03:05:57 +00:00
|
|
|
if h.manager == nil || h.networkConfigurator == nil {
|
|
|
|
h.logger.Trace("shared network namespaces are not supported on this platform, skipping network hook")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-09-18 20:34:57 +00:00
|
|
|
spec, created, err := h.manager.CreateNetwork(h.alloc.ID)
|
|
|
|
|
2019-05-21 04:11:48 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to create network for alloc: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if spec != nil {
|
|
|
|
h.spec = spec
|
|
|
|
h.setter.SetNetworkIsolation(spec)
|
|
|
|
}
|
|
|
|
|
2019-09-18 20:34:57 +00:00
|
|
|
if created {
|
|
|
|
if err := h.networkConfigurator.Setup(context.TODO(), h.alloc, spec); err != nil {
|
|
|
|
return fmt.Errorf("failed to configure networking for alloc: %v", err)
|
|
|
|
}
|
2019-06-11 04:29:12 +00:00
|
|
|
}
|
2019-05-21 04:11:48 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *networkHook) Postrun() error {
|
|
|
|
if h.spec == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-09-04 20:33:25 +00:00
|
|
|
if err := h.networkConfigurator.Teardown(context.TODO(), h.alloc, h.spec); err != nil {
|
2019-06-11 04:29:12 +00:00
|
|
|
h.logger.Error("failed to cleanup network for allocation, resources may have leaked", "alloc", h.alloc.ID, "error", err)
|
|
|
|
}
|
2019-05-21 04:11:48 +00:00
|
|
|
return h.manager.DestroyNetwork(h.alloc.ID, h.spec)
|
|
|
|
}
|