github.com/john-lin/cni@v0.6.0-rc1.0.20170712150331-b69e640cc0e2/cnitool/cni.go (about)

     1  // Copyright 2015 CNI authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"os"
    21  	"path/filepath"
    22  	"strings"
    23  
    24  	"github.com/containernetworking/cni/libcni"
    25  )
    26  
    27  const (
    28  	EnvCNIPath        = "CNI_PATH"
    29  	EnvNetDir         = "NETCONFPATH"
    30  	EnvCapabilityArgs = "CAP_ARGS"
    31  	EnvCNIArgs        = "CNI_ARGS"
    32  
    33  	DefaultNetDir = "/etc/cni/net.d"
    34  
    35  	CmdAdd = "add"
    36  	CmdDel = "del"
    37  )
    38  
    39  func parseArgs(args string) ([][2]string, error) {
    40  	var result [][2]string
    41  
    42  	pairs := strings.Split(args, ";")
    43  	for _, pair := range pairs {
    44  		kv := strings.Split(pair, "=")
    45  		if len(kv) != 2 || kv[0] == "" || kv[1] == "" {
    46  			return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair)
    47  		}
    48  
    49  		result = append(result, [2]string{kv[0], kv[1]})
    50  	}
    51  
    52  	return result, nil
    53  }
    54  
    55  func main() {
    56  	if len(os.Args) < 3 {
    57  		usage()
    58  		return
    59  	}
    60  
    61  	netdir := os.Getenv(EnvNetDir)
    62  	if netdir == "" {
    63  		netdir = DefaultNetDir
    64  	}
    65  	netconf, err := libcni.LoadConfList(netdir, os.Args[2])
    66  	if err != nil {
    67  		exit(err)
    68  	}
    69  
    70  	var capabilityArgs map[string]interface{}
    71  	capabilityArgsValue := os.Getenv(EnvCapabilityArgs)
    72  	if len(capabilityArgsValue) > 0 {
    73  		if err = json.Unmarshal([]byte(capabilityArgsValue), &capabilityArgs); err != nil {
    74  			exit(err)
    75  		}
    76  	}
    77  
    78  	var cniArgs [][2]string
    79  	args := os.Getenv(EnvCNIArgs)
    80  	if len(args) > 0 {
    81  		cniArgs, err = parseArgs(args)
    82  		if err != nil {
    83  			exit(err)
    84  		}
    85  	}
    86  
    87  	netns := os.Args[3]
    88  
    89  	cninet := &libcni.CNIConfig{
    90  		Path: filepath.SplitList(os.Getenv(EnvCNIPath)),
    91  	}
    92  
    93  	rt := &libcni.RuntimeConf{
    94  		ContainerID:    "cni",
    95  		NetNS:          netns,
    96  		IfName:         "eth0",
    97  		Args:           cniArgs,
    98  		CapabilityArgs: capabilityArgs,
    99  	}
   100  
   101  	switch os.Args[1] {
   102  	case CmdAdd:
   103  		result, err := cninet.AddNetworkList(netconf, rt)
   104  		if result != nil {
   105  			_ = result.Print()
   106  		}
   107  		exit(err)
   108  	case CmdDel:
   109  		exit(cninet.DelNetworkList(netconf, rt))
   110  	}
   111  }
   112  
   113  func usage() {
   114  	exe := filepath.Base(os.Args[0])
   115  
   116  	fmt.Fprintf(os.Stderr, "%s: Add or remove network interfaces from a network namespace\n", exe)
   117  	fmt.Fprintf(os.Stderr, "  %s %s <net> <netns>\n", exe, CmdAdd)
   118  	fmt.Fprintf(os.Stderr, "  %s %s <net> <netns>\n", exe, CmdDel)
   119  	os.Exit(1)
   120  }
   121  
   122  func exit(err error) {
   123  	if err != nil {
   124  		fmt.Fprintf(os.Stderr, "%s\n", err)
   125  		os.Exit(1)
   126  	}
   127  	os.Exit(0)
   128  }