stoobly-agent 1.7.2__py3-none-any.whl → 1.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stoobly_agent/__init__.py +1 -1
- stoobly_agent/app/cli/intercept_cli.py +2 -0
- stoobly_agent/app/cli/scaffold/constants.py +0 -3
- stoobly_agent/app/cli/scaffold/docker/constants.py +0 -1
- stoobly_agent/app/cli/scaffold/docker/service/builder.py +10 -4
- stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py +50 -23
- stoobly_agent/app/cli/scaffold/docker/workflow/decorators_factory.py +2 -2
- stoobly_agent/app/cli/scaffold/service_config.py +10 -0
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +0 -29
- stoobly_agent/app/cli/scaffold/templates/__init__.py +2 -2
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +1 -1
- stoobly_agent/app/cli/scaffold/templates/app/gateway/.docker-compose.base.template.yml +5 -5
- stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.configure +2 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.init +2 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.configure +2 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.init +2 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.configure +2 -1
- stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.init +2 -0
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.configure +0 -6
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.configure +0 -6
- stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.configure +0 -6
- stoobly_agent/app/cli/scaffold/templates/constants.py +5 -5
- stoobly_agent/app/cli/scaffold/templates/factory.py +5 -7
- stoobly_agent/app/cli/scaffold_cli.py +11 -0
- stoobly_agent/app/settings/__init__.py +8 -4
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- {stoobly_agent-1.7.2.dist-info → stoobly_agent-1.8.1.dist-info}/METADATA +1 -1
- {stoobly_agent-1.7.2.dist-info → stoobly_agent-1.8.1.dist-info}/RECORD +31 -32
- stoobly_agent/app/cli/scaffold/templates/run/nginx.tmpl +0 -1060
- {stoobly_agent-1.7.2.dist-info → stoobly_agent-1.8.1.dist-info}/LICENSE +0 -0
- {stoobly_agent-1.7.2.dist-info → stoobly_agent-1.8.1.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.7.2.dist-info → stoobly_agent-1.8.1.dist-info}/entry_points.txt +0 -0
stoobly_agent/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
COMMAND = 'stoobly-agent'
|
2
|
-
VERSION = '1.
|
2
|
+
VERSION = '1.8.1'
|
@@ -40,9 +40,6 @@ STOOBLY_HOME_DIR = '/home/stoobly'
|
|
40
40
|
STOOBLY_DATA_DIR = os.path.join(STOOBLY_HOME_DIR, DATA_DIR_NAME)
|
41
41
|
STOOBLY_CERTS_DIR = os.path.join(STOOBLY_DATA_DIR, CERTS_DIR_NAME)
|
42
42
|
USER_ID_ENV = 'USER_ID'
|
43
|
-
VIRTUAL_HOST_ENV = 'VIRTUAL_HOST'
|
44
|
-
VIRTUAL_PORT_ENV = 'VIRTUAL_PORT'
|
45
|
-
VIRTUAL_PROTO_ENV = 'VIRTUAL_PROTO'
|
46
43
|
WORKFLOW_CONTAINER_CONFIGURE = 'configure'
|
47
44
|
WORKFLOW_CONTAINER_INIT = 'init'
|
48
45
|
WORKFLOW_CONTAINER_PROXY = 'proxy'
|
@@ -10,7 +10,6 @@ DOCKER_COMPOSE_CUSTOM = 'docker-compose.yml'
|
|
10
10
|
DOCKER_COMPOSE_NETWORKS = '.docker-compose.networks.yml'
|
11
11
|
DOCKERFILE_CONTEXT = '.Dockerfile.context'
|
12
12
|
DOCKERFILE_SERVICE = 'Dockerfile.source'
|
13
|
-
GATEWAY_NGINX_TEMPLATE = 'nginx.tmpl'
|
14
13
|
|
15
14
|
# TODO: add scaffold container name templates here
|
16
15
|
|
@@ -91,22 +91,28 @@ class ServiceBuilder(Builder):
|
|
91
91
|
if not self.config.hostname:
|
92
92
|
return
|
93
93
|
|
94
|
+
service_id = self.config.id
|
94
95
|
environment = { **self.env_dict() }
|
96
|
+
labels = [
|
97
|
+
'traefik.enable=true',
|
98
|
+
f"traefik.http.routers.{service_id}.rule=Host(`{SERVICE_HOSTNAME}`)",
|
99
|
+
f"traefik.http.services.{service_id}.loadbalancer.server.port={SERVICE_PORT}"
|
100
|
+
]
|
95
101
|
volumes = []
|
96
102
|
|
97
|
-
environment['VIRTUAL_HOST'] = SERVICE_HOSTNAME
|
98
|
-
environment['VIRTUAL_PORT'] = SERVICE_PORT
|
99
|
-
environment['VIRTUAL_PROTO'] = SERVICE_SCHEME
|
100
|
-
|
101
103
|
if self.config.detached:
|
102
104
|
self.__with_detached_volumes(volumes)
|
103
105
|
|
106
|
+
if self.config.tls:
|
107
|
+
labels.append(f"traefik.http.routers.{service_id}.tls=true")
|
108
|
+
|
104
109
|
base = {
|
105
110
|
'environment': environment,
|
106
111
|
'extends': {
|
107
112
|
'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
|
108
113
|
'service': self.extends_service
|
109
114
|
},
|
115
|
+
'labels': labels,
|
110
116
|
'working_dir': self.__working_dir,
|
111
117
|
}
|
112
118
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import os
|
2
2
|
import pdb
|
3
|
-
import shutil
|
4
3
|
import yaml
|
5
4
|
|
6
5
|
from typing import List
|
@@ -8,9 +7,8 @@ from typing import List
|
|
8
7
|
from stoobly_agent.config.data_dir import DATA_DIR_NAME, TMP_DIR_NAME
|
9
8
|
from stoobly_agent.app.cli.scaffold.constants import APP_DIR
|
10
9
|
from stoobly_agent.app.cli.scaffold.service_config import ServiceConfig
|
11
|
-
from stoobly_agent.app.cli.scaffold.docker.constants import APP_INGRESS_NETWORK_NAME, APP_EGRESS_NETWORK_NAME, DOCKER_COMPOSE_BASE, DOCKER_COMPOSE_BASE_TEMPLATE
|
10
|
+
from stoobly_agent.app.cli.scaffold.docker.constants import APP_INGRESS_NETWORK_NAME, APP_EGRESS_NETWORK_NAME, DOCKER_COMPOSE_BASE, DOCKER_COMPOSE_BASE_TEMPLATE
|
12
11
|
from stoobly_agent.app.cli.scaffold.templates.constants import CORE_GATEWAY_SERVICE_NAME
|
13
|
-
from stoobly_agent.app.cli.scaffold.templates import run_template_path
|
14
12
|
|
15
13
|
def configure_gateway(service_paths: List[str], no_publish = False):
|
16
14
|
if len(service_paths) == 0:
|
@@ -38,7 +36,7 @@ def configure_gateway(service_paths: List[str], no_publish = False):
|
|
38
36
|
gateway_base['ports'] = ports
|
39
37
|
|
40
38
|
app_dir_path = os.path.dirname(os.path.dirname(service_dir_path))
|
41
|
-
|
39
|
+
__with_traefik_config(service_paths, gateway_base, app_dir_path)
|
42
40
|
__with_networks(gateway_base, hostnames)
|
43
41
|
|
44
42
|
with open(docker_compose_dest_path, 'w') as fp:
|
@@ -52,31 +50,60 @@ def __with_networks(config: dict, hostnames: List[str]):
|
|
52
50
|
'aliases': hostnames
|
53
51
|
}
|
54
52
|
|
55
|
-
def
|
56
|
-
if not
|
57
|
-
|
53
|
+
def __with_traefik_config(service_paths: str, compose: dict, app_dir_path: str):
|
54
|
+
if not compose['volumes']:
|
55
|
+
compose['volumes'] = []
|
56
|
+
|
57
|
+
entry_points = {}
|
58
|
+
certificates = []
|
59
|
+
traefik_config = {
|
60
|
+
'accessLog': {
|
61
|
+
'format': 'common',
|
62
|
+
},
|
63
|
+
'entryPoints': entry_points,
|
64
|
+
'log': {
|
65
|
+
'format': 'common',
|
66
|
+
'level': 'INFO',
|
67
|
+
},
|
68
|
+
'providers': {
|
69
|
+
'docker': {
|
70
|
+
'exposedByDefault': False
|
71
|
+
}
|
72
|
+
},
|
73
|
+
'tls': {
|
74
|
+
'certificates': certificates
|
75
|
+
}
|
76
|
+
}
|
58
77
|
|
59
|
-
|
60
|
-
|
61
|
-
nginx_template_relative_path = os.path.join(DATA_DIR_NAME, TMP_DIR_NAME, GATEWAY_NGINX_TEMPLATE)
|
62
|
-
nginx_template_dest_path = os.path.join(app_dir_path, nginx_template_relative_path)
|
78
|
+
for path in service_paths:
|
79
|
+
config = ServiceConfig(path)
|
63
80
|
|
64
|
-
|
65
|
-
|
81
|
+
if not config.hostname:
|
82
|
+
continue
|
66
83
|
|
67
|
-
|
84
|
+
entry_points[config.port] = {
|
85
|
+
'address': f":{config.port}"
|
86
|
+
}
|
68
87
|
|
69
|
-
|
70
|
-
|
71
|
-
|
88
|
+
if config.scheme == 'https':
|
89
|
+
certificates.append({
|
90
|
+
'certFile': f"/certs/{config.hostname}.crt",
|
91
|
+
'keyFile': f"/certs/{config.hostname}.key"
|
92
|
+
})
|
93
|
+
|
94
|
+
# Create traefik.yml in .stoobly/tmp
|
95
|
+
traefik_template_relative_path = os.path.join(DATA_DIR_NAME, TMP_DIR_NAME, 'traefik.yml')
|
96
|
+
traefik_template_dest_path = os.path.join(app_dir_path, traefik_template_relative_path)
|
72
97
|
|
73
|
-
|
74
|
-
|
75
|
-
config['environment'] = environment
|
76
|
-
else:
|
77
|
-
environment = config['environment']
|
98
|
+
if not os.path.exists(os.path.dirname(traefik_template_dest_path)):
|
99
|
+
os.makedirs(os.path.dirname(traefik_template_dest_path), exist_ok=True)
|
78
100
|
|
79
|
-
|
101
|
+
with open(traefik_template_dest_path, 'w') as fp:
|
102
|
+
fp.write(yaml.dump(traefik_config))
|
103
|
+
|
104
|
+
compose['volumes'].append(
|
105
|
+
f"{os.path.join(APP_DIR, traefik_template_relative_path)}:/etc/traefik/traefik.yml:ro"
|
106
|
+
)
|
80
107
|
|
81
108
|
def __find_hosts(service_paths):
|
82
109
|
hostnames = []
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from stoobly_agent.app.cli.scaffold.service_config import ServiceConfig
|
2
2
|
|
3
|
-
from ...constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE
|
3
|
+
from ...constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE
|
4
4
|
from .dns_decorator import DnsDecorator
|
5
5
|
from .mock_decorator import MockDecorator
|
6
6
|
from .reverse_proxy_decorator import ReverseProxyDecorator
|
@@ -12,7 +12,7 @@ def get_workflow_decorators(workflow: str, service_config: ServiceConfig):
|
|
12
12
|
if service_config.hostname:
|
13
13
|
workflow_decorators.append(ReverseProxyDecorator)
|
14
14
|
workflow_decorators.append(DnsDecorator)
|
15
|
-
elif workflow == WORKFLOW_MOCK_TYPE:
|
15
|
+
elif workflow == WORKFLOW_MOCK_TYPE or workflow == WORKFLOW_TEST_TYPE:
|
16
16
|
if service_config.hostname:
|
17
17
|
workflow_decorators.append(ReverseProxyDecorator if service_config.detached else MockDecorator)
|
18
18
|
workflow_decorators.append(DnsDecorator)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# Wraps the .config.yml file in the service folder
|
2
|
+
import hashlib
|
3
|
+
import os
|
2
4
|
import pdb
|
3
5
|
|
4
6
|
from .config import Config
|
@@ -51,6 +53,10 @@ class ServiceConfig(Config):
|
|
51
53
|
def detached(self, v):
|
52
54
|
self.__detached = v
|
53
55
|
|
56
|
+
@property
|
57
|
+
def id(self):
|
58
|
+
return hashlib.md5(os.path.basename(self.dir).encode()).hexdigest()
|
59
|
+
|
54
60
|
@property
|
55
61
|
def hostname(self):
|
56
62
|
return (self.__hostname or '').strip()
|
@@ -120,6 +126,10 @@ class ServiceConfig(Config):
|
|
120
126
|
def scheme(self, v):
|
121
127
|
self.__scheme = v
|
122
128
|
|
129
|
+
@property
|
130
|
+
def tls(self) -> bool:
|
131
|
+
return self.__scheme == 'https'
|
132
|
+
|
123
133
|
def load(self, config = None):
|
124
134
|
config = config or self.read()
|
125
135
|
|
@@ -13,9 +13,6 @@ from docker.models.containers import Container
|
|
13
13
|
from stoobly_agent.app.cli.scaffold.constants import (
|
14
14
|
PUBLIC_FOLDER_NAME,
|
15
15
|
STOOBLY_DATA_DIR,
|
16
|
-
VIRTUAL_HOST_ENV,
|
17
|
-
VIRTUAL_PORT_ENV,
|
18
|
-
VIRTUAL_PROTO_ENV,
|
19
16
|
WORKFLOW_RECORD_TYPE,
|
20
17
|
WORKFLOW_TEST_TYPE,
|
21
18
|
)
|
@@ -172,30 +169,6 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
|
|
172
169
|
if Counter(public_folder_contents_container) != Counter(public_folder_contents_scaffold):
|
173
170
|
raise ScaffoldValidateException(f"public folder was not mounted properly, expected {self.public_dir_path} to exist in container path {public_folder_path}")
|
174
171
|
|
175
|
-
# Note: might not need this if the hostname is reachable and working
|
176
|
-
def proxy_environment_variables_exist(self, container: Container) -> None:
|
177
|
-
environment_variables = container.attrs['Config']['Env']
|
178
|
-
virtual_host_exists = False
|
179
|
-
virtual_port_exists = False
|
180
|
-
virtual_proto_exists = False
|
181
|
-
|
182
|
-
for environment_variable in environment_variables:
|
183
|
-
environment_variable_name, environment_variable_value = environment_variable.split('=')
|
184
|
-
if environment_variable_name == VIRTUAL_HOST_ENV:
|
185
|
-
virtual_host_exists = True
|
186
|
-
elif environment_variable_name == VIRTUAL_PORT_ENV:
|
187
|
-
virtual_port_exists = True
|
188
|
-
elif environment_variable_name == VIRTUAL_PROTO_ENV:
|
189
|
-
virtual_proto_exists = True
|
190
|
-
|
191
|
-
if not virtual_host_exists:
|
192
|
-
raise ScaffoldValidateException(f"VIRTUAL_HOST environment variable is missing from container: {container.name}")
|
193
|
-
if not virtual_port_exists:
|
194
|
-
raise ScaffoldValidateException(f"VIRTUAL_POST environment variable is missing from container: {container.name}")
|
195
|
-
if not virtual_proto_exists:
|
196
|
-
raise ScaffoldValidateException(f"VIRTUAL_PROTO environment variable is missing from container: {container.name}")
|
197
|
-
|
198
|
-
|
199
172
|
def validate_proxy_container(self, service_proxy_container: Container):
|
200
173
|
print(f"Validating proxy container: {service_proxy_container.name}")
|
201
174
|
|
@@ -209,8 +182,6 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
|
|
209
182
|
if not self.service_config.detached:
|
210
183
|
self.validate_public_folder(service_proxy_container)
|
211
184
|
|
212
|
-
self.proxy_environment_variables_exist(service_proxy_container)
|
213
|
-
|
214
185
|
def validate_service_container(self):
|
215
186
|
pass
|
216
187
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
services:
|
2
2
|
gateway_base:
|
3
|
-
|
4
|
-
|
5
|
-
image:
|
3
|
+
command:
|
4
|
+
- "--configFile=/etc/traefik/traefik.yml"
|
5
|
+
image: traefik:v3
|
6
6
|
profiles:
|
7
7
|
- gateway_base
|
8
8
|
volumes:
|
9
|
-
- /var/run/docker.sock:/
|
10
|
-
- ${CERTS_DIR}:/
|
9
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
10
|
+
- ${CERTS_DIR}:/certs:ro
|
@@ -3,12 +3,6 @@
|
|
3
3
|
# This file was automatically generated. DO NOT EDIT.
|
4
4
|
# Any changes made to this file will be overwritten.
|
5
5
|
|
6
|
-
echo "Configuring intercept..."
|
7
|
-
stoobly-agent intercept configure --mode mock --policy all
|
8
|
-
|
9
|
-
echo "Enabling intercept..."
|
10
|
-
stoobly-agent intercept enable
|
11
|
-
|
12
6
|
entrypoint=$1
|
13
7
|
|
14
8
|
if [ -e "$entrypoint" ]; then
|
@@ -3,12 +3,6 @@
|
|
3
3
|
# This file was automatically generated. DO NOT EDIT.
|
4
4
|
# Any changes made to this file will be overwritten.
|
5
5
|
|
6
|
-
echo "Configuring intercept..."
|
7
|
-
stoobly-agent intercept configure --mode record --policy all
|
8
|
-
|
9
|
-
echo "Disabling intercept..."
|
10
|
-
stoobly-agent intercept disable
|
11
|
-
|
12
6
|
entrypoint=$1
|
13
7
|
|
14
8
|
if [ -e "$entrypoint" ]; then
|
@@ -3,12 +3,6 @@
|
|
3
3
|
# This file was automatically generated. DO NOT EDIT.
|
4
4
|
# Any changes made to this file will be overwritten.
|
5
5
|
|
6
|
-
echo "Configuring intercept..."
|
7
|
-
stoobly-agent intercept configure --mode mock --policy all
|
8
|
-
|
9
|
-
echo "Enabling intercept..."
|
10
|
-
stoobly-agent intercept enable
|
11
|
-
|
12
6
|
entrypoint=$1
|
13
7
|
|
14
8
|
if [ -e "$entrypoint" ]; then
|
@@ -16,14 +16,13 @@ CUSTOM_CONFIGURE = os.path.join('bin', 'configure')
|
|
16
16
|
CUSTOM_INIT = os.path.join('bin', 'init')
|
17
17
|
CUSTOM_FIXTURES = 'fixtures.yml'
|
18
18
|
CUSTOM_LIFECYCLE_HOOKS = os.path.join('lifecycle_hooks.py')
|
19
|
+
CUSTOM_PUBLIC_GITIGNORE = os.path.join('public', '.gitignore')
|
19
20
|
MAINTAINED_CONFIGURE = os.path.join('bin', '.configure')
|
20
21
|
MAINTAINED_INIT = os.path.join('bin', '.init')
|
21
|
-
MAINTAINED_PUBLIC = os.path.join('public', '.gitignore')
|
22
22
|
|
23
23
|
MOCK_WORKFLOW_MAINTAINED_FILES = [
|
24
24
|
MAINTAINED_CONFIGURE,
|
25
25
|
MAINTAINED_INIT,
|
26
|
-
MAINTAINED_PUBLIC
|
27
26
|
]
|
28
27
|
|
29
28
|
MOCK_WORKFLOW_CUSTOM_FILES = [
|
@@ -32,6 +31,7 @@ MOCK_WORKFLOW_CUSTOM_FILES = [
|
|
32
31
|
CUSTOM_FIXTURES,
|
33
32
|
CUSTOM_INIT,
|
34
33
|
CUSTOM_LIFECYCLE_HOOKS,
|
34
|
+
CUSTOM_PUBLIC_GITIGNORE
|
35
35
|
]
|
36
36
|
|
37
37
|
RECORD_WORKFLOW_MAINTAINED_FILES = [
|
@@ -43,13 +43,12 @@ RECORD_WORKFLOW_CUSTOM_FILES = [
|
|
43
43
|
CUSTOM_BUILD,
|
44
44
|
CUSTOM_CONFIGURE,
|
45
45
|
CUSTOM_INIT,
|
46
|
-
CUSTOM_LIFECYCLE_HOOKS
|
46
|
+
CUSTOM_LIFECYCLE_HOOKS,
|
47
47
|
]
|
48
48
|
|
49
49
|
TEST_WORKFLOW_MAINTAINED_FILES = [
|
50
50
|
MAINTAINED_CONFIGURE,
|
51
51
|
MAINTAINED_INIT,
|
52
|
-
MAINTAINED_PUBLIC
|
53
52
|
]
|
54
53
|
|
55
54
|
TEST_WORKFLOW_CUSTOM_FILES = [
|
@@ -57,7 +56,8 @@ TEST_WORKFLOW_CUSTOM_FILES = [
|
|
57
56
|
CUSTOM_CONFIGURE,
|
58
57
|
CUSTOM_FIXTURES,
|
59
58
|
CUSTOM_INIT,
|
60
|
-
CUSTOM_LIFECYCLE_HOOKS
|
59
|
+
CUSTOM_LIFECYCLE_HOOKS,
|
60
|
+
CUSTOM_PUBLIC_GITIGNORE
|
61
61
|
]
|
62
62
|
|
63
63
|
SERVICE_HOSTNAME_BUILD_ARG = 'SERVICE_HOSTNAME'
|
@@ -1,7 +1,9 @@
|
|
1
|
+
import pdb
|
2
|
+
|
1
3
|
from ..constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE
|
2
4
|
from ..docker.workflow.builder import WorkflowBuilder
|
3
5
|
from .constants import (
|
4
|
-
CUSTOM_CONFIGURE, CUSTOM_INIT,
|
6
|
+
CUSTOM_CONFIGURE, CUSTOM_INIT, CUSTOM_PUBLIC_GITIGNORE, MAINTAINED_CONFIGURE, MOCK_WORKFLOW_CUSTOM_FILES, MOCK_WORKFLOW_MAINTAINED_FILES, RECORD_WORKFLOW_CUSTOM_FILES, RECORD_WORKFLOW_MAINTAINED_FILES, TEST_WORKFLOW_CUSTOM_FILES, TEST_WORKFLOW_MAINTAINED_FILES
|
5
7
|
)
|
6
8
|
|
7
9
|
def custom_files(workflow: str, workflow_builder: WorkflowBuilder):
|
@@ -21,8 +23,8 @@ def custom_files(workflow: str, workflow_builder: WorkflowBuilder):
|
|
21
23
|
|
22
24
|
# Fixtures are only relevant if the workflow is mock/test and if the service has a hostname
|
23
25
|
if not workflow_builder.config.hostname:
|
24
|
-
if
|
25
|
-
files.remove(
|
26
|
+
if CUSTOM_PUBLIC_GITIGNORE in files:
|
27
|
+
files.remove(CUSTOM_PUBLIC_GITIGNORE)
|
26
28
|
|
27
29
|
return files
|
28
30
|
|
@@ -39,8 +41,4 @@ def maintained_files(workflow: str, workflow_builder: WorkflowBuilder):
|
|
39
41
|
if workflow_builder.configure in workflow_builder.services:
|
40
42
|
files.append(MAINTAINED_CONFIGURE)
|
41
43
|
|
42
|
-
if not workflow_builder.config.hostname:
|
43
|
-
if MAINTAINED_PUBLIC in files:
|
44
|
-
files.remove(MAINTAINED_PUBLIC)
|
45
|
-
|
46
44
|
return files
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import click
|
2
2
|
import os
|
3
3
|
import pdb
|
4
|
+
import re
|
4
5
|
import sys
|
5
6
|
|
6
7
|
from io import TextIOWrapper
|
@@ -142,6 +143,16 @@ def mkcert(**kwargs):
|
|
142
143
|
def create(**kwargs):
|
143
144
|
__validate_app_dir(kwargs['app_dir_path'])
|
144
145
|
|
146
|
+
if '/' in kwargs['service_name']:
|
147
|
+
print(f"Error: {kwargs['service_name']} is invalid. It cannot container '/", file=sys.stderr)
|
148
|
+
sys.exit(1)
|
149
|
+
|
150
|
+
if kwargs.get('hostname'):
|
151
|
+
hostname_regex = re.compile(r'^[a-zA-Z0-9.-]+$')
|
152
|
+
if not re.search(hostname_regex, kwargs['hostname']):
|
153
|
+
print(f"Error: {kwargs['hostname']} is invalid.", file=sys.stderr)
|
154
|
+
sys.exit(1)
|
155
|
+
|
145
156
|
app = App(kwargs['app_dir_path'], DOCKER_NAMESPACE)
|
146
157
|
|
147
158
|
service = Service(kwargs['service_name'], app)
|
@@ -178,14 +178,18 @@ class Settings:
|
|
178
178
|
|
179
179
|
def write(self, contents):
|
180
180
|
if contents:
|
181
|
-
|
182
|
-
|
183
|
-
fp.close()
|
181
|
+
with open(self.__settings_file_path, 'w') as fp:
|
182
|
+
yaml.dump(contents, fp, allow_unicode=True)
|
184
183
|
|
185
184
|
### Helpers
|
186
185
|
|
187
186
|
def __create_default_file(self):
|
188
|
-
|
187
|
+
contents = ''
|
188
|
+
with open(SourceDir.instance().settings_template_file_path, 'r') as fp:
|
189
|
+
contents = fp.read()
|
190
|
+
|
191
|
+
with open(self.__settings_file_path, 'w') as fp:
|
192
|
+
fp.write(contents)
|
189
193
|
|
190
194
|
def __detect_paths(self):
|
191
195
|
self.__settings_file_path = os.environ.get(env_vars.AGENT_CONFIG_PATH) or self.__data_dir.settings_file_path
|
@@ -1 +1 @@
|
|
1
|
-
1.7.
|
1
|
+
1.7.2
|