Skip to content

Commit

Permalink
added user configuration for containers (#224)
Browse files Browse the repository at this point in the history
* added user configuration

* documented cmd option
  • Loading branch information
hellt committed Jan 10, 2021
1 parent e94d9e7 commit 5f28d76
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 3 deletions.
25 changes: 22 additions & 3 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ type NodeConfig struct {
MgmtIPv4 string `yaml:"mgmt_ipv4,omitempty"` // user-defined IPv4 address in the management network
MgmtIPv6 string `yaml:"mgmt_ipv6,omitempty"` // user-defined IPv6 address in the management network

Env map[string]string `yaml:"env,omitempty"` // environment variables
Env map[string]string `yaml:"env,omitempty"` // environment variables
User string `yaml:"user,omitempty"` // linux user used in a container
}

// Topology represents a lab topology
Expand Down Expand Up @@ -325,6 +326,20 @@ func (c *cLab) positionInitialization(nodeCfg *NodeConfig, kind string) string {
return c.Config.Topology.Defaults.Position
}

func (c *cLab) userInit(nodeCfg *NodeConfig, kind string) string {
switch {
case nodeCfg.User != "":
return nodeCfg.User

case c.Config.Topology.Kinds[kind].User != "":
return c.Config.Topology.Kinds[kind].User

case c.Config.Topology.Defaults.User != "":
return c.Config.Topology.Defaults.User
}
return ""
}

// NewNode initializes a new node object
func (c *cLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error {
// initialize a new node
Expand Down Expand Up @@ -361,6 +376,8 @@ func (c *cLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error {
// initialize passed env variables which will be merged with kind specific ones
envs := c.envInit(&nodeCfg, node.Kind)

user := c.userInit(&nodeCfg, node.Kind)

switch node.Kind {
case "ceos":
// initialize the global parameters with defaults, can be overwritten later
Expand All @@ -383,7 +400,7 @@ func (c *cLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error {
"MGMT_INTF": "eth0"}
node.Env = mergeStringMaps(kindEnv, envs)

node.User = "root"
node.User = user
node.Group = c.groupInitialization(&nodeCfg, node.Kind)
node.NodeType = nodeCfg.Type

Expand Down Expand Up @@ -431,10 +448,11 @@ func (c *cLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error {

// initialize specifc container information
node.Cmd = "sudo bash -c /opt/srlinux/bin/sr_linux"

kindEnv := map[string]string{"SRLINUX": "1"}
node.Env = mergeStringMaps(kindEnv, envs)

node.User = "root"
node.User = user

node.Sysctls = make(map[string]string)
node.Sysctls["net.ipv4.ip_forward"] = "0"
Expand Down Expand Up @@ -468,6 +486,7 @@ func (c *cLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error {
node.NodeType = c.typeInit(&nodeCfg, node.Kind)
node.Position = c.positionInitialization(&nodeCfg, node.Kind)
node.Cmd = c.cmdInit(&nodeCfg, node.Kind)
node.User = user

node.Sysctls = make(map[string]string)
node.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0"
Expand Down
48 changes: 48 additions & 0 deletions clab/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,51 @@ func TestEnvInit(t *testing.T) {
})
}
}

func TestUserInit(t *testing.T) {
tests := map[string]struct {
got string
node string
want string
}{
"user_defined_at_node_level": {
got: "test_data/topo1.yml",
node: "node2",
want: "custom",
},
"user_defined_at_kind_level": {
got: "test_data/topo2.yml",
node: "node2",
want: "customkind",
},
"user_defined_at_defaults_level": {
got: "test_data/topo3.yml",
node: "node1",
want: "customglobal",
},
"user_defined_at_node_and_kind_and_default_level": {
got: "test_data/topo4.yml",
node: "node1",
want: "customnode",
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
WithTopoFile(tc.got),
}
c := NewContainerLab(opts...)
if err := c.ParseTopology(); err != nil {
t.Fatal(err)
}

nodeCfg := c.Config.Topology.Nodes[tc.node]
kind := strings.ToLower(c.kindInitialization(&nodeCfg))
user := c.userInit(&nodeCfg, kind)
if user != tc.want {
t.Fatalf("wanted %q got %q", tc.want, user)
}
})
}
}
1 change: 1 addition & 0 deletions clab/test_data/topo1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ topology:
node2:
kind: srl
license: node1.lic
user: custom
1 change: 1 addition & 0 deletions clab/test_data/topo2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ topology:
type: ixrd2
env:
env1: val1
user: customkind
nodes:
node1:
kind: srl
Expand Down
1 change: 1 addition & 0 deletions clab/test_data/topo3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ topology:
type: ixrd2
env:
env1: val1
user: customglobal
nodes:
node1:
kind: srl
Expand Down
3 changes: 3 additions & 0 deletions clab/test_data/topo4.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ topology:
env1: global
env2: global
env3: global
user: customglobal
kinds:
srl:
license: kind.lic
Expand All @@ -16,6 +17,7 @@ topology:
env:
env2: kind
env4: kind
user: customkind
nodes:
node1:
kind: srl
Expand All @@ -26,3 +28,4 @@ topology:
env:
env1: node
env5: node
user: customnode
34 changes: 34 additions & 0 deletions docs/manual/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ topology:
- 80:8080
- 55555:43555/udp
- 55554:43554/tcp
user: test
env:
ENV1: VAL1
cmd: /bin/bash script.sh
```

### kind
Expand Down Expand Up @@ -107,4 +111,34 @@ topology:
node1:
env:
ENV1: 1 # ENV1=1 will be set for node1
```

### user
To set a user which will be used to run a containerized process use the `user` configuration option. Can be defined at `node`, `kind` and `global` levels.

```yaml
topology:
defaults:
user: alice # alice user will be used for all nodes unless set on kind or node levels
kinds:
srl:
user: bob # bob user will be used for nodes of kind srl unless it is set on node level
nodes:
node1:
user: clab # clab user will be used for node1
```

### cmd
It is possible to set/override the command of the container image with `cmd` configuration option. It accepts the "shell" form and can be set on all levels.

```yaml
topology:
defaults:
cmd: bash cmd.sh
kinds:
srl:
cmd: bash cmd2.sh
nodes:
node1:
cmd: bash cmd3.sh
```

0 comments on commit 5f28d76

Please sign in to comment.