Skip to content

Commit

Permalink
allow templating the ceos startup-config
Browse files Browse the repository at this point in the history
  • Loading branch information
hellt committed Jul 19, 2021
1 parent 97e0ef3 commit a619aff
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 10 deletions.
28 changes: 27 additions & 1 deletion docs/manual/kinds/ceos.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ cEOS nodes have a dedicated [`config`](../conf-artifacts.md#identifying-a-lab-di
used as a startup config instead.

#### Default node configuration
When a node is defined without `config` statement present, containerlab will generate an empty config from [this template](https://github.com/srl-labs/containerlab/blob/master/nodes/crpd/crpd.cfg) and copy it to the config directory of the node.
When a node is defined without `config` statement present, containerlab will generate an empty config from [this template](https://github.com/srl-labs/containerlab/blob/master/nodes/ceos/ceos.cfg) and copy it to the config directory of the node.

```yaml
# example of a topo file that does not define a custom config
Expand Down Expand Up @@ -142,6 +142,31 @@ When a config file is passed via `config` parameter, it will override any config

With such topology file containerlab is instructed to take a file `myconfig.conf` from the current working directory, copy it to the lab directory for that specific node under the `/flash/startup-config` name and mount that dir to the container. This will result in this config to act as a startup config for the node.

It is possible to change the default config which every ceos node will start with with the following steps:

1. Save the [default configuration template](https://github.com/srl-labs/containerlab/blob/master/nodes/ceos/ceos.cfg) under some local file name[^2] and add the necessary changes to it
2. Use this file as a startup-config for ceos kind:
```
name: ceos
topology:
kinds:
ceos:
startup-config: ceos-custom-startup.cfg
nodes:
# ceos1 will boot with ceos-custom-startup.cfg as set in the kind parameters
ceos1:
kind: ceos
image: ceos:4.25.0F
# ceos2 will boot with its own specific startup config, as it overrides the kind variables
ceos2:
kind: ceos
image: ceos:4.25.0F
startup-config: node-specific-startup.cfg
links:
- endpoints: ["ceos1:eth1", "ceos2:eth1"]
```

#### Configuration persistency

It is important to understand how configuration persistency behaves when a single lab is going through rounds of `deploy->destroy` actions.
Expand Down Expand Up @@ -221,3 +246,4 @@ As of this writing (22-June, 2021), ceos-lab image requires a cgroups v1 environ
Consult your distribution's documentation for details regarding configuring cgroups v1 in case you see similar startup issues as indicated in [#467](https://github.com/srl-labs/containerlab/issues/467).

[^1]: https://eos.arista.com/ceos-lab-topo/
[^2]: do not remove the template variables from the `Management0` interface, otherwise the nodes will not apply the IP address from docker IPAM service.
28 changes: 19 additions & 9 deletions nodes/ceos/ceos.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package ceos

import (
"bytes"
"context"
_ "embed"
"fmt"
Expand Down Expand Up @@ -141,38 +142,47 @@ func createCEOSFiles(node *types.NodeConfig) error {
return nil
}

func ceosPostDeploy(ctx context.Context, r runtime.ContainerRuntime, nodeCfg *types.NodeConfig) error {
func ceosPostDeploy(ctx context.Context, r runtime.ContainerRuntime, node *types.NodeConfig) error {
// post deploy actions are not needed if a user specified startup config was provided
if nodeCfg.StartupConfig != "" {
return nil
// and it doesn't have templation vars for ipv4 management address
if node.StartupConfig != "" {
c, err := os.ReadFile(node.StartupConfig)
if err != nil {
return err
}
if !bytes.Contains(c, []byte("{{ if .MgmtIPv4Address }}")) {
return nil
}

cfgTemplate = string(c)
}

// regenerate ceos config since it is now known which IP address docker assigned to this container
err := nodeCfg.GenerateConfig(nodeCfg.ResStartupConfig, cfgTemplate)
err := node.GenerateConfig(node.ResStartupConfig, cfgTemplate)
if err != nil {
return err
}

err = r.StopContainer(ctx, nodeCfg.ContainerID)
err = r.StopContainer(ctx, node.ContainerID)
if err != nil {
return err
}
// remove the netns symlink created during original start
// we will re-symlink it later
if err := utils.DeleteNetnsSymlink(nodeCfg.LongName); err != nil {
if err := utils.DeleteNetnsSymlink(node.LongName); err != nil {
return err
}

err = r.StartContainer(ctx, nodeCfg.ContainerID)
err = r.StartContainer(ctx, node.ContainerID)
if err != nil {
return err
}
nodeCfg.NSPath, err = r.GetNSPath(ctx, nodeCfg.ContainerID)
node.NSPath, err = r.GetNSPath(ctx, node.ContainerID)
if err != nil {
return err
}

return utils.LinkContainerNS(nodeCfg.NSPath, nodeCfg.LongName)
return utils.LinkContainerNS(node.NSPath, node.LongName)
}

func (s *ceos) GetImages() map[string]string {
Expand Down

0 comments on commit a619aff

Please sign in to comment.