Skip to content

Commit e320961

Browse files
committed
Merge branch 'improvements' into 'master'
Features: global-restart and customizable tmpfs with systemd See merge request evernym/utilities/devlab!14
2 parents d84f615 + 8639137 commit e320961

10 files changed

Lines changed: 104 additions & 20 deletions

File tree

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ If you would like contribute to this project, please do the following:
4040
1. **Wizard**: A script that is run before the `up` action. After the wizard has been executed a proper [DevlabConfig.json or DevlabConfig.yaml](#devlab-configuration) should exist. It is normal for the wizard to result in more files than just a `DevlabConfig.json` or `DevlabConfig.yaml`, and those files can be added to the config so that devlab can reset the wizard (forcing it to run again) if so desired.
4141

4242
# Usage
43-
All actions have a `--help` which should display relevent help. The following options below are "global" options and *should* preceed any action:
43+
All actions have a `--help` which should display relevent help. The following options below are "common" options and *should* preceed any action:
4444

4545
```
4646
-h, --help show this help message and exit
@@ -49,7 +49,7 @@ All actions have a `--help` which should display relevent help. The following op
4949
```
5050

5151
The format of the command should be:
52-
`devlab <global options> <action> <action options>`
52+
`devlab <common options> <action> <action options>`
5353

5454
The "wizard" logic will be invoked the first time you run a `devlab up` command. This can be invoked separately with `wizard` if you so desire.
5555

@@ -128,6 +128,7 @@ The structure looks like this:
128128
{
129129
"image": "",
130130
"systemd_support": false,
131+
"systemd_tmpfs_args": "",
131132
"enabled": false,
132133
"cmd": "",
133134
"ports": [],
@@ -153,6 +154,7 @@ All Keys that are in **bold** are required
153154
| --- | --- | --- |
154155
| **image** | String | A docker notation of docker image to use for the component. This can also reference a devlab base image, as well as a project's [runtime image](#runtime-image-structure) |
155156
| systemd_support | Boolean | If set to `true` then this will start the component with proper `/run`, `/run/lock`, `/tmp`, and `/sys/fs/cgroup` mounts so systemd can run |
157+
| systemd_tmpfs_args | String | If `systemd_support` is set to `true`, and this argument is set, then the value is appended to the tmpfs mounts as arguments for systemd support. This way you can specify things like: `rw`, `exec`, etc... |
156158
| **enabled** | Boolean | Whether or not the component should be brought [up](#up-action) and images [built](#build-action) |
157159
| **_name_** | String | This is only supported for `foreground_components` but required. It indicates the name of the component |
158160
| type | String | This only only supported for `foreground_components`, but can be either `host` or `container`. If set to host then `cmd` is executed on the local system instead of a container |
@@ -457,7 +459,7 @@ foreground_component:
457459
```
458460

459461
# Devlab Argument documentation
460-
All actions have a `--help` which should display relevent help. The following options below are "global" options and *should* preceed any action:
462+
All actions have a `--help` which should display relevent help. The following options below are "common" options and *should* preceed any action:
461463

462464
```
463465
-h, --help show this help message and exit
@@ -466,7 +468,7 @@ All actions have a `--help` which should display relevent help. The following op
466468
```
467469

468470
The format of the command should be:
469-
`devlab <global options> <action> <action options>`
471+
`devlab <common options> <action> <action options>`
470472

471473
For example. To bring the environment up with debug level messages:
472474
`devlab -l debug up`
@@ -481,6 +483,7 @@ For example. To bring the environment up with debug level messages:
481483
including persistent data. This is useful if you want
482484
to have a component start from scratch without re-
483485
running the wizard
486+
global-restart Restart components across all environments managed by devlab
484487
global-status Get a global status of all environments where devlab
485488
has created containers
486489
status Get a status of the environment

ci/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ else
3535
release_ver=$(echo "$legacy_last_release" | cut -d ' ' -f 3)
3636
fi
3737
fi
38-
echo "Getting changes comit changes between: ${beg_range}${last_change}"
38+
echo "Getting commit changes between: ${beg_range}${last_change}"
3939
changes_since_release=$(git log --pretty=format:'%s%n' ${beg_range}${last_change} | sed "/^Merge branch '.\+' into '.\+'/d ; /^Merge branch '.\+' of .\+/d; /^$/d")
4040

4141
if [ $(echo "$changes_since_release" | wc -l) -gt 0 ] ; then

devlab

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ if __name__ == '__main__':
9898
PARSER_RESET.add_argument('--full', '-f', action='store_true', help='Remove all component specific files, wizard files, as well as devlab files AND potentially files you\'re working on. BE CAREFUL IF YOU HAVE MANUAL CHANGES IN PATHS DEFINED IN YOUR \'paths.reset_full\'!!')
9999
PARSER_RESET.set_defaults(func=devlab_bench.actions.reset.action)
100100

101+
#Add Subparser for global_restart action
102+
PARSER_GLOBAL_RESTART = SUBPARSERS.add_parser('global-restart', help='Restart components across all environments managed by devlab')
103+
PARSER_GLOBAL_RESTART.add_argument('--update-images', '-u', action='store_true', help='Look for images that components are using, and try to either build new versions, or pull new ones')
104+
PARSER_GLOBAL_RESTART.set_defaults(func=devlab_bench.actions.global_restart.action)
105+
101106
#Add Subparser for global_status action
102107
PARSER_GLOBAL_STATUS = SUBPARSERS.add_parser('global-status', help='Get a global status of all environments where devlab has created containers')
103108
PARSER_GLOBAL_STATUS.set_defaults(func=devlab_bench.actions.global_status.action)
@@ -150,7 +155,12 @@ if __name__ == '__main__':
150155

151156
#The 'update' action is special and doesn't need all of the checks or a devlab_bench.PROJ_ROOT etc..
152157
#it also will exit after executing
153-
if ARGS.func in [devlab_bench.actions.upgrade.action, devlab_bench.actions.global_status.action, action_default]:
158+
if ARGS.func in [
159+
devlab_bench.actions.upgrade.action,
160+
devlab_bench.actions.global_restart.action,
161+
devlab_bench.actions.global_status.action,
162+
action_default
163+
]:
154164
ARGS.func(**vars(ARGS))
155165

156166
if ARGS.project_root:

devlab_bench/actions/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
import devlab_bench.actions.build
55
import devlab_bench.actions.down
6+
import devlab_bench.actions.global_restart
67
import devlab_bench.actions.global_status
78
import devlab_bench.actions.restart
89
import devlab_bench.actions.reset
@@ -15,6 +16,7 @@
1516
__all__ = [
1617
'build',
1718
'down',
19+
'global_restart',
1820
'global_status',
1921
'restart',
2022
'reset',

devlab_bench/actions/build.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import os
77
import sys
88

9+
import devlab_bench
910
import devlab_bench.helpers.docker
10-
from devlab_bench import DEVLAB_ROOT, IMAGES, PROJ_ROOT
1111
from devlab_bench.helpers.common import get_config, get_ordinal_sorting
1212
from devlab_bench.helpers.docker import docker_obj_status, DockerHelper, get_needed_images
1313

@@ -39,7 +39,7 @@ def action(images='*', clean=False, no_cache=False, pull=False, skip_pull_images
3939
log.debug("Will build with no_cache set to: %s", no_cache)
4040
log.debug("Will build with pull set to: %s", pull)
4141
config = get_config()
42-
base_images_dict = dict(IMAGES)
42+
base_images_dict = dict(devlab_bench.IMAGES)
4343
images_dict = dict(base_images_dict)
4444
docker_helper = devlab_bench.helpers.docker.DOCKER
4545
docker_helper_base = DockerHelper(
@@ -99,12 +99,12 @@ def action(images='*', clean=False, no_cache=False, pull=False, skip_pull_images
9999
else:
100100
image_n_tag = '{}:{}'.format(image, images_dict[image]['tag'])
101101
image_status = docker_obj_status(image_n_tag, 'image', devlab_bench.helpers.docker.DOCKER, logger=log)[0]
102-
image_context = os.path.dirname('{}/{}'.format(PROJ_ROOT, images_dict[image]['docker_file']))
102+
image_context = os.path.dirname('{}/{}'.format(devlab_bench.PROJ_ROOT, images_dict[image]['docker_file']))
103103
docker_helper_obj = docker_helper
104-
build_context = PROJ_ROOT
104+
build_context = devlab_bench.PROJ_ROOT
105105
if image in base_images_to_build: #Override default build context for built-in images
106-
build_context = DEVLAB_ROOT
107-
image_context = DEVLAB_ROOT
106+
build_context = devlab_bench.DEVLAB_ROOT
107+
image_context = devlab_bench.DEVLAB_ROOT
108108
docker_helper_obj = docker_helper_base
109109
images_dict[image]['docker_file_full_path'] = '{}/{}'.format(build_context, images_dict[image]['docker_file'])
110110
if 'build_opts' not in images_dict[image]:
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""
2+
Things dealing with the 'global_restart' action
3+
"""
4+
import sys
5+
import logging
6+
7+
import devlab_bench
8+
from devlab_bench.helpers.common import get_config
9+
from devlab_bench.helpers.docker import DockerHelper
10+
def action(**kwargs):
11+
"""
12+
Restart all containers spun up with devlab across all environments
13+
"""
14+
log = logging.getLogger('Global-Restart')
15+
restart_args = kwargs
16+
global_devlab_docker = DockerHelper(
17+
filter_label='com.lab.type=devlab'
18+
)
19+
containers = global_devlab_docker.get_containers()[1]
20+
project_map = {}
21+
log.info("containers='%s'", containers)
22+
for cont in containers:
23+
cont_name = cont['name']
24+
comp_name = cont_name
25+
comp_logger = logging.getLogger('{}-{}'.format(log.name, cont_name))
26+
details = global_devlab_docker.inspect_container(cont_name)[0]
27+
labels = details['Config']['Labels']
28+
container_project = None
29+
for label in labels:
30+
if label == 'com.lab.project':
31+
container_project = labels[label]
32+
break
33+
if not container_project:
34+
log.error('Container: "%s" does not have a project path defined in the label "com.lab.project"', cont_name)
35+
sys.exit(1)
36+
if cont_name.endswith('-devlab'):
37+
comp_name = cont_name[0:len(cont_name)-7]
38+
try:
39+
project_map[container_project]['components'].append(comp_name)
40+
except KeyError:
41+
project_map[container_project] = {
42+
'components': [comp_name]
43+
}
44+
for project in project_map:
45+
restart_args['components'] = []
46+
comp_logger.info('Performing restarts for project at path: %s', project)
47+
comp_logger.debug('Project components to restart: "%s"', ','.join(project_map[project]['components']))
48+
#Switch to other Devlab env:
49+
devlab_bench.PROJ_ROOT = project
50+
devlab_bench.CONFIG = get_config(force_reload=True)
51+
devlab_bench.helpers.docker.DOCKER = DockerHelper(
52+
labels=[
53+
'com.lab.type=devlab',
54+
'com.lab.project={}'.format(project),
55+
devlab_bench.CONFIG['project_filter']
56+
]
57+
)
58+
#Customize the components to pass to the restart action
59+
restart_args['components'] = project_map[project]['components']
60+
#Execute the restart action
61+
devlab_bench.actions.restart.action(logger=logging.getLogger('{}-{}'.format(comp_logger.name, 'Restart')), **restart_args)
62+
sys.exit(0)

devlab_bench/actions/global_status.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Things dealing with the 'global_satus' action
2+
Things dealing with the 'global_status' action
33
"""
44
import sys
55

devlab_bench/actions/restart.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import devlab_bench.actions.down
77
import devlab_bench.actions.up
88
from devlab_bench.helpers.common import get_components, unnest_list
9-
def action(components='*', update_images=False, **kwargs):
9+
def action(components='*', logger=None, update_images=False, **kwargs):
1010
"""
1111
Restart components by bringing them down and then back up again
1212
@@ -15,7 +15,10 @@ def action(components='*', update_images=False, **kwargs):
1515
"""
1616
#restart
1717
ignored_args = kwargs
18-
log = logging.getLogger('Restart')
18+
if logger:
19+
log = logger
20+
else:
21+
log = logging.getLogger('Restart')
1922
components_to_restart = components
2023
rm = False
2124
if isinstance(components, str):

devlab_bench/helpers/docker.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def rm_image(self, name):
452452
logger=self.log
453453
).run()
454454
return cmd_ret
455-
def run_container(self, image, name, network=None, ports=None, background=True, interactive=False, ignore_nonzero_rc=False, cmd=None, logger=None, mounts=None, systemd_support=False, run_opts=None, **kwargs): #pylint: disable=too-many-arguments
455+
def run_container(self, image, name, network=None, ports=None, background=True, interactive=False, ignore_nonzero_rc=False, cmd=None, logger=None, mounts=None, systemd_support=False, systemd_tmpfs_args=None, run_opts=None, **kwargs): #pylint: disable=too-many-arguments
456456
"""
457457
Run a docker_container
458458
@@ -473,6 +473,8 @@ def run_container(self, image, name, network=None, ports=None, background=True,
473473
'docker run'. (OPTIONAL)
474474
systemd_support: bool, whether to enable opts to let systemd work
475475
inside the container. (OPTIONAL)
476+
systemd_tmpfs_args: comma separated string of arguments to pass to
477+
the --tmpfs argument when systemd_support is True
476478
Returns:
477479
tuple where:
478480
First Element is the return code from docker
@@ -498,10 +500,12 @@ def run_container(self, image, name, network=None, ports=None, background=True,
498500
if network:
499501
opts.append("--network={}".format(network))
500502
if systemd_support:
503+
if systemd_tmpfs_args:
504+
systemd_tmpfs_args=':{}'.format(systemd_tmpfs_args)
501505
opts += [
502-
'--tmpfs=/run',
503-
'--tmpfs=/run/lock',
504-
'--tmpfs=/tmp',
506+
'--tmpfs=/run{}'.format(systemd_tmpfs_args),
507+
'--tmpfs=/run/lock{}'.format(systemd_tmpfs_args),
508+
'--tmpfs=/tmp{}'.format(systemd_tmpfs_args),
505509
'--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro',
506510
'-t' #This is needed so that 'docker logs' will show systemd output
507511
]

installer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,9 @@ def list_packages(path, logger):
395395
else:
396396
logger = logging.getLogger('list_packages')
397397
packages = {}
398-
path = path.lower()
399398
found_files = []
400399
if 'http' in path:
400+
path = path.lower()
401401
log.debug("Repo path is an HTTP url")
402402
if 'github.com/' in path and path.endswith('releases'):
403403
log.debug('Repo path is a github releases url. Looking for devlab packages in releases')

0 commit comments

Comments
 (0)