Skip to content

Commit

Permalink
IPAM config through cni network config
Browse files Browse the repository at this point in the history
This commit introduces configurable IPAM setting
for cni configs. This would allow used to configure the
network level ipam configs in the cni config

Signed-off-by: Abhinandan Prativadi <[email protected]>
  • Loading branch information
abhi committed Oct 12, 2017
1 parent 312cda7 commit 5fa7fd9
Show file tree
Hide file tree
Showing 13 changed files with 412 additions and 378 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ build-local:
@mkdir -p "bin"
go build -tags experimental -o "bin/dnet" ./cmd/dnet
go build -o "bin/docker-proxy" ./cmd/proxy
go build -o "bin/cniserver" ./pkg/server
go build -o "bin/cniserver" ./cmd/cni_
go build -o "bin/cnictl" ./cni/
clean:
@echo "🐳 $@"
Expand Down
36 changes: 36 additions & 0 deletions cmd/cni_/cni_.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"io"
"os"

"github.com/codegangsta/cli"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/docker/pkg/term"
"github.com/sirupsen/logrus"
)

func main() {
if reexec.Init() {
return
}
_, stdout, stderr := term.StdStreams()
logrus.SetOutput(stderr)
err := cniApp(stdout, stderr)
if err != nil {
os.Exit(1)
}
}

func cniApp(stdout, stderr io.Writer) error {
app := cli.NewApp()

app.Name = "cniserver"
app.Usage = "A cni side car for libnetwork daemon."
app.Flags = cniserverFlags
app.Before = processFlags
//app.Commands = cniCommands

app.Run(os.Args)
return nil
}
54 changes: 54 additions & 0 deletions cmd/cni_/flags_.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"fmt"
"os"

"github.com/codegangsta/cli"
cniserver "github.com/docker/libnetwork/pkg/server/cniserver"
"github.com/sirupsen/logrus"
)

var (
cniserverFlags = []cli.Flag{
cli.StringFlag{
Name: "sock",
Value: "/var/run/cniserver.sock",
Usage: "path to the socket file on which cniserver listens. Default (/var/run/cni-libnetwork.sock)",
},
cli.StringFlag{
Name: "dnet-port",
Value: "2389",
Usage: "Daemon socket to connect to. Default(2389)",
},
cli.StringFlag{
Name: "dnet-address",
Value: "127.0.0.1",
Usage: "Daemon IP address to connect to",
},
cli.BoolFlag{
Name: "D, -debug",
Usage: "Enable debug mode",
},
}
)

func processFlags(c *cli.Context) error {
var err error

if c.Bool("D") {
logrus.SetLevel(logrus.DebugLevel)
}

cniService, err := cniserver.NewCniService(c.String("sock"), c.String("dnet-address"), c.String("dnet-port"))
if err != nil {
return fmt.Errorf("faile to create cni service: %v", err)
}
serverCloseChan := make(chan struct{})
if err := cniService.InitCniService(serverCloseChan); err != nil {
fmt.Printf("Failed to initialize CNI server: \n", err)
os.Exit(1)
}
<-serverCloseChan
return nil
}
26 changes: 5 additions & 21 deletions cmd/dnet/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"

"github.com/codegangsta/cli"
"github.com/docker/docker/pkg/term"
"github.com/docker/libnetwork/client"
"github.com/docker/libnetwork/netutils"
)

var (
Expand Down Expand Up @@ -49,7 +47,7 @@ func runContainerCreate(c *cli.Context) {
}

sc := client.SandboxCreate{ContainerID: c.Args()[0]}
obj, _, err := readBody(epConn.httpCall("POST", "/sandboxes", sc, nil))
obj, _, err := netutils.ReadBody(epConn.conn.HttpCall("POST", "/sandboxes", sc, nil))
if err != nil {
fmt.Printf("POST failed during create container: %v\n", err)
os.Exit(1)
Expand All @@ -74,7 +72,7 @@ func runContainerRm(c *cli.Context) {
os.Exit(1)
}

obj, _, err := readBody(epConn.httpCall("GET", "/sandboxes?partial-container-id="+c.Args()[0], nil, nil))
obj, _, err := netutils.ReadBody(epConn.conn.HttpCall("GET", "/sandboxes?partial-container-id="+c.Args()[0], nil, nil))
if err != nil {
fmt.Printf("GET failed during container id lookup: %v\n", err)
os.Exit(1)
Expand All @@ -91,7 +89,7 @@ func runContainerRm(c *cli.Context) {
os.Exit(1)
}

_, _, err = readBody(epConn.httpCall("DELETE", "/sandboxes/"+sbList[0].ID, nil, nil))
_, _, err = netutils.ReadBody(epConn.conn.HttpCall("DELETE", "/sandboxes/"+sbList[0].ID, nil, nil))
if err != nil {
fmt.Printf("DELETE of sandbox id %s failed: %v", sbList[0].ID, err)
os.Exit(1)
Expand All @@ -100,7 +98,7 @@ func runContainerRm(c *cli.Context) {

func runDockerCommand(c *cli.Context, cmd string) {
_, stdout, stderr := term.StdStreams()
oldcli := client.NewNetworkCli(stdout, stderr, epConn.httpCall)
oldcli := client.NewNetworkCli(stdout, stderr, epConn.conn.HttpCall)
var args []string
args = append(args, cmd)
if c.Bool("h") {
Expand Down Expand Up @@ -130,17 +128,3 @@ func createDockerCommand(cmd string) cli.Command {
},
}
}

func readBody(stream io.ReadCloser, hdr http.Header, statusCode int, err error) ([]byte, int, error) {
if stream != nil {
defer stream.Close()
}
if err != nil {
return nil, statusCode, err
}
body, err := ioutil.ReadAll(stream)
if err != nil {
return nil, -1, err
}
return body, statusCode, nil
}
117 changes: 29 additions & 88 deletions cmd/dnet/dnet.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -96,10 +94,10 @@ func (d *dnetConnection) parseConfig(cfgFile string) (*config.Config, error) {
return config.ParseConfig(cfgFile)
}

func processConfig(cfg *config.Config) []config.Option {
func processConfig(cfg *config.Config) ([]config.Option, error) {
options := []config.Option{}
if cfg == nil {
return options
return options, nil
}

dn := "bridge"
Expand Down Expand Up @@ -131,14 +129,19 @@ func processConfig(cfg *config.Config) []config.Option {
options = append(options, config.OptionDataDir(cfg.Daemon.DataDir))
}

dOptions, err := startDiscovery(&cfg.Cluster)
if err != nil {
logrus.Infof("Skipping discovery : %s", err.Error())
} else {
options = append(options, dOptions...)
// Retry discovery for 2 minutes before exiting
for {
select {
case <-time.After(2 * time.Minute):
return nil, fmt.Errorf("failed to initialize discovery")
default:
dOptions, err := startDiscovery(&cfg.Cluster)
if err == nil {
options = append(options, dOptions...)
return options, nil
}
}
}

return options
}

func startDiscovery(cfg *config.ClusterCfg) ([]config.Option, error) {
Expand Down Expand Up @@ -238,10 +241,7 @@ func createDefaultNetwork(c libnetwork.NetworkController) {
}

type dnetConnection struct {
// proto holds the client protocol i.e. unix.
proto string
// addr holds the client address.
addr string
conn *netutils.HttpConnection
Orchestration *NetworkOrchestration
configEvent chan cluster.ConfigEventType
}
Expand All @@ -262,9 +262,12 @@ func (d *dnetConnection) dnetDaemon(cfgFile string) error {
cfg, err := d.parseConfig(cfgFile)
var cOptions []config.Option
if err == nil {
cOptions = processConfig(cfg)
cOptions, err = processConfig(cfg)
if err != nil {
fmt.Errorf("failed to process config: %v", err)
}
} else {
logrus.Errorf("Error parsing config %v", err)
logrus.Errorf("failed to parse config: %v", err)
}

bridgeConfig := options.Generic{
Expand Down Expand Up @@ -306,7 +309,7 @@ func (d *dnetConnection) dnetDaemon(cfgFile string) error {
handleSignals(controller)
setupDumpStackTrap()

return http.ListenAndServe(d.addr, r)
return http.ListenAndServe(d.conn.Addr, r)
}

func (d *dnetConnection) IsManager() bool {
Expand Down Expand Up @@ -436,76 +439,14 @@ func newDnetConnection(val string) (*dnetConnection, error) {
return nil, errors.New("dnet currently only supports tcp transport")
}

return &dnetConnection{protoAddrParts[0], protoAddrParts[1], &NetworkOrchestration{}, make(chan cluster.ConfigEventType, 10)}, nil
}

func (d *dnetConnection) httpCall(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
var in io.Reader
in, err := encodeData(data)
if err != nil {
return nil, nil, -1, err
}

req, err := http.NewRequest(method, fmt.Sprintf("%s", path), in)
if err != nil {
return nil, nil, -1, err
}

setupRequestHeaders(method, data, req, headers)

req.URL.Host = d.addr
req.URL.Scheme = "http"
fmt.Printf("Requesting http: %+v", req)
httpClient := &http.Client{}
resp, err := httpClient.Do(req)
statusCode := -1
if resp != nil {
statusCode = resp.StatusCode
}
if err != nil {
return nil, nil, statusCode, fmt.Errorf("error when trying to connect: %v", err)
}

if statusCode < 200 || statusCode >= 400 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, nil, statusCode, err
}
return nil, nil, statusCode, fmt.Errorf("error : %s", bytes.TrimSpace(body))
}

return resp.Body, resp.Header, statusCode, nil
}

func setupRequestHeaders(method string, data interface{}, req *http.Request, headers map[string][]string) {
if data != nil {
if headers == nil {
headers = make(map[string][]string)
}
headers["Content-Type"] = []string{"application/json"}
}

expectedPayload := (method == "POST" || method == "PUT")

if expectedPayload && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain")
}

if headers != nil {
for k, v := range headers {
req.Header[k] = v
}
}
}

func encodeData(data interface{}) (*bytes.Buffer, error) {
params := bytes.NewBuffer(nil)
if data != nil {
if err := json.NewEncoder(params).Encode(data); err != nil {
return nil, err
}
}
return params, nil
return &dnetConnection{
&netutils.HttpConnection{
Proto: protoAddrParts[0],
Addr: protoAddrParts[1],
},
&NetworkOrchestration{},
make(chan cluster.ConfigEventType, 10),
}, nil
}

func ipamOption(bridgeName string) libnetwork.NetworkOption {
Expand Down
14 changes: 7 additions & 7 deletions cni/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ import (
)

func cmdAdd(args *skel.CmdArgs) error {
libClient := cniapi.NewLibNetCniClient()
result, err := libClient.SetupPod(args)
c := cniapi.NewDnetCniClient()
result, err := c.SetupPod(args)
if err != nil {
return fmt.Errorf("Failed to setup Pod , %v", err)
return fmt.Errorf("failed to setup Pod: %v", err)
}
return types.PrintResult(result, version.Current())
}

func cmdDel(args *skel.CmdArgs) error {
libClient := cniapi.NewLibNetCniClient()
if err := libClient.TearDownPod(args); err != nil {
return fmt.Errorf("Failed to tear down pod, %v", err)
c := cniapi.NewDnetCniClient()
if err := c.TearDownPod(args); err != nil {
return fmt.Errorf("failed to tear down pod: %v", err)
}
return nil
}

func main() {
log.Infof("Starting Libnetwork CNI plugin")
log.Infof("Dnet CNI plugin")
skel.PluginMain(cmdAdd, cmdDel, version.PluginSupports("", "0.1.0", "0.2.0", version.Current()))
}
Loading

0 comments on commit 5fa7fd9

Please sign in to comment.