mirror of
https://github.com/clearlinux/rkt.git
synced 2026-08-23 16:06:00 +00:00
net: call ipam plugin on container shutdown
- Fixes bugs in ipam/static release path - veth and bridge plugins invoke ipam plugin during DEL cmd
This commit is contained in:
+26
-1
@@ -94,7 +94,13 @@ func findIPAMPlugin(plugin string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func ExecPlugin(plugin string) (*IPConfig, error) {
|
||||
// Executes IPAM plugin, assuming RKT_NETPLUGIN_COMMAND == ADD.
|
||||
// Parses and returns resulting IPConfig
|
||||
func ExecPluginAdd(plugin string) (*IPConfig, error) {
|
||||
if os.Getenv("RKT_NETPLUGIN_COMMAND") != "ADD" {
|
||||
return nil, fmt.Errorf("RKT_NETPLUGIN_COMMAND is not ADD")
|
||||
}
|
||||
|
||||
pluginPath := findIPAMPlugin(plugin)
|
||||
if pluginPath == "" {
|
||||
return nil, fmt.Errorf("could not find %q plugin", plugin)
|
||||
@@ -117,6 +123,25 @@ func ExecPlugin(plugin string) (*IPConfig, error) {
|
||||
return ipConf, err
|
||||
}
|
||||
|
||||
// Executes IPAM plugin, assuming RKT_NETPLUGIN_COMMAND == DEL.
|
||||
func ExecPluginDel(plugin string) error {
|
||||
if os.Getenv("RKT_NETPLUGIN_COMMAND") != "DEL" {
|
||||
return fmt.Errorf("RKT_NETPLUGIN_COMMAND is not DEL")
|
||||
}
|
||||
|
||||
pluginPath := findIPAMPlugin(plugin)
|
||||
if pluginPath == "" {
|
||||
return fmt.Errorf("could not find %q plugin", plugin)
|
||||
}
|
||||
|
||||
c := exec.Cmd{
|
||||
Path: pluginPath,
|
||||
Args: []string{pluginPath},
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
return c.Run()
|
||||
}
|
||||
|
||||
func ApplyIPConfig(ifName string, ipConf *IPConfig) error {
|
||||
link, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
|
||||
@@ -58,21 +58,20 @@ func (s *Store) Release(ip net.IP) error {
|
||||
return os.Remove(filepath.Join(s.dataDir, ip.String()))
|
||||
}
|
||||
|
||||
// N.B. This function eats errors to be tolerant and
|
||||
// release as much as possible
|
||||
func (s *Store) ReleaseByContainerID(id string) error {
|
||||
err := filepath.Walk(s.dataDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() && path != s.dataDir {
|
||||
if err != nil || info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
if string(data) == id {
|
||||
if err := os.Remove(path); err != nil {
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -45,6 +45,16 @@ func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
func loadConf(path string) (*Net, error) {
|
||||
n := &Net{
|
||||
BrName: defaultBrName,
|
||||
}
|
||||
if err := rktnet.LoadNet(path, n); err != nil {
|
||||
return nil, fmt.Errorf("failed to load %q: %v", path, err)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func ensureBridgeAddr(br *netlink.Bridge, ipn *net.IPNet) error {
|
||||
addrs, err := netlink.AddrList(br, syscall.AF_INET)
|
||||
if err != nil && err != syscall.ENOENT {
|
||||
@@ -183,15 +193,13 @@ func cmdAdd(contID, netns, netConf, ifName string) error {
|
||||
return fmt.Errorf("error parsing ContainerID: %v", err)
|
||||
}
|
||||
|
||||
n := &Net{
|
||||
BrName: defaultBrName,
|
||||
}
|
||||
if err := rktnet.LoadNet(netConf, n); err != nil {
|
||||
return fmt.Errorf("failed to load %q: %v", netConf, err)
|
||||
n, err := loadConf(netConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// run the IPAM plugin and get back the config to apply
|
||||
ipConf, err := ipam.ExecPlugin(n.Net.IPAM.Type)
|
||||
ipConf, err := ipam.ExecPluginAdd(n.Net.IPAM.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -211,9 +219,19 @@ func cmdAdd(contID, netns, netConf, ifName string) error {
|
||||
}
|
||||
|
||||
func cmdDel(contID, netns, netConf, ifName string) error {
|
||||
return util.WithNetNSPath(netns, func(hostNS *os.File) error {
|
||||
n, err := loadConf(netConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = util.WithNetNSPath(netns, func(hostNS *os.File) error {
|
||||
return util.DelLinkByName(ifName)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ipam.ExecPluginDel(n.Net.IPAM.Type)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -44,7 +44,7 @@ func cmdAdd(contID, netns, netConf, ifName, args string) error {
|
||||
}
|
||||
|
||||
// run the IPAM plugin and get back the config to apply
|
||||
ipConf, err := ipam.ExecPlugin(conf.IPAM.Type)
|
||||
ipConf, err := ipam.ExecPluginAdd(conf.IPAM.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -96,9 +96,19 @@ func cmdAdd(contID, netns, netConf, ifName, args string) error {
|
||||
}
|
||||
|
||||
func cmdDel(contID, netns, netConf, ifName, args string) error {
|
||||
return util.WithNetNSPath(netns, func(hostNS *os.File) error {
|
||||
conf := rktnet.Net{}
|
||||
if err := rktnet.LoadNet(netConf, &conf); err != nil {
|
||||
return fmt.Errorf("failed to load %q: %v", netConf, err)
|
||||
}
|
||||
|
||||
err := util.WithNetNSPath(netns, func(hostNS *os.File) error {
|
||||
return util.DelLinkByName(ifName)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ipam.ExecPluginDel(conf.IPAM.Type)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -182,7 +182,7 @@ func (e *containerEnv) setupNets(netns string, nets []Net) ([]activeNet, error)
|
||||
ifName: fmt.Sprintf(ifnamePattern, i),
|
||||
}
|
||||
|
||||
log.Printf("Executing net-plugin %v", nt.Type)
|
||||
log.Printf("Setup: executing net-plugin %v", nt.Type)
|
||||
|
||||
an.ip, err = e.netPluginAdd(&nt, netns, nt.args, an.ifName)
|
||||
if err != nil {
|
||||
@@ -193,8 +193,6 @@ func (e *containerEnv) setupNets(netns string, nets []Net) ([]activeNet, error)
|
||||
active = append(active, an)
|
||||
}
|
||||
|
||||
log.Print("Done executing net plugins")
|
||||
|
||||
if err != nil {
|
||||
e.teardownNets(netns, active)
|
||||
return nil, err
|
||||
@@ -206,6 +204,8 @@ func (e *containerEnv) setupNets(netns string, nets []Net) ([]activeNet, error)
|
||||
func (e *containerEnv) teardownNets(netns string, nets []activeNet) {
|
||||
for i := len(nets) - 1; i >= 0; i-- {
|
||||
nt := nets[i]
|
||||
|
||||
log.Printf("Teardown: executing net-plugin %v", nt.Type)
|
||||
err := e.netPluginDel(&nt.Net, netns, nt.args, nt.ifName)
|
||||
if err != nil {
|
||||
log.Printf("Error deleting %q: %v", nt.Name, err)
|
||||
|
||||
Reference in New Issue
Block a user