Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/srl-wim/container-lab int…
Browse files Browse the repository at this point in the history
…o subshelling
  • Loading branch information
steiler committed Dec 17, 2020
2 parents 125b5c5 + b3bfcf2 commit e4beadc
Show file tree
Hide file tree
Showing 62 changed files with 6,853 additions and 570 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/docs-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Test
on:
push:
branches:
- "*"
- "!releases/**"
paths:
- "docs/**"

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker run -v $(pwd):/docs --entrypoint mkdocs squidfunk/mkdocs-material:6.1.5 build --clean --strict --site-dir /tmp/mkdocs-test
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: docs
on:
push:
branches:
- "docs-*"
- "docs-publish"
tags:
- "v*"

Expand All @@ -11,4 +11,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker run -v $(pwd):/docs --entrypoint mkdocs squidfunk/mkdocs-material:6.1.0 gh-deploy --force --strict
- run: docker run -v $(pwd):/docs --entrypoint mkdocs squidfunk/mkdocs-material:6.1.5 gh-deploy --force --strict
18 changes: 18 additions & 0 deletions .github/workflows/manual-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: manual code checks
on:
workflow_dispatch:

jobs:
run-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: 1.14
- name: Staticcheck
run: |
go get -u honnef.co/go/tools/cmd/staticcheck
staticcheck ./...
env:
CGO_ENABLED: 0
10 changes: 10 additions & 0 deletions .github/workflows/manual-pubdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: manual docs publish
on:
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker run -v $(pwd):/docs --entrypoint mkdocs squidfunk/mkdocs-material:6.1.5 gh-deploy --force --strict
11 changes: 5 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ on:
branches:
- "*"
- "!releases/**"
paths-ignore:
- "docs/**"
- "lab-examples/**"
- "mkdocs.yml"
- "README.md"

jobs:
test:
Expand All @@ -17,9 +22,3 @@ jobs:
- run: go test -cover ./...
env:
CGO_ENABLED: 0

# enable staticcheck when we reach maturity
# - name: Staticcheck
# run: |
# go get -u honnef.co/go/tools/cmd/staticcheck
# staticcheck ./...
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ dist

# ignore the following files
PRIVATE.md
graph
graph/*
containerlab*
containerlab*/
Expand Down
5 changes: 4 additions & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ nfpms:
file_name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
package_name: containerlab
maintainer: Wim Henderickx <[email protected]>, Karim Radhouani <[email protected]>, Roman Dodin <[email protected]>
homepage: https://containerlab.srlinux.dev
description: |
containerlab written in go
vendor: Nokia
license: GNU GPLv3
formats:
- rpm
- deb
bindir: /usr/local/bin
bindir: /usr/bin
files:
./lab-examples/**/*: /etc/containerlab/lab-examples
./templates/**/*: /etc/containerlab/templates
symlinks:
/usr/bin/clab: /usr/bin/containerlab
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,37 @@

## Description

Containerlab provides a framework for setting up and destroying labs for networking containers. It builds a virtual wiring using veth pairs between the containers to provide virtual topologies.
Containerlab provides a framework for setting up networking labs with containers. It starts the containers and builds a virtual wiring between them to create lab topologies of users choice.

![pic](https://gitlab.com/rdodin/pics/-/wikis/uploads/8244ceb188abd3831e3715c42d4fa38f/image.png)
Containerlab focuses on containerized Network Operating Systems which are typically used to test network features and designs, such as:

* [Nokia SR-Linux](https://www.nokia.com/networks/products/service-router-linux-NOS/)
* [Arista cEOS](https://www.arista.com/en/products/software-controlled-container-networking)
* [SONiC](https://azure.github.io/SONiC/)
* [Juniper cRPD](https://www.juniper.net/documentation/en_US/crpd/topics/concept/understanding-crpd.html)

But, of course, containerlab is perfectly capable of wiring up arbitrary containers which can host your network applications, virtual router or simply be a test client.

<p align="center">
<img src="https://gitlab.com/rdodin/pics/-/wikis/uploads/e9222468fe580bc57a9ff2da03cca1cb/image.png" width="40%">
</p>

## Features
* **IaaC approach**
Declarative way of defining the labs by means of the [topology definition files](https://containerlab.srlinux.dev/manual/topo-def-file/).
* **Network Operating Systems centric**
Focus on containerized Network Operating Systems. The sophisticated startup requirements of various NOS containers are abstracted with [kinds](https://containerlab.srlinux.dev/manual/kinds/) which allows the user to focus on the use cases, rather than infrastructure.
* **Simplicity and convenience are keys**
One-click [installation](https://containerlab.srlinux.dev/install/) and upgrade capabilities.
* **Fast**
Blazing fast way to create container based labs on any Debian or RHEL system.
* **Automated TLS certificates provisioning**
The nodes which require TLS certs will get them automatically on start.
* **Documentation is a first-class citizen**
We do not let our users guess by making a complete, concise and clean [documentation](https://containerlab.srlinux.dev).
* **Lab catalog**
The "most-wanted" lab topologies are [documented and included](https://containerlab.srlinux.dev/lab-examples/lab-examples/) with containerlab installation. Based on this cherry-picked selection you can start crafting the labs answering your needs.

The labs could also be wired to an external bridge to connect to external environment or to build hierarchical labs.

A CA can be provided per lab and when enabled, containerlab generates certificates per device that can be used for various use cases, like GNMI, JSON RPC, etc.

Lastly, containerlab also allows for a graphical output to validate the lab in a visual format using [graphviz](https://graphviz.org)

Containerlab supports the following containers:

* standard linux/alpine containers, typically used as test clients
* networking containers:
* Nokia SR-Linux
* Arista cEOS.

Containerlab documentation is provided at https://containerlab.srlinux.dev.
89 changes: 77 additions & 12 deletions clab/clab.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"sync"
"time"

"github.com/docker/docker/api/types"
docker "github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
)

// var debug bool
Expand All @@ -19,8 +21,9 @@ type cLab struct {
DockerClient *docker.Client
Dir *cLabDirectory

debug bool
timeout time.Duration
debug bool
timeout time.Duration
gracefulShutdown bool
}

type cLabDirectory struct {
Expand All @@ -30,23 +33,60 @@ type cLabDirectory struct {
LabGraph string
}

type ClabOption func(c *cLab)

func WithDebug(d bool) ClabOption {
return func(c *cLab) {
c.debug = d
}
}

func WithTimeout(dur time.Duration) ClabOption {
return func(c *cLab) {
c.timeout = dur
}
}

func WithEnvDockerClient() ClabOption {
return func(c *cLab) {
var err error
c.DockerClient, err = docker.NewEnvClient()
if err != nil {
log.Fatalf("failed to create docker client: %v", err)
}
}
}

func WithTopoFile(file string) ClabOption {
return func(c *cLab) {
if file == "" {
return
}
if err := c.GetTopology(file); err != nil {
log.Fatalf("failed to read topology file: %v", err)
}
}
}

func WithGracefulShutdown(gracefulShutdown bool) ClabOption {
return func(c *cLab) {
c.gracefulShutdown = gracefulShutdown
}
}

// NewContainerLab function defines a new container lab
func NewContainerLab(d bool) *cLab {
return &cLab{
func NewContainerLab(opts ...ClabOption) *cLab {
c := &cLab{
Config: new(Config),
TopoFile: new(TopoFile),
m: new(sync.RWMutex),
Nodes: make(map[string]*Node),
Links: make(map[int]*Link),
debug: d,
}
}

// Init creates a docker client and adds it to containerlab structure
func (c *cLab) Init(timeout time.Duration) (err error) {
c.DockerClient, err = docker.NewEnvClient()
c.timeout = timeout
return
for _, o := range opts {
o(c)
}
return c
}

func (c *cLab) CreateNode(ctx context.Context, node *Node, certs *certificates) error {
Expand All @@ -60,3 +100,28 @@ func (c *cLab) CreateNode(ctx context.Context, node *Node, certs *certificates)
}
return c.CreateContainer(ctx, node)
}

// ExecPostDeployTasks executes tasks that some nodes might require to boot properly after start
func (c *cLab) ExecPostDeployTasks(ctx context.Context, node *Node) error {
switch node.Kind {
case "ceos":
log.Infof("Running postdeploy actions for '%s' node", node.ShortName)
// regenerate ceos config since it is now known which IP address docker assigned to this container
err := node.generateConfig(node.ResConfig)
if err != nil {
return err
}
log.Infof("Restarting '%s' node", node.ShortName)
// force stopping and start is faster than ContainerRestart
var timeout time.Duration = 1
err = c.DockerClient.ContainerStop(ctx, node.ContainerID, &timeout)
if err != nil {
return err
}
err = c.DockerClient.ContainerStart(ctx, node.ContainerID, types.ContainerStartOptions{})
if err != nil {
return err
}
}
return nil
}
Loading

0 comments on commit e4beadc

Please sign in to comment.