Skip to content

Configure containers using 'clab.startup-config' parameter#3084

Open
ipspace wants to merge 1 commit intodevfrom
startup-cfg
Open

Configure containers using 'clab.startup-config' parameter#3084
ipspace wants to merge 1 commit intodevfrom
startup-cfg

Conversation

@ipspace
Copy link
Owner

@ipspace ipspace commented Feb 4, 2026

This commit implements 'startup' netlab_config_mode:

  • The node_files/x/startup.partial.config file is generated from the configuration files created by the 'config' output module
  • The clab.startup-config attribute is set to the name of the startup config file

This configuration mode is an experimental feature and might not work on all devices. It's enabled by setting device clab.group_vars or node 'netlab_config_mode' parameter to 'startup'

Other changes:

  • The number of modules deployed using startup config is collected in node._deploy.startup list
  • The two node._deploy lists (success and startup) are used to generate the internal deployment statistics.

This commit implements 'startup' netlab_config_mode:

* The node_files/x/startup.partial.config file is generated from the
  configuration files created by the 'config' output module
* The clab.startup-config attribute is set to the name of the startup
  config file

This configuration mode is an experimental feature and might not work
on all devices. It's enabled by setting device clab.group_vars or node
'netlab_config_mode' parameter to 'startup'

Other changes:

* The number of modules deployed using startup config is collected in
  node._deploy.startup list
* The two node._deploy lists (success and startup) are used to generate
  the internal deployment statistics.
@ipspace
Copy link
Owner Author

ipspace commented Feb 4, 2026

@DanPartelly -- You asked for it ;)

@ipspace
Copy link
Owner Author

ipspace commented Feb 4, 2026

This PR has been tested with IOL and works like a charm. I have no idea how well it would work with other devices; that would have to be thoroughly tested.

In any case, this mode is a bit dangerous as I don't know how (and if) we'd get the config error messages, so it will never be enabled by default.

Documentation coming once @DanPartelly likes the feature ;))

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements experimental 'startup' netlab_config_mode support for containerlab, allowing configuration to be loaded directly at container startup rather than through deployment scripts.

Changes:

  • Adds functions to generate and configure startup configuration files from 'startup' mode config templates
  • Tracks deployment statistics separately for startup-configured and script-deployed modules
  • Updates reporting to display both startup and script deployment results

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
netsim/providers/clab.py Implements startup config generation: filtering templates by mode, setting startup-config path, generating consolidated config file, and tracking startup deployments
netsim/cli/initial/deploy.py Updates deployment statistics reporting to show both script-deployed and startup-configured modules separately

Comment on lines +321 to +322
try:
with pathlib.Path(startup_path).open("w") as startup_cfg:
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory containing the startup config file may not exist when opening the file for writing. Consider using pathlib.Path(startup_path).parent.mkdir(parents=True, exist_ok=True) before opening the file, or handle FileNotFoundError specifically in the exception handler.

Suggested change
try:
with pathlib.Path(startup_path).open("w") as startup_cfg:
startup_file = pathlib.Path(startup_path)
startup_file.parent.mkdir(parents=True, exist_ok=True)
try:
with startup_file.open("w") as startup_cfg:

Copilot uses AI. Check for mistakes.

'''
Generate node startup configuration from configuration snippets with 'startup' mode
in node_files/node/startup-config
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the file is "startup-config" but the actual filename is "startup.partial.config" as set in line 293.

Suggested change
in node_files/node/startup-config
in node_files/node/startup.partial.config

Copilot uses AI. Check for mistakes.
if not log.QUIET:
log.status_created()
print(f"startup configuration for {n.name}",flush=True)
n.clab['startup-config'] = startup_path
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is redundant. The value of startup_path comes from n.clab['startup-config'] at line 320, so reassigning it back to the same location has no effect.

Suggested change
n.clab['startup-config'] = startup_path

Copilot uses AI. Check for mistakes.
startup_cfg.write("\n")
except Exception as ex:
log.error(
'Cannot open/write startup configuration file {startup_path}',
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is missing an f-string prefix. The variable startup_path will not be interpolated into the string and will appear literally as {startup_path} in the error message.

Suggested change
'Cannot open/write startup configuration file {startup_path}',
f'Cannot open/write startup configuration file {startup_path}',

Copilot uses AI. Check for mistakes.
def get_templates_with_mode(n: Box, mode: typing.Optional[str]) -> list:
return [ item for item in n.get('clab.config_templates',[]) # Collect config template items
if 'mode' in item and # ... that have mode set
item.mode == mode or mode is None] # ... and match the requested mode (None == all modes)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operator precedence issue in the conditional expression. The current expression evaluates as ('mode' in item and item.mode == mode) or mode is None, which means items without a mode will be included when mode is None. This should use parentheses to express the intended logic: 'mode' in item and (item.mode == mode or mode is None).

Suggested change
item.mode == mode or mode is None] # ... and match the requested mode (None == all modes)
(item.mode == mode or mode is None)] # ... and match the requested mode (None == all modes)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use clab "startup_config" parameter to configure lab devices

1 participant