Passed
Pull Request — master (#3)
by
unknown
04:15
created

get_configured_services()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.2963

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
c 1
b 0
f 1
dl 0
loc 4
ccs 1
cts 3
cp 0.3333
crap 1.2963
rs 10
1 1
import click
2 1
import os
3 1
import subprocess
4 1
import sys
5
6 1
from stakkr import package_utils
7 1
from stakkr.configreader import Config
8 1
verbose = click.style('[VERBOSE] ', fg='green')
9
10
11 1
@click.command(help="Wrapper for docker-compose", context_settings=dict(ignore_unknown_options=True))
12 1
@click.option('--config', '-c', help="Override the conf/compose.ini")
13 1
@click.argument('command', nargs=-1, type=click.UNPROCESSED)
14 1
def cli(config: str, command):
15
    main_config = get_main_config(config)
16
    set_env_values_from_conf(main_config)
17
18
    project_name = main_config.get('project_name')
19
    os.putenv('COMPOSE_PROJECT_NAME', project_name)
20
21
    # What to load
22
    compose_file = package_utils.get_file('static', 'docker-compose.yml')
23
    activated_services = get_enabled_services(main_config.get('services'))
24
25
    # Create the command
26
    services = []
27
    for service in activated_services:
28
        services.append('-f')
29
        services.append(service)
30
31
    base_cmd = ['docker-compose', '-f', compose_file] + services + ['-p', project_name]
32
33
    # _dump_compose_config(base_cmd, project_name)
34
35
    click.echo(verbose + 'Compose command: ' + ' '.join(base_cmd + list(command)), err=True)
36
    subprocess.call(base_cmd + list(command))
37
38
39 1
def add_services_from_plugins(available_services: list):
40 1
    from pkg_resources import iter_entry_points
41
42
    # Override services with plugins
43 1
    for entry in iter_entry_points('stakkr.plugins'):
44
        plugin_dir = str(entry).split('=')[0].strip()
45
        services_dir = package_utils.get_venv_basedir() + '/plugins/' + plugin_dir + '/services'
46
47
        conf_files = _get_services_from_dir(services_dir)
48
        if conf_files is []:
49
            continue
50
51
        for conf_file in conf_files:
52
            available_services[conf_file[:-4]] = services_dir + '/' + conf_file
53
54 1
    return available_services
55
56
57 1
def add_local_services(available_services: list):
58 1
    services_dir = package_utils.get_venv_basedir() + '/services'
59
60 1
    conf_files = _get_services_from_dir(services_dir)
61 1
    for conf_file in conf_files:
62
        available_services[conf_file[:-4]] = services_dir + '/' + conf_file
63
64 1
    return available_services
65
66
67 1
def get_available_services():
68 1
    services_dir = package_utils.get_dir('static') + '/services/'
69 1
    conf_files = _get_services_from_dir(services_dir)
70
71 1
    services = dict()
72 1
    for conf_file in conf_files:
73 1
        services[conf_file[:-4]] = services_dir + conf_file
74
75 1
    return services
76
77
78 1
def get_enabled_services(configured_services: list):
79
    # Services available from base and plugins
80 1
    available_services = get_available_services()
81 1
    available_services = add_services_from_plugins(available_services)
82 1
    available_services = add_local_services(available_services)
83
84 1
    services_files = []
85 1
    for service in configured_services:
86 1
        if service not in available_services:
87 1
            print(click.style('Error: service "{}" has no configuration file. Check your compose.ini'.format(service), fg='red'))
88 1
            sys.exit(1)
89 1
        services_files.append(available_services[service])
90
91 1
    return services_files
92
93 1
def get_configured_services(config_file: str = None):
94
    # Services configured in the given config file. 
95
    configured_services = get_main_config(config_file).get('services')
96
    return configured_services
97
98 1
def get_main_config(config: str):
99
    config = Config(config)
100
    main_config = config.read()
101
102
    if main_config is False:
103
        config.display_errors()
104
        sys.exit(1)
105
106
    return main_config['main']
107
108
109 1
def set_env_values_from_conf(config: list):
110
    os.environ['DOCKER_UID'] = _get_uid(config.pop('uid'))
111
    os.environ['DOCKER_GID'] = _get_gid(config.pop('gid'))
112
    os.environ['COMPOSE_BASE_DIR'] = package_utils.get_venv_basedir()
113
114
    for parameter, value in config.items():
115
        parameter = 'DOCKER_{}'.format(parameter.replace('.', '_').upper())
116
        os.environ[parameter] = str(value)
117
118
119 1
def _get_services_from_dir(services_dir: str):
120 1
    if os.path.isdir(services_dir) is False:
121
        return []
122
123 1
    return [service for service in os.listdir(services_dir) if service.endswith('.yml')]
124
125
126 1
def _get_uid(uid: int):
127 1
    if uid is not None:
128 1
        return str(uid)
129
130 1
    return '1000' if os.name == 'nt' else str(os.getuid())
131
132
133 1
def _get_gid(gid: int):
134 1
    if gid is not None:
135 1
        return str(gid)
136
137 1
    return '1000' if os.name == 'nt' else str(os.getgid())
138
139
140
# def _dump_compose_config(base_cmd: list, project_name: str):
141
    # import tempfile
142
143
    # tmpdir = '{}/stakkr/{}'.format(tempfile.gettempdir(), project_name)
144
    # os.putenv('TMP_COMPOSE_CONFIG_DIR', tmpdir)
145
    # try:
146
        # os.makedirs(tmpdir)
147
    # except:
148
        # pass
149
150
    # with open(tmpdir + '/docker-compose.yml', 'w') as file:
151
        # file.write(subprocess.check_output(base_cmd + ['config']).decode())
152
153
154 1
if __name__ == '__main__':
155
    cli()
156