Skip to content

Commit

Permalink
added stdin support for topos (#1621)
Browse files Browse the repository at this point in the history
* added stdin support for topos

* lazy to use act, testing in gh actions

* create clab temp dir before reading from stdin
  • Loading branch information
hellt committed Oct 7, 2023
1 parent 0cb7612 commit c8d72d5
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 7 deletions.
40 changes: 35 additions & 5 deletions clab/clab.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,24 @@ func WithKeepMgmtNet() ClabOption {

func WithTopoPath(path, varsFile string) ClabOption {
return func(c *CLab) error {
if path == "" {
var file string
var err error

switch path {
case "-", "stdin":
file, err = c.readFromStdin()
if err != nil {
return err
}

case "":
return fmt.Errorf("provide a path to the clab topology file")
}

file, err := findTopoFileByPath(path)
if err != nil {
return err
default:
file, err = findTopoFileByPath(path)
if err != nil {
return err
}
}

if err := c.GetTopology(file, varsFile); err != nil {
Expand Down Expand Up @@ -184,6 +195,25 @@ func findTopoFileByPath(path string) (string, error) {
return file, nil
}

// readFromStdin reads the topology file from stdin
// creates a temp file with topology contents
// and returns a path to the temp file.
func (c *CLab) readFromStdin() (string, error) {
c.TopoPaths.CreateTmpDir()

tmpFile, err := os.CreateTemp(c.TopoPaths.ClabTmpDir(), "topo-*.clab.yml")
if err != nil {
return "", err
}

_, err = tmpFile.ReadFrom(os.Stdin)
if err != nil {
return "", err
}

return tmpFile.Name(), nil
}

// WithNodeFilter option sets a filter for nodes to be deployed.
// A filter is a list of node names to be deployed,
// names are provided exactly as they are listed in the topology file.
Expand Down
3 changes: 1 addition & 2 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ func (c *CLab) processStartupConfig(nodeCfg *types.NodeConfig) error {

if isEmbeddedConfig || isDownloadableConfig {
// both embedded and downloadable configs are require clab tmp dir to be created
tmpLoc := c.TopoPaths.ClabTmpDir()
utils.CreateDirectory(tmpLoc, 0755)
c.TopoPaths.CreateTmpDir()

switch {
case isEmbeddedConfig:
Expand Down
9 changes: 9 additions & 0 deletions docs/cmd/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ When the topology file flag is omitted, containerlab will try to find the matchi

If more than one file is found for directory-based path or when the flag is omitted entirely, containerlab will fail with an error.

It is possible to read the topology file from stdin by passing `-` as a value to the `--topo` flag. See [examples](#deploy-a-lab-from-a-remote-url-with-curl) for more details.

#### name

With the global `--name | -n` flag a user sets a lab name. This value will override the lab name value passed in the topology definition file.
Expand Down Expand Up @@ -140,3 +142,10 @@ containerlab deploy
```bash
clab dep -t mylab.clab.yml
```

#### Deploy a lab from a remote URL with curl

```bash
curl -s https://gist.githubusercontent.com/hellt/9baa28d7e3cb8290ade1e1be38a8d12b/raw/03067e242d44c9bbe38afa81131e46bab1fa0c42/test.clab.yml | \
sudo containerlab deploy -t -
```
31 changes: 31 additions & 0 deletions tests/01-smoke/13-stdin-lab.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
*** Settings ***
Library OperatingSystem
Library String
Library Process
Resource ../common.robot

Suite Teardown Run Keyword Teardown


*** Variables ***
${lab-url} https://gist.githubusercontent.com/hellt/9baa28d7e3cb8290ade1e1be38a8d12b/raw/03067e242d44c9bbe38afa81131e46bab1fa0c42/test.clab.yml


*** Test Cases ***
Deploy remote lab
${rc} ${output} = Run And Return Rc And Output
... sudo curl -s ${lab-url} | sudo ${CLAB_BIN} --runtime ${runtime} deploy -c -t -
Log ${output}
Should Be Equal As Integers ${rc} 0

Ensure inspect works
${rc} ${output} = Run And Return Rc And Output
... sudo ${CLAB_BIN} --runtime ${runtime} inspect --all
Log ${output}
Should Be Equal As Integers ${rc} 0


*** Keywords ***
Teardown
# destroy all labs
Run sudo ${CLAB_BIN} --runtime ${runtime} destroy -c -a
5 changes: 5 additions & 0 deletions types/topo_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ func (*TopoPaths) ClabTmpDir() string {
return clabTmpDir
}

// CreateTmpDir creates a clab temp directory.
func (t *TopoPaths) CreateTmpDir() {
utils.CreateDirectory(t.ClabTmpDir(), 0755)
}

// StartupConfigDownloadFileAbsPath returns the absolute path to the startup-config file
// when it is downloaded from a remote location to the clab temp directory.
func (t *TopoPaths) StartupConfigDownloadFileAbsPath(node, postfix string) string {
Expand Down

0 comments on commit c8d72d5

Please sign in to comment.