Commit edc72dbf authored by David Danier's avatar David Danier 🚀
Browse files

Modified implementation to be more generic

parent 7e6d3d62
Loading
Loading
Loading
Loading
+48 −34
Original line number Original line Diff line number Diff line
@@ -4,7 +4,7 @@ import pwd
import warnings
import warnings


from ..exceptions import B5ExecutionError
from ..exceptions import B5ExecutionError
from . import BaseModule
from . import BaseModule, CONFIG_PREFIX_RE




class DockerModule(BaseModule):
class DockerModule(BaseModule):
@@ -24,7 +24,7 @@ class DockerModule(BaseModule):
        'docker_machine': None,
        'docker_machine': None,
        'commands': {},
        'commands': {},
        'sync': {},
        'sync': {},
        'ensure_exists': {},
        'setup': {},
    }
    }


    def prepare_config(self):
    def prepare_config(self):
@@ -46,8 +46,12 @@ class DockerModule(BaseModule):
            raise B5ExecutionError('docker commands has to be a dictionary')
            raise B5ExecutionError('docker commands has to be a dictionary')
        if not isinstance(self.config['sync'], dict):
        if not isinstance(self.config['sync'], dict):
            raise B5ExecutionError('docker sync has to be a dictionary')
            raise B5ExecutionError('docker sync has to be a dictionary')
        if not isinstance(self.config['ensure_exists'], dict):
        if not isinstance(self.config['setup'], dict):
            raise B5ExecutionError('ensure_exists has to be a dictionary')
            raise B5ExecutionError('setup has to be a dictionary')
        else:
            if 'networks' in self.config['setup']:
                if not isinstance(self.config['setup']['networks'], list):
                    raise B5ExecutionError('setup.networks has to be a last')


        ##### CONFIGURATION MANAGEMENT #####
        ##### CONFIGURATION MANAGEMENT #####


@@ -143,11 +147,13 @@ class DockerModule(BaseModule):
        )))
        )))


        script.append(self._script_function_source('run', '''
        script.append(self._script_function_source('run', '''
            {name}:setup
            (
            (
                {docker_env}
                {docker_env}
                "$@"
                "$@"
            )
            )
        '''.format(
        '''.format(
            name=self.name,
            docker_env=self.get_script_env(),
            docker_env=self.get_script_env(),
            base_path=shlex.quote(self.config['base_path']),
            base_path=shlex.quote(self.config['base_path']),
        )))
        )))
@@ -166,7 +172,6 @@ class DockerModule(BaseModule):
        script.append(self._script_function_source('docker-compose', '''
        script.append(self._script_function_source('docker-compose', '''
            (
            (
                cd {base_path} && \\
                cd {base_path} && \\
                if (declare -f -F {name}:create_external_networks > /dev/null); then {name}:create_external_networks; fi && \\
                {name}:run {docker_compose_bin} {docker_compose_configs} "$@"
                {name}:run {docker_compose_bin} {docker_compose_configs} "$@"
            )
            )
        '''.format(
        '''.format(
@@ -461,42 +466,51 @@ class DockerModule(BaseModule):
                    else shlex.quote(command_options.get('bin')),
                    else shlex.quote(command_options.get('bin')),
            )))
            )))


        for ensure_exists, ensure_exists_options in self.config['ensure_exists'].items():
        if self.config['setup']:
            if ensure_exists == "external_networks":
            # Setup networks
                network_script = ""
            if 'networks' in self.config['setup'] and self.config['setup']['networks']:
                if not isinstance(ensure_exists_options, list):
                # Create a function for each network
                    raise B5ExecutionError('ensure_exists options have to be a list')
                for setup_network_name in self.config['setup']['networks']:
                for network in ensure_exists_options:
                    script.append(self._script_function_source('setup:network:{network}'.format(network=setup_network_name), '''
                    network_script = network_script + """
                        {name}:docker network inspect {network} &>/dev/null || (
                        {name}:run {docker_bin} network inspect {network} &>/dev/null || (
                            {name}:docker network create {network} && echo \"Created network {network}.\"
                            {name}:run {docker_bin} network create {network} && echo \"Created external network {network}.\"
                        );
                        );
                    """.format(
                    '''.format(
                            name=self.name,
                            name=self.name,
                       docker_bin=shlex.quote(self.config['docker_bin']),
                            network=shlex.quote(setup_network_name),
                       network=network
                        )))
                   )
                # Create general network setup function

                script.append(self._script_function_source('setup:network', '''
                if network_script == "":
                    {setup_all_networks}
                    # no networks to create => dummy function
                    script.append(self._script_function_source('create_external_networks', '''
                            (
                                cd {base_path}
                            )
                '''.format(
                '''.format(
                            base_path=shlex.quote(self.config['base_path']),
                    setup_all_networks='\n                    '.join([
                        'setup:network:{network}'.format(network=setup_network_name)
                        for setup_network_name
                        in self.config['setup']['networks']
                    ])
                )))
                )))
                else:
            # Create general setup function
                    # append script to add external networks
            setup_ran_var_name = '_{prefix}_SETUP_RAN'.format(
                    script.append(self._script_function_source('create_external_networks', '''
                prefix=CONFIG_PREFIX_RE.sub('_', self.name.upper())
                            (
                                cd {base_path} && \\
                                {network_script}
            )
            )
            script.append('{setup_ran_var}=0'.format(setup_ran_var=setup_ran_var_name))
            script.append(self._script_function_source('setup', '''
                if [ "${setup_ran_var}" -eq 1 ]
                then
                    return 0
                fi
                {setup_networks}
                {setup_ran_var}=1
            '''.format(
            '''.format(
                            base_path=shlex.quote(self.config['base_path']),
                setup_networks='{name}:setup:network'.format(name=self.name) if
                            network_script=network_script
                    'networks' in self.config['setup'] and self.config['setup']['networks'] else '',
                setup_ran_var=setup_ran_var_name,
            )))
            )))
        else:
            # Create EMPTY general setup function, if no config exists
            script.append(self._script_function_source('setup', '''
                true
            '''))


        for sync, sync_options in self.config['sync'].items():
        for sync, sync_options in self.config['sync'].items():
            if not isinstance(sync_options, dict):
            if not isinstance(sync_options, dict):
+8 −7
Original line number Original line Diff line number Diff line
@@ -27,9 +27,10 @@ you probably want to put inside build/, too.
  `--pipe-in` to handle pipes (see `container_run`). You may use `-T` or `--disable-tty` to disable pseudo-tty
  `--pipe-in` to handle pipes (see `container_run`). You may use `-T` or `--disable-tty` to disable pseudo-tty
  allocation at all. All these parameters must be passed first, as other parameters will be passed to the executed
  allocation at all. All these parameters must be passed first, as other parameters will be passed to the executed
  command inside docker.
  command inside docker.
* **ensure_exists**: This currently only supports one subkey 'external_networks' which can be a list of
* **setup**: Allows you to tell b5 to setup some docker specific things before running docker itself. This currently
  external_networks to create (if they do not yet exist) before running docker-compose. There is (currently) no logic
  only supports one subkey 'networks' which can be a list of networks to create (if they do not yet exist).
  implemented to clean up these external networks after they have been created by b5.  
  There is (currently) no logic implemented to clean up these networks after they have been created by b5.
  Can be used to make sure networks marked as external exist before running docker.  
* **sync**: List of paths to sync to docker volumes. See example below. Syncing some paths into volumes may
* **sync**: List of paths to sync to docker volumes. See example below. Syncing some paths into volumes may
  increase the performance significantly. Note that these paths will only be updated when calling `docker:update`
  increase the performance significantly. Note that these paths will only be updated when calling `docker:update`
  or `docker:sync`. Internally
  or `docker:sync`. Internally
@@ -237,13 +238,13 @@ task:sync:phpvendor() {
```
```




### Example 4 - auto-create external networks
### Example 4 - auto-create networks


If external networks are defined in docker-compose.yml they are by default not auto-created by docker-compose and
If external networks are defined in docker-compose.yml they are by default not auto-created by docker-compose and
using docker-compose will fail with an error message about missing these networks.
using docker-compose will fail with an error message about missing these networks.


To auto-create these external networks when using docker-compose commands use the option
To auto-create these external networks when using docker-compose commands use the option
ensure_exists['external_networks'] and provide a list of external networks to auto-create:
setup.networks and provide a list of networks to auto-create:


docker-compose.yml:
docker-compose.yml:
```yaml
```yaml
@@ -267,9 +268,9 @@ config.yml:
```yaml
```yaml
modules:
modules:
  docker:
  docker:
    ensure_exists:
    setup:
      # networks to auto-create
      # networks to auto-create
      external_networks:
      networks:
        - test_external_net
        - test_external_net
```
```