Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create labdir next to clab file #2394

Merged
merged 7 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ tests/out
.python-version

.devcontainer/private-*


# readd test labDir files
!clab/test_data/clab-*
2 changes: 1 addition & 1 deletion clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func (c *CLab) createNodeCfg(nodeName string, nodeDef *types.NodeDefinition, idx
if err != nil {
return nil, err
}
err = c.resolveBindPaths(binds, nodeCfg.LabDir)
err = c.resolveBindPaths(binds, c.TopoPaths.NodeDir(nodeName))
if err != nil {
return nil, err
}
Expand Down
64 changes: 13 additions & 51 deletions clab/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,6 @@ import (
"go.uber.org/mock/gomock"
)

func setupTestCase(t *testing.T) func(t *testing.T) {
// setup function
// create node' labdir with a file that is used in topo2 definition for binds resolver to check path existence
f, _ := filepath.Abs("clab-topo2/node1/somefile")
os.MkdirAll("clab-topo2/node1", 0777) // skipcq: GSC-G301

if _, err := os.Create(f); err != nil {
t.Error(err)
}
// teardown function
return func(t *testing.T) {
os.RemoveAll("clab-topo2")
}
}

func TestLicenseInit(t *testing.T) {
tests := map[string]struct {
got string
Expand All @@ -62,9 +47,6 @@ func TestLicenseInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -96,7 +78,7 @@ func TestBindsInit(t *testing.T) {
want: []string{
"node1.lic:/dst1",
"kind.lic:/dst2",
"${PWD}/clab-topo2/node1/somefile:/somefile",
"${PWD}/test_data/clab-topo2/node1/somefile:/somefile",
},
},
"kind_and_node_binds": {
Expand All @@ -113,9 +95,6 @@ func TestBindsInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -174,9 +153,6 @@ func TestTypeInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -250,9 +226,6 @@ func TestEnvInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
for k, v := range tc.envvar {
Expand Down Expand Up @@ -307,9 +280,6 @@ func TestUserInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -346,9 +316,6 @@ func TestVerifyLinks(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

ctx := context.Background()

for name, tc := range tests {
Expand Down Expand Up @@ -382,6 +349,10 @@ func TestVerifyLinks(t *testing.T) {
}

func TestLabelsInit(t *testing.T) {
owner := os.Getenv("SUDO_USER")
if owner == "" {
owner = os.Getenv("USER")
}
tests := map[string]struct {
got string
node string
Expand All @@ -396,9 +367,9 @@ func TestLabelsInit(t *testing.T) {
labels.NodeKind: "nokia_srlinux",
labels.NodeType: "ixrd2l",
labels.NodeGroup: "",
labels.NodeLabDir: "../clab-topo1/node1",
labels.NodeLabDir: "./clab-topo1/node1",
labels.TopoFile: "topo1.yml",
labels.Owner: "runner",
labels.Owner: owner,
},
},
"custom_node_label": {
Expand All @@ -410,10 +381,10 @@ func TestLabelsInit(t *testing.T) {
labels.NodeKind: "nokia_srlinux",
labels.NodeType: "ixrd2l",
labels.NodeGroup: "",
labels.NodeLabDir: "../clab-topo1/node2",
labels.NodeLabDir: "./clab-topo1/node2",
labels.TopoFile: "topo1.yml",
"node-label": "value",
labels.Owner: "runner",
labels.Owner: owner,
},
},
"custom_kind_label": {
Expand All @@ -425,10 +396,10 @@ func TestLabelsInit(t *testing.T) {
labels.NodeKind: "nokia_srlinux",
labels.NodeType: "ixrd2l",
labels.NodeGroup: "",
labels.NodeLabDir: "../clab-topo2/node1",
labels.NodeLabDir: "./clab-topo2/node1",
labels.TopoFile: "topo2.yml",
"kind-label": "value",
labels.Owner: "runner",
labels.Owner: owner,
},
},
"custom_default_label": {
Expand All @@ -440,17 +411,14 @@ func TestLabelsInit(t *testing.T) {
labels.NodeKind: "nokia_srlinux",
labels.NodeType: "ixrd2l",
labels.NodeGroup: "",
labels.NodeLabDir: "../clab-topo3/node2",
labels.NodeLabDir: "./clab-topo3/node2",
labels.TopoFile: "topo3.yml",
"default-label": "value",
labels.Owner: "runner",
labels.Owner: owner,
},
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -663,9 +631,6 @@ func TestEnvFileInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down Expand Up @@ -755,9 +720,6 @@ func TestStartupConfigInit(t *testing.T) {
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion docs/cmd/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Example command-line usage: `CLAB_VERSION_CHECK=disable containerlab deploy`

To change the [lab directory](../manual/conf-artifacts.md#identifying-a-lab-directory) location, set `CLAB_LABDIR_BASE` environment variable accordingly. It denotes the base directory in which the lab directory will be created.

The default behavior is to create the lab directory in the current working dir.
The default behavior is to create the lab directory in the same directory as the topology file (`clab.yml` file).

### Examples

Expand Down
18 changes: 8 additions & 10 deletions docs/manual/conf-artifacts.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
When containerlab deploys a lab it creates a Lab Directory in the **current working directory**. This directory is used to keep all the necessary files that are needed to run/configure the nodes. We call these files _configuration artifacts_.
# Lab Directory and Configuration Artifacts

When containerlab deploys a lab it creates a Lab Directory in the same directory where your topology (`clab.yml`) file is. This directory is used to keep all the necessary files that are needed to run/configure the nodes. We call these files _configuration artifacts_ and/or lab state files.

Things like:

Expand All @@ -7,15 +9,11 @@ Things like:
* node-specific files and directories that are required to launch the container
* license files if needed

all these artifacts will be available under a Lab Directory.

!!!note
If you configure a node with [`binds`](nodes.md#binds) mounts and the source of the bind is not within the lab directory already, containerlab will copy over the source files/dirs into the lab directory on users behalf.

### Identifying a lab directory
All these artifacts will be available under a Lab Directory.

The lab directory name follows the `clab-<lab_name>` template. Thus, if the name of your lab is `srl02` you will find the `clab-srl02` directory created by default in the current working directory. The location can be altered via the [CLAB_LABDIR_BASE](../cmd/deploy.md#clab_labdir_base) envorinment variable.
## Identifying a Lab Directory

The lab directory name follows the `clab-<lab_name>` template. Thus, if the name of your lab is `srl02` you will find the `clab-srl02` directory created by default in the directory where topology file is located. The location can be changed by setting the [`CLAB_LABDIR_BASE`](../cmd/deploy.md#clab_labdir_base) environment variable.

```
❯ ls -lah clab-srl02
Expand All @@ -29,7 +27,7 @@ drwxr-xr-x 3 root root 79 Dec 1 22:11 srl2

The contents of this directory will contain kind-specific files and directories. Containerlab will name directories after the node names and will only created those if they are needed. For instance, by default any node of kind `linux` will not have it's own directory under the Lab Directory.

### Persistence of a lab directory
### Persistence of a Lab Directory

When a user first deploy a lab, the Lab Directory gets created if it was not present. Depending on a node's kind, this directory might act as a persistent storage area for a node. A common case is having the configuration file saved when the changes are made to the node via management interfaces.

Expand All @@ -48,4 +46,4 @@ When a user destroys a lab without providing the [`--cleanup`](../cmd/destroy.md

Moreover, when the user will deploy the same lab, containerlab will reuse the configuration artifacts if possible, which will, for example, start the nodes with the config files saved from the previous lab run.

To be able to deploy a lab without reusing existing configuration artifact use the [`--reconfigure`](../cmd/deploy.md#reconfigure) flag with `deploy` command. With that setting, containerlab will first delete the Lab Directory and then will start the deployment process.
To be able to deploy a lab without reusing existing configuration artifact use the [`redeploy`](../cmd/redeploy.md) command with `--cleanup` or add [`--reconfigure`](../cmd/deploy.md#reconfigure) flag to the `deploy` command. With that setting, containerlab will first delete the Lab Directory and then will start the deployment process.
8 changes: 4 additions & 4 deletions tests/01-smoke/02-destroy-all.robot
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Deploy first lab
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Exist %{PWD}/clab-2-linux-nodes
Should Exist ${CURDIR}/clab-2-linux-nodes

Set Suite Variable ${orig_dir} ${CURDIR}

Expand All @@ -42,7 +42,7 @@ Deploy second lab
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Exist /tmp/clab-single-node
Should Exist ${CURDIR}/clab-single-node

Inspect ${lab2-name} lab using its name
${rc} ${output} = Run And Return Rc And Output
Expand Down Expand Up @@ -102,7 +102,7 @@ Redeploy second lab
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Exist /tmp/clab-single-node
Should Exist ${CURDIR}/clab-single-node

Destroy all labs
${rc} ${output} = Run And Return Rc And Output
Expand All @@ -116,4 +116,4 @@ Check all labs have been removed
Log ${output}
Should Contain ${output} no containers found
Should Not Exist /tmp/single-node
Should Not Exist %{PWD}/clab-2-linux-nodes
Should Not Exist ${CURDIR}/clab-2-linux-nodes
6 changes: 3 additions & 3 deletions tests/01-smoke/09-external-ca.robot
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ ${ca-keylength} 2048
${runtime} docker

# Node based certs files
${l1-key} ./clab-${lab-name}/.tls/l1/l1.key
${l1-cert} ./clab-${lab-name}/.tls/l1/l1.pem
${l1-key} ${CURDIR}/clab-${lab-name}/.tls/l1/l1.key
${l1-cert} ${CURDIR}/clab-${lab-name}/.tls/l1/l1.pem


*** Test Cases ***
Expand Down Expand Up @@ -64,7 +64,7 @@ Review Node l1 Certificate
Should Contain ${output} Issuer: L = Internet, O = srl-labs, OU = Containerlab, CN = containerlab.dev
Should Contain ${output} Public-Key: (2048 bit)

Verfiy node cert with CA Cert
Verify node cert with CA Cert
${rc} ${output} = Run And Return Rc And Output
... openssl verify -CAfile ${ca-cert-file} ${l1-cert}
Log ${output}
Expand Down
16 changes: 8 additions & 8 deletions tests/01-smoke/10-ca-parameter.robot
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ ${l2-keysize} 1024
${ca-validity-duration} 5 hours

# cert files
${ca-cert-key} ./clab-${lab-name}/.tls/ca/ca.key
${ca-cert-file} ./clab-${lab-name}/.tls/ca/ca.pem
${l1-key} ./clab-${lab-name}/.tls/l1/l1.key
${l1-cert} ./clab-${lab-name}/.tls/l1/l1.pem
${l2-key} ./clab-${lab-name}/.tls/l2/l2.key
${l2-cert} ./clab-${lab-name}/.tls/l2/l2.pem
${l3-key} ./clab-${lab-name}/.tls/l3/l3.key
${l3-cert} ./clab-${lab-name}/.tls/l3/l3.pem
${ca-cert-key} ${CURDIR}/clab-${lab-name}/.tls/ca/ca.key
${ca-cert-file} ${CURDIR}/clab-${lab-name}/.tls/ca/ca.pem
${l1-key} ${CURDIR}/clab-${lab-name}/.tls/l1/l1.key
${l1-cert} ${CURDIR}/clab-${lab-name}/.tls/l1/l1.pem
${l2-key} ${CURDIR}/clab-${lab-name}/.tls/l2/l2.key
${l2-cert} ${CURDIR}/clab-${lab-name}/.tls/l2/l2.pem
${l3-key} ${CURDIR}/clab-${lab-name}/.tls/l3/l3.key
${l3-cert} ${CURDIR}/clab-${lab-name}/.tls/l3/l3.pem


*** Test Cases ***
Expand Down
4 changes: 2 additions & 2 deletions tests/02-basic-srl/01-two-srls.robot
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,14 @@ Verify TLS works with JSON-RPC with skipping certificate check

Verify TLS works with JSON-RPC and certificate check
${rc} ${output} = Run And Return Rc And Output
... curl --cacert ./clab-${lab-name}/.tls/ca/ca.pem 'https://admin:NokiaSrl1!@clab-${lab-name}-srl1/jsonrpc' -d '{"jsonrpc":"2.0","id":0,"method":"get","params":{"commands":[{"path":"/system/information/version","datastore":"state"}]}}'
... curl --cacert ${CURDIR}/clab-${lab-name}/.tls/ca/ca.pem 'https://admin:NokiaSrl1!@clab-${lab-name}-srl1/jsonrpc' -d '{"jsonrpc":"2.0","id":0,"method":"get","params":{"commands":[{"path":"/system/information/version","datastore":"state"}]}}'
Log ${output}
Should Be Equal As Integers ${rc} 0
Should Not Contain ${output} error

Verify TLS works with JSON-RPC, certificate check and IP address as SAN
${rc} ${output} = Run And Return Rc And Output
... curl --cacert ./clab-${lab-name}/.tls/ca/ca.pem 'https://admin:[email protected]/jsonrpc' -d '{"jsonrpc":"2.0","id":0,"method":"get","params":{"commands":[{"path":"/system/information/version","datastore":"state"}]}}'
... curl --cacert ${CURDIR}/clab-${lab-name}/.tls/ca/ca.pem 'https://admin:[email protected]/jsonrpc' -d '{"jsonrpc":"2.0","id":0,"method":"get","params":{"commands":[{"path":"/system/information/version","datastore":"state"}]}}'
Log ${output}
Should Be Equal As Integers ${rc} 0
Should Not Contain ${output} error
Expand Down
6 changes: 3 additions & 3 deletions tests/03-basic-ceos/01-two-ceos.robot
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ Get nodes mgmt IPs
Should Be Equal As Strings ${inspected-n2-mgmt-ip} ${n2-mgmt-ip}

Ensure n1 mgmt IPv4 is in the config file
${f} = OperatingSystem.Get File ${EXECDIR}/clab-${lab-name}/${node1-name}/flash/startup-config
${f} = OperatingSystem.Get File ${CURDIR}/clab-${lab-name}/${node1-name}/flash/startup-config
Log ${f}
Log ${n1-mgmt-ip}
Should Contain ${f} ${n1-mgmt-ip}

Ensure n2 mgmt IPv4 is in the config file
${f} = OperatingSystem.Get File ${EXECDIR}/clab-${lab-name}/${node2-name}/flash/startup-config
${f} = OperatingSystem.Get File ${CURDIR}/clab-${lab-name}/${node2-name}/flash/startup-config
Log ${f}
Should Contain ${f} ${n2-mgmt-ip}

Ensure IPv6 default route is in the config file
${f} = OperatingSystem.Get File ${EXECDIR}/clab-${lab-name}/${node1-name}/flash/startup-config
${f} = OperatingSystem.Get File ${CURDIR}/clab-${lab-name}/${node1-name}/flash/startup-config
Log ${f}
Should Contain ${f} ipv6 route

Expand Down
7 changes: 2 additions & 5 deletions types/topo_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,10 @@ func (t *TopoPaths) SetLabDir(p string) (err error) {
func (t *TopoPaths) SetLabDirByPrefix(topologyName string) (err error) {
t.topoName = topologyName
// if "CLAB_LABDIR_BASE" Env Var is set, use that dir as a base
// for the labDir, otherwise use PWD.
// for the labDir, otherwise use dir where topology clab file is.
baseDir := os.Getenv("CLAB_LABDIR_BASE")
if baseDir == "" {
baseDir, err = os.Getwd()
if err != nil {
return err
}
baseDir = t.TopologyFileDir()
}
// construct the path
t.labDir = path.Join(baseDir, labDirPrefix+topologyName)
Expand Down
Loading