diff options
| -rw-r--r-- | data/templates/container/registries.conf.j2 | 6 | ||||
| -rw-r--r-- | interface-definitions/container.xml.in | 9 | ||||
| -rw-r--r-- | interface-definitions/include/generic-password.xml.i | 15 | ||||
| -rw-r--r-- | interface-definitions/include/generic-username.xml.i | 15 | ||||
| -rw-r--r-- | interface-definitions/include/interface/authentication.xml.i | 28 | ||||
| -rwxr-xr-x | src/conf_mode/container.py | 37 | 
6 files changed, 79 insertions, 31 deletions
diff --git a/data/templates/container/registries.conf.j2 b/data/templates/container/registries.conf.j2 index 2e86466a1..eb7ff8775 100644 --- a/data/templates/container/registries.conf.j2 +++ b/data/templates/container/registries.conf.j2 @@ -23,5 +23,9 @@  # unqualified-search-registries = ["example.com"]  {% if registry is vyos_defined %} -unqualified-search-registries = {{ registry }} +{%     set registry_list = [] %} +{%     for r, r_options in registry.items() if r_options.disable is not vyos_defined %} +{%         set _ = registry_list.append(r) %} +{%     endfor %} +unqualified-search-registries = {{ registry_list }}  {% endif %} diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index a5940ae17..6947ed500 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -368,13 +368,16 @@            </leafNode>          </children>        </tagNode> -      <leafNode name="registry"> +      <tagNode name="registry">          <properties>            <help>Registry Name</help> -          <multi/>          </properties>          <defaultValue>docker.io quay.io</defaultValue> -      </leafNode> +        <children> +          #include <include/interface/authentication.xml.i> +          #include <include/generic-disable-node.xml.i> +        </children> +      </tagNode>      </children>    </node>  </interfaceDefinition> diff --git a/interface-definitions/include/generic-password.xml.i b/interface-definitions/include/generic-password.xml.i new file mode 100644 index 000000000..76d5f12d8 --- /dev/null +++ b/interface-definitions/include/generic-password.xml.i @@ -0,0 +1,15 @@ +<!-- include start from generic-password.xml.i --> +<leafNode name="password"> +  <properties> +    <help>Password used for authentication</help> +    <valueHelp> +      <format>txt</format> +      <description>Password</description> +    </valueHelp> +    <constraint> +      <regex>[[:ascii:]]{1,128}</regex> +    </constraint> +    <constraintErrorMessage>Password is limited to ASCII characters only, with a total length of 128</constraintErrorMessage> +  </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/generic-username.xml.i b/interface-definitions/include/generic-username.xml.i new file mode 100644 index 000000000..678f30ddf --- /dev/null +++ b/interface-definitions/include/generic-username.xml.i @@ -0,0 +1,15 @@ +<!-- include start from generic-username.xml.i --> +<leafNode name="username"> +  <properties> +    <help>Username used for authentication</help> +    <valueHelp> +      <format>txt</format> +      <description>Username</description> +    </valueHelp> +    <constraint> +      <regex>[[:ascii:]]{1,128}</regex> +    </constraint> +    <constraintErrorMessage>Username is limited to ASCII characters only, with a total length of 128</constraintErrorMessage> +  </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/interface/authentication.xml.i b/interface-definitions/include/interface/authentication.xml.i index ac06faef5..0bd792209 100644 --- a/interface-definitions/include/interface/authentication.xml.i +++ b/interface-definitions/include/interface/authentication.xml.i @@ -4,32 +4,8 @@      <help>Authentication settings</help>    </properties>    <children> -    <leafNode name="username"> -      <properties> -        <help>Username used for authentication</help> -        <valueHelp> -          <format>txt</format> -          <description>Username</description> -        </valueHelp> -        <constraint> -          <regex>[[:ascii:]]{1,128}</regex> -        </constraint> -        <constraintErrorMessage>Username is limited to ASCII characters only, with a total length of 128</constraintErrorMessage> -      </properties> -    </leafNode> -    <leafNode name="password"> -      <properties> -        <help>Password used for authentication</help> -        <valueHelp> -          <format>txt</format> -          <description>Password</description> -        </valueHelp> -        <constraint> -          <regex>[[:ascii:]]{1,128}</regex> -        </constraint> -        <constraintErrorMessage>Password is limited to ASCII characters only, with a total length of 128</constraintErrorMessage> -      </properties> -    </leafNode> +    #include <include/generic-username.xml.i> +    #include <include/generic-password.xml.i>    </children>  </node>  <!-- include end --> diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 10e9e9213..68070ea5b 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -18,7 +18,6 @@ import os  from ipaddress import ip_address  from ipaddress import ip_network -from time import sleep  from json import dumps as json_write  from vyos.base import Warning @@ -28,6 +27,7 @@ from vyos.configdict import node_changed  from vyos.util import call  from vyos.util import cmd  from vyos.util import run +from vyos.util import rc_cmd  from vyos.util import write_file  from vyos.template import inc_ip  from vyos.template import is_ipv4 @@ -68,6 +68,9 @@ def get_config(config=None):      # container base default values can not be merged here - remove and add them later      if 'name' in default_values:          del default_values['name'] +    # registry will be handled below +    if 'registry' in default_values: +        del default_values['registry']      container = dict_merge(default_values, container)      # Merge per-container default values @@ -95,6 +98,15 @@ def get_config(config=None):                      container['name'][name]['volume'][volume] = dict_merge(                          default_values_volume, container['name'][name]['volume'][volume]) +    # registry is a tagNode with default values - merge the list from +    # default_values['registry'] into the tagNode variables +    if 'registry' not in container: +        container.update({'registry' : {}}) +        default_values = defaults(base) +        for registry in default_values['registry'].split(): +            tmp = {registry : {}} +            container['registry'] = dict_merge(tmp, container['registry']) +      # Delete container network, delete containers      tmp = node_changed(conf, base + ['network'])      if tmp: container.update({'network_remove' : tmp}) @@ -226,6 +238,11 @@ def verify(container):                  if 'network' in container_config and network in container_config['network']:                      raise ConfigError(f'Can not remove network "{network}", used by container "{container}"!') +    if 'registry' in container and 'authentication' in container['registry']: +        for registry, registry_config in container['registry']['authentication'].items(): +            if not {'username', 'password'} <= set(registry_config): +                raise ConfigError('If registry username or or password is defined, so must be the other!') +      return None  def generate_run_arguments(name, container_config): @@ -355,6 +372,24 @@ def generate(container):              write_file(f'/etc/cni/net.d/{network}.conflist', json_write(tmp, indent=2)) +    if 'registry' in container: +        cmd = f'podman logout --all' +        rc, out = rc_cmd(cmd) +        if rc != 0: +            raise ConfigError(out) + +        for registry, registry_config in container['registry'].items(): +            if 'disable' in registry_config: +                continue +            if 'authentication' in registry_config: +                if {'username', 'password'} <= set(registry_config['authentication']): +                    username = registry_config['authentication']['username'] +                    password = registry_config['authentication']['password'] +                    cmd = f'podman login --username {username} --password {password} {registry}' +                    rc, out = rc_cmd(cmd) +                    if rc != 0: +                        raise ConfigError(out) +      render(config_containers_registry, 'container/registries.conf.j2', container)      render(config_containers_storage, 'container/storage.conf.j2', container)  | 
