diff --git a/clab/register.go b/clab/register.go index 4437c74d2..efd3bc934 100644 --- a/clab/register.go +++ b/clab/register.go @@ -23,6 +23,7 @@ import ( ovs "github.com/srl-labs/containerlab/nodes/ovs" rare "github.com/srl-labs/containerlab/nodes/rare" sonic "github.com/srl-labs/containerlab/nodes/sonic" + vr_sonic "github.com/srl-labs/containerlab/nodes/sonic_vm" srl "github.com/srl-labs/containerlab/nodes/srl" vr_aoscx "github.com/srl-labs/containerlab/nodes/vr_aoscx" vr_c8000v "github.com/srl-labs/containerlab/nodes/vr_c8000v" @@ -43,7 +44,6 @@ import ( vr_vsrx "github.com/srl-labs/containerlab/nodes/vr_vsrx" vr_xrv "github.com/srl-labs/containerlab/nodes/vr_xrv" vr_xrv9k "github.com/srl-labs/containerlab/nodes/vr_xrv9k" - vr_sonic "github.com/srl-labs/containerlab/nodes/vr_sonic" xrd "github.com/srl-labs/containerlab/nodes/xrd" ) diff --git a/docs/manual/kinds/sonic-vm.md b/docs/manual/kinds/sonic-vm.md new file mode 100644 index 000000000..8abc03c05 --- /dev/null +++ b/docs/manual/kinds/sonic-vm.md @@ -0,0 +1,49 @@ +--- +search: + boost: 4 +--- +# SONiC (VM) + +[SONiC](https://sonic-net.github.io/SONiC/) Network OS is distributed in two formats suitable for testing with containerlab + +1. Containerized SONiC +2. Virtual Machine SONiC (topic of this document) + +This document covers the containerized SONiC that is identified with `sonic-vs` kind in the [topology file](../topo-def-file.md). A kind defines a supported feature set and a startup procedure of a `sonic-vs` node. + +## Getting Sonic images + +Getting SONiC images is possible via two resources: + +1. [Sonic.software](https://sonic.software/) -- an unofficial repo with SONiC images +2. [Azure pipeline](https://dev.azure.com/mssonic/build/_build) -- an official source of SONiC images, but finding the right one there is a pita. + +## Managing sonic-vs nodes + +SONiC node launched with containerlab can be managed via the following interfaces: + +/// tab | bash +to connect to a `bash` shell of a running sonic-vs container: + +```bash +docker exec -it bash +``` + +/// +/// tab | CLI +to connect to the sonic-vs CLI (vtysh) + +```bash +docker exec -it vtysh +``` + +/// + +## Interfaces mapping + +sonic-vs container uses the following mapping for its linux interfaces: + +* `eth0` - management interface connected to the containerlab management network +* `eth1` - first data (front-panel port) interface + +When containerlab launches sonic-vs node, it will assign IPv4/6 address to the `eth0` interface. Data interface `eth1` mapped to `Ethernet0` port and needs to be configured with IP addressing manually. See Lab examples for exact configurations. diff --git a/docs/manual/kinds/sonic-vs.md b/docs/manual/kinds/sonic-vs.md index f11fa74cc..bd0cbd3b0 100644 --- a/docs/manual/kinds/sonic-vs.md +++ b/docs/manual/kinds/sonic-vs.md @@ -2,40 +2,45 @@ search: boost: 4 --- -# SONiC +# SONiC (container) -[SONiC](https://sonic-net.github.io/SONiC/) is identified with `sonic-vs` kind in the [topology file](../topo-def-file.md). A kind defines a supported feature set and a startup procedure of a `sonic-vs` node. +[SONiC](https://sonic-net.github.io/SONiC/) Network OS is distributed in two formats suitable for testing with containerlab -!!!note - To build a `sonic-vs` docker image: +1. Containerized SONiC (topic of this document) +2. Virtual Machine SONiC - 1. Leverage [automated scripts](https://github.com/antongisli/sonic-builder) provided by @antongisli - 2. or consult with the [SONiC build documentation](https://github.com/Azure/sonic-buildimage/blob/master/README.md#usage) and create the docker images with `PLATFORM=vs` yourself. - - -sonic-vs nodes launched with containerlab come without any additional configuration. +This document covers the containerized SONiC that is identified with `sonic-vs` kind in the [topology file](../topo-def-file.md). A kind defines a supported feature set and a startup procedure of a `sonic-vs` node. ## Getting Sonic images -Apparently, it is still tricky to find sonic container images, as their prime distribution format is a VM. [Several discussions](https://github.com/srl-labs/containerlab/pull/545#issuecomment-998205602) happened around creating a container build pipeline and a [few projects](https://github.com/antongisli/sonic-builder) were created. -One of the latest known working images can be found [here](https://hub.docker.com/r/netreplica/docker-sonic-vs). +Getting SONiC images is possible via two resources: + +1. [Sonic.software](https://sonic.software/) -- an unofficial repo with SONiC images +2. [Azure pipeline](https://dev.azure.com/mssonic/build/_build) -- an official source of SONiC images, but finding the right one there is a pita. ## Managing sonic-vs nodes + SONiC node launched with containerlab can be managed via the following interfaces: -=== "bash" - to connect to a `bash` shell of a running sonic-vs container: - ```bash - docker exec -it bash - ``` -=== "CLI" - to connect to the sonic-vs CLI (vtysh) - ```bash - docker exec -it vtysh - ``` +/// tab | bash +to connect to a `bash` shell of a running sonic-vs container: + +```bash +docker exec -it bash +``` +/// +/// tab | CLI +to connect to the sonic-vs CLI (vtysh) + +```bash +docker exec -it vtysh +``` + +/// ## Interfaces mapping + sonic-vs container uses the following mapping for its linux interfaces: * `eth0` - management interface connected to the containerlab management network @@ -44,6 +49,7 @@ sonic-vs container uses the following mapping for its linux interfaces: When containerlab launches sonic-vs node, it will assign IPv4/6 address to the `eth0` interface. Data interface `eth1` mapped to `Ethernet0` port and needs to be configured with IP addressing manually. See Lab examples for exact configurations. ## Lab examples + The following labs feature sonic-vs node: -- [SR Linux and sonic-vs](../../lab-examples/srl-sonic.md) +* [SR Linux and sonic-vs](../../lab-examples/srl-sonic.md) diff --git a/mkdocs.yml b/mkdocs.yml index 3d9f9142d..f52c5faef 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,7 +30,9 @@ nav: - Cisco FTDv: manual/kinds/vr-ftdv.md - Cumulus VX: manual/kinds/cvx.md - Aruba AOS-CX: manual/kinds/vr-aoscx.md - - SONiC: manual/kinds/sonic-vs.md + - SONiC: + - Container: manual/kinds/sonic-vs.md + - VM: manual/kinds/sonic-vm.md - Dell FTOS10v: manual/kinds/vr-ftosv.md - MikroTik RouterOS: manual/kinds/vr-ros.md - IPInfusion OcNOS: manual/kinds/ipinfusion-ocnos.md diff --git a/nodes/vr_sonic/vr-sonic.go b/nodes/sonic_vm/sonic_vm.go similarity index 58% rename from nodes/vr_sonic/vr-sonic.go rename to nodes/sonic_vm/sonic_vm.go index 391107453..a67919978 100644 --- a/nodes/vr_sonic/vr-sonic.go +++ b/nodes/sonic_vm/sonic_vm.go @@ -3,7 +3,7 @@ // SPDX-License-Identifier: BSD-3-Clause // The author of this code is Adam Kulagowski (adam.kulagowski@codilime.com), CodiLime (codilime.com). -package vr_sonic +package sonic_vm import ( "context" @@ -19,28 +19,28 @@ import ( ) var ( - kindnames = []string{"vr-sonic"} + kindnames = []string{"sonic_vm"} defaultCredentials = nodes.NewCredentials("admin", "admin") ) const ( configDirName = "config" startupCfgFName = "config_db.json" - saveCmd = `sh -c "/backup.sh -u $USERNAME -p $PASSWORD backup"` + saveCmd = `sh -c "/backup.sh -u $USERNAME -p $PASSWORD backup"` ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { r.Register(kindnames, func() nodes.Node { - return new(vrSONiC) + return new(sonic_vm) }, defaultCredentials) } -type vrSONiC struct { +type sonic_vm struct { nodes.DefaultNode } -func (n *vrSONiC) Init(cfg *types.NodeConfig, opts ...nodes.NodeOption) error { +func (n *sonic_vm) Init(cfg *types.NodeConfig, opts ...nodes.NodeOption) error { // Init DefaultNode n.DefaultNode = *nodes.NewDefaultNode(n) // set virtualization requirement @@ -63,50 +63,46 @@ func (n *vrSONiC) Init(cfg *types.NodeConfig, opts ...nodes.NodeOption) error { // mount config dir to support startup-config functionality n.Cfg.Binds = append(n.Cfg.Binds, fmt.Sprint(path.Join(n.Cfg.LabDir, configDirName), ":/config")) - if n.Cfg.Env["CONNECTION_MODE"] == "macvtap" { - // mount dev dir to enable macvtap - n.Cfg.Binds = append(n.Cfg.Binds, "/dev:/dev") - } - n.Cfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", - defaultCredentials.GetUsername(), defaultCredentials.GetPassword(), n.Cfg.ShortName, n.Cfg.Env["CONNECTION_MODE"]) + n.Cfg.Env["USERNAME"], n.Cfg.Env["PASSWORD"], n.Cfg.ShortName, n.Cfg.Env["CONNECTION_MODE"]) return nil } -func (n *vrSONiC) PreDeploy(_ context.Context, params *nodes.PreDeployParams) error { +func (n *sonic_vm) PreDeploy(_ context.Context, params *nodes.PreDeployParams) error { utils.CreateDirectory(n.Cfg.LabDir, 0777) _, err := n.LoadOrGenerateCertificate(params.Cert, params.TopologyName) if err != nil { - log.Errorf("Error handling certifcate for %s: %w", n.Cfg.ShortName, err) + log.Errorf("Error handling certifcate for %s: %v", n.Cfg.ShortName, err) + return nil } return nodes.LoadStartupConfigFileVr(n, configDirName, startupCfgFName) } -func (n *vrSONiC) SaveConfig(ctx context.Context) error { - cmd, err := exec.NewExecCmdFromString(saveCmd) - if err != nil { - return fmt.Errorf("%s: failed to create execute cmd: %w", n.Cfg.ShortName, err) - } +func (n *sonic_vm) SaveConfig(ctx context.Context) error { + cmd, err := exec.NewExecCmdFromString(saveCmd) + if err != nil { + return fmt.Errorf("%s: failed to create execute cmd: %w", n.Cfg.ShortName, err) + } - execResult, err := n.RunExec(ctx, cmd) - if err != nil { - return fmt.Errorf("%s: failed to execute cmd: %w", n.Cfg.ShortName, err) - } + execResult, err := n.RunExec(ctx, cmd) + if err != nil { + return fmt.Errorf("%s: failed to execute cmd: %w", n.Cfg.ShortName, err) + } - if len(execResult.GetStdErrString()) > 0 { - return fmt.Errorf("%s errors: %s", n.Cfg.ShortName, execResult.GetStdErrString()) - } + if len(execResult.GetStdErrString()) > 0 { + return fmt.Errorf("%s errors: %s", n.Cfg.ShortName, execResult.GetStdErrString()) + } - confPath := n.Cfg.LabDir + "/" + configDirName - log.Infof("saved /etc/sonic/config_db.json backup from %s node to %s\n", n.Cfg.ShortName, confPath) + confPath := n.Cfg.LabDir + "/" + configDirName + log.Infof("saved /etc/sonic/config_db.json backup from %s node to %s\n", n.Cfg.ShortName, confPath) - return nil + return nil } // CheckInterfaceName checks if a name of the interface referenced in the topology file correct. -func (n *vrSONiC) CheckInterfaceName() error { +func (n *sonic_vm) CheckInterfaceName() error { return nodes.GenericVMInterfaceCheck(n.Cfg.ShortName, n.Endpoints) } diff --git a/schemas/clab.schema.json b/schemas/clab.schema.json index d94dc6019..3ffacf7f1 100644 --- a/schemas/clab.schema.json +++ b/schemas/clab.schema.json @@ -38,6 +38,7 @@ "crpd", "juniper_crpd", "sonic-vs", + "sonic-vm", "vr-sros", "nokia_sros", "vr-nokia_sros", @@ -884,6 +885,9 @@ "sonic-vs": { "$ref": "#/definitions/node-config" }, + "sonic-vm": { + "$ref": "#/definitions/node-config" + }, "vr-nokia_sros": { "$ref": "#/definitions/node-config" },