stoobly-agent 1.2.2__py3-none-any.whl → 1.3.0__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.
Files changed (69) hide show
  1. stoobly_agent/__init__.py +1 -1
  2. stoobly_agent/app/cli/helpers/certificate_authority.py +1 -5
  3. stoobly_agent/app/cli/scaffold/app.py +14 -32
  4. stoobly_agent/app/cli/scaffold/app_command.py +4 -7
  5. stoobly_agent/app/cli/scaffold/app_config.py +15 -2
  6. stoobly_agent/app/cli/scaffold/app_create_command.py +18 -2
  7. stoobly_agent/app/cli/scaffold/command.py +1 -1
  8. stoobly_agent/app/cli/scaffold/constants.py +9 -3
  9. stoobly_agent/app/cli/scaffold/docker/app_builder.py +3 -7
  10. stoobly_agent/app/cli/scaffold/docker/builder.py +1 -1
  11. stoobly_agent/app/cli/scaffold/docker/constants.py +0 -1
  12. stoobly_agent/app/cli/scaffold/docker/service/builder.py +12 -11
  13. stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +14 -31
  14. stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +6 -2
  15. stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +6 -2
  16. stoobly_agent/app/cli/scaffold/service.py +1 -1
  17. stoobly_agent/app/cli/scaffold/service_command.py +1 -1
  18. stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +6 -8
  19. stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +2 -4
  20. stoobly_agent/app/cli/scaffold/templates/app/.Makefile +37 -21
  21. stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.base.yml +8 -13
  22. stoobly_agent/app/cli/scaffold/templates/app/Makefile +1 -1
  23. stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +8 -4
  24. stoobly_agent/app/cli/scaffold/templates/app/build/mock/.docker-compose.mock.yml +2 -6
  25. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.configure +3 -0
  26. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.init +3 -0
  27. stoobly_agent/app/cli/scaffold/templates/app/build/record/.docker-compose.record.yml +2 -6
  28. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.configure +3 -0
  29. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.init +3 -0
  30. stoobly_agent/app/cli/scaffold/templates/app/build/test/.docker-compose.test.yml +2 -6
  31. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.configure +3 -0
  32. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.init +3 -0
  33. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +2 -0
  34. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/.docker-compose.mock.yml +2 -8
  35. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/.docker-compose.record.yml +2 -8
  36. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/.docker-compose.test.yml +2 -8
  37. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml +2 -3
  38. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.logs +1 -0
  39. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/.docker-compose.mock.yml +1 -2
  40. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/.docker-compose.record.yml +1 -2
  41. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.configure +3 -0
  42. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.init +7 -1
  43. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.configure +3 -0
  44. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.init +7 -1
  45. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.configure +3 -0
  46. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.init +7 -1
  47. stoobly_agent/app/cli/scaffold/validate_command.py +2 -2
  48. stoobly_agent/app/cli/scaffold/workflow.py +5 -4
  49. stoobly_agent/app/cli/scaffold/workflow_command.py +3 -3
  50. stoobly_agent/app/cli/scaffold/workflow_run_command.py +74 -35
  51. stoobly_agent/app/cli/scaffold_cli.py +61 -44
  52. stoobly_agent/app/cli/snapshot_cli.py +6 -2
  53. stoobly_agent/app/models/adapters/joined_request_adapter.py +6 -0
  54. stoobly_agent/app/models/factories/resource/local_db/helpers/scenario_snapshot.py +3 -1
  55. stoobly_agent/app/models/helpers/apply.py +34 -17
  56. stoobly_agent/app/models/helpers/create_request_params_service.py +4 -0
  57. stoobly_agent/app/proxy/replay/body_parser_service.py +11 -3
  58. stoobly_agent/config/data_dir.py +2 -1
  59. stoobly_agent/config/schema.yml +2 -2
  60. stoobly_agent/test/app/cli/scaffold/cli_invoker.py +1 -2
  61. stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py +162 -1
  62. stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
  63. stoobly_agent/test/mock_data/scaffold/docker-compose-assets-service.yml +1 -3
  64. {stoobly_agent-1.2.2.dist-info → stoobly_agent-1.3.0.dist-info}/METADATA +1 -1
  65. {stoobly_agent-1.2.2.dist-info → stoobly_agent-1.3.0.dist-info}/RECORD +68 -69
  66. stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.proxy +0 -34
  67. {stoobly_agent-1.2.2.dist-info → stoobly_agent-1.3.0.dist-info}/LICENSE +0 -0
  68. {stoobly_agent-1.2.2.dist-info → stoobly_agent-1.3.0.dist-info}/WHEEL +0 -0
  69. {stoobly_agent-1.2.2.dist-info → stoobly_agent-1.3.0.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.2'
2
+ VERSION = '1.3.0'
@@ -23,10 +23,6 @@ class CertificateAuthority():
23
23
 
24
24
  def __init__(self, certs_dir = DataDir.instance().mitmproxy_conf_dir_path, cn = MITMPROXY_CN):
25
25
  self.certs_dir = certs_dir
26
-
27
- if not os.path.exists(certs_dir):
28
- self.generate_certs()
29
-
30
26
  self.cn = cn
31
27
  self.key_size = 2048
32
28
 
@@ -201,5 +197,5 @@ class CertificateAuthority():
201
197
  return org_name, alt_names
202
198
 
203
199
  except Exception as e:
204
- Logger.instance(LOG_ID).warn(f"Could not retrieve certificate for {domain}: {e}")
200
+ Logger.instance(LOG_ID).debug(f"Could not retrieve certificate for {domain}: {e}")
205
201
  return None, alt_names
@@ -5,20 +5,18 @@ from stoobly_agent.config.data_dir import DataDir, DATA_DIR_NAME
5
5
 
6
6
  class App():
7
7
 
8
- def __init__(self, path: str, namespace: str, **kwargs):
8
+ def __init__(self, path: str, scaffold_namespace: str, **kwargs):
9
9
  path = os.path.abspath(path) or os.getcwd()
10
10
  data_dir: DataDir = DataDir.instance(path)
11
11
 
12
- self.__scaffold_dir_path = data_dir.path
12
+ self.__data_dir_path = data_dir.path
13
13
  self.__ca_certs_dir_path = kwargs.get('ca_certs_dir_path') or data_dir.mitmproxy_conf_dir_path
14
- self.__certs_dir_path = data_dir.certs_dir_path
15
- self.__context_dir_path = data_dir.context_dir_path
14
+ self.__certs_dir_path = kwargs.get('certs_dir_path') or data_dir.certs_dir_path
15
+ self.__context_dir_path = kwargs.get('context_dir_path') or data_dir.context_dir_path
16
16
  self.__data_dir = data_dir
17
17
  self.__dir_path = path
18
- self.__name = os.path.basename(self.__dir_path)
19
- self.__network = os.path.basename(self.__dir_path)
20
- self.__namespace = namespace
21
- self.__skip_validate_path = not not kwargs.get('skip_validate_path')
18
+ self.__scaffold_namespace = scaffold_namespace
19
+ self.__skip_validate_path = not not kwargs.get('dry_run')
22
20
 
23
21
  @property
24
22
  def ca_certs_dir_path(self):
@@ -60,40 +58,24 @@ class App():
60
58
  return os.path.exists(self.dir_path)
61
59
 
62
60
  @property
63
- def name(self):
64
- return self.__name
65
-
66
- @name.setter
67
- def name(self, v: str):
68
- self.__name = v
69
-
70
- @property
71
- def network(self):
72
- return self.__network
73
-
74
- @network.setter
75
- def network(self, v: str):
76
- self.__network = v
61
+ def scaffold_namespace(self):
62
+ return self.__scaffold_namespace
77
63
 
78
64
  @property
79
- def namespace(self):
80
- return self.__namespace
81
-
82
- @property
83
- def namespace_path(self):
84
- return os.path.join(self.data_dir_path, self.namespace)
65
+ def scaffold_namespace_path(self):
66
+ return os.path.join(self.data_dir_path, self.scaffold_namespace)
85
67
 
86
68
  @property
87
69
  def dir_path(self):
88
70
  return self.__dir_path
89
71
 
90
72
  @property
91
- def scaffold_dir_path(self):
92
- return self.__scaffold_dir_path
73
+ def data_dir_path(self):
74
+ return self.__data_dir_path
93
75
 
94
76
  @property
95
77
  def scaffold_namespace_path(self):
96
- return os.path.join(self.scaffold_dir_path, self.namespace)
78
+ return os.path.join(self.data_dir_path, self.scaffold_namespace)
97
79
 
98
80
  @property
99
81
  def services(self):
@@ -101,7 +83,7 @@ class App():
101
83
 
102
84
  @property
103
85
  def service_paths(self):
104
- services_dir = os.path.join(self.scaffold_dir_path, self.namespace)
86
+ services_dir = os.path.join(self.data_dir_path, self.scaffold_namespace)
105
87
 
106
88
  services = []
107
89
  for filename in os.listdir(services_dir):
@@ -13,9 +13,6 @@ class AppCommand(Command):
13
13
 
14
14
  self.__config = AppConfig(self.scaffold_namespace_path)
15
15
 
16
- if not self.__config.network:
17
- self.__config.network = app.network
18
-
19
16
  @property
20
17
  def app_dir_path(self):
21
18
  return self.app.dir_path
@@ -33,16 +30,16 @@ class AppCommand(Command):
33
30
  return self.__config.path
34
31
 
35
32
  @property
36
- def app_namespace_path(self):
37
- return self.app.namespace_path
33
+ def scaffold_namespace_path(self):
34
+ return self.app.scaffold_namespace_path
38
35
 
39
36
  @property
40
37
  def app_templates_root_dir(self):
41
38
  return os.path.join(self.templates_root_dir, 'app')
42
39
 
43
40
  @property
44
- def scaffold_dir_path(self):
45
- return self.app.scaffold_dir_path
41
+ def data_dir_path(self):
42
+ return self.app.data_dir_path
46
43
 
47
44
  @property
48
45
  def scaffold_namespace_path(self):
@@ -1,15 +1,24 @@
1
1
  from .config import Config
2
- from .constants import APP_NETWORK_ENV
2
+ from .constants import APP_NAME_ENV, APP_NETWORK_ENV
3
3
 
4
4
  class AppConfig(Config):
5
5
 
6
6
  def __init__(self, dir: str):
7
7
  super().__init__(dir)
8
8
 
9
+ self.__name = None
9
10
  self.__network = None
10
11
 
11
12
  self.load()
12
13
 
14
+ @property
15
+ def name(self):
16
+ return self.__name
17
+
18
+ @name.setter
19
+ def name(self, v):
20
+ self.__name = v
21
+
13
22
  @property
14
23
  def network(self):
15
24
  return self.__network
@@ -21,11 +30,15 @@ class AppConfig(Config):
21
30
  def load(self, config = None):
22
31
  config = config or self.read()
23
32
 
24
- self.__network = config.get(APP_NETWORK_ENV)
33
+ self.name = config.get(APP_NAME_ENV)
34
+ self.network = config.get(APP_NETWORK_ENV)
25
35
 
26
36
  def write(self):
27
37
  config = {}
28
38
 
39
+ if self.name:
40
+ config[APP_NAME_ENV] = self.name
41
+
29
42
  if self.network:
30
43
  config[APP_NETWORK_ENV] = self.network
31
44
 
@@ -1,17 +1,33 @@
1
1
  import os
2
2
  import pdb
3
3
 
4
+ from typing import TypedDict
5
+
4
6
  from .app import App
5
7
  from .app_command import AppCommand
6
8
 
9
+ class AppCreateOptions(TypedDict):
10
+ name: str
11
+ network: str
12
+
7
13
  class AppCreateCommand(AppCommand):
8
14
 
9
- def __init__(self, app: App, **kwargs):
15
+ def __init__(self, app: App, **kwargs: AppCreateOptions):
10
16
  super().__init__(app)
11
17
 
18
+ if kwargs.get('app_name'):
19
+ self.app_config.name = kwargs['app_name']
20
+
21
+ if kwargs.get('network'):
22
+ self.app_config.network = kwargs['network']
23
+
12
24
  @property
13
25
  def app_name(self):
14
- return self.app.name
26
+ return self.app_config.name
27
+
28
+ @property
29
+ def app_network(self):
30
+ return self.app_config.network
15
31
 
16
32
  def build(self):
17
33
  dest = self.scaffold_namespace_path
@@ -4,7 +4,7 @@ class Command():
4
4
 
5
5
  def __init__(self, app: App):
6
6
  self.__app = app
7
- self.__namespace = app.namespace
7
+ self.__namespace = app.scaffold_namespace
8
8
 
9
9
  @property
10
10
  def app(self):
@@ -1,9 +1,11 @@
1
- from typing import Literal
1
+ import os
2
2
 
3
- from stoobly_agent.config.data_dir import DATA_DIR_NAME
3
+ from typing import Literal
4
4
 
5
+ from stoobly_agent.config.data_dir import CERTS_DIR_NAME, DATA_DIR_NAME
5
6
 
6
7
  APP_NETWORK_ENV = 'APP_NETWORK'
8
+ APP_NAME_ENV = 'APP_NAME'
7
9
  BIN_FOLDER_NAME = 'bin'
8
10
  CA_CERTS_DIR_ENV = 'CA_CERTS_DIR'
9
11
  CERTS_DIR_ENV = 'CERTS_DIR'
@@ -22,6 +24,7 @@ SERVICE_HOSTNAME = '${SERVICE_HOSTNAME}'
22
24
  SERVICE_HOSTNAME_ENV = 'SERVICE_HOSTNAME'
23
25
  SERVICE_DNS = '${SERVICE_DNS}'
24
26
  SERVICE_DNS_ENV = 'SERVICE_DNS'
27
+ SERVICE_NAME = '${SERVICE_NAME}'
25
28
  SERVICE_NAME_ENV = 'SERVICE_NAME'
26
29
  SERVICE_PROXY_MODE = '${SERVICE_PROXY_MODE}'
27
30
  SERVICE_PROXY_MODE_ENV = 'SERVICE_PROXY_MODE'
@@ -31,7 +34,8 @@ SERVICE_PORT = '${SERVICE_PORT}'
31
34
  SERVICE_PORT_ENV = 'SERVICE_PORT'
32
35
  SERVICE_PRIORITY_ENV = 'SERVICE_PRIORITY'
33
36
  STOOBLY_HOME_DIR = '/home/stoobly'
34
- STOOBLY_DATA_DIR = f"{STOOBLY_HOME_DIR}/{DATA_DIR_NAME}"
37
+ STOOBLY_DATA_DIR = os.path.join(STOOBLY_HOME_DIR, DATA_DIR_NAME)
38
+ STOOBLY_CERTS_DIR = os.path.join(STOOBLY_DATA_DIR, CERTS_DIR_NAME)
35
39
  USER_ID_ENV = 'USER_ID'
36
40
  VIRTUAL_HOST_ENV = 'VIRTUAL_HOST'
37
41
  VIRTUAL_PORT_ENV = 'VIRTUAL_PORT'
@@ -44,7 +48,9 @@ WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_C
44
48
  WORKFLOW_CONTAINER_INIT_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_INIT
45
49
  WORKFLOW_CONTAINER_PROXY_TEMPLATE = '{service_name}.' + WORKFLOW_CONTAINER_PROXY
46
50
  WORKFLOW_MOCK_TYPE = 'mock'
51
+ WORKFLOW_NAME = '${WORKFLOW_NAME}'
47
52
  WORKFLOW_NAME_ENV = 'WORKFLOW_NAME'
53
+ WORKFLOW_NAMESPACE_ENV = 'WORKFLOW_NAMESPACE'
48
54
  WORKFLOW_RECORD_TYPE = 'record'
49
55
  WORKFLOW_TEST_TYPE = 'test'
50
56
 
@@ -1,7 +1,7 @@
1
1
  import os
2
2
 
3
3
  from .builder import Builder
4
- from .constants import DOCKER_COMPOSE_BASE, DOCKERFILE_CONTEXT, DOCKERFILE_PROXY
4
+ from .constants import DOCKER_COMPOSE_BASE, DOCKERFILE_CONTEXT
5
5
  from ..app_config import AppConfig
6
6
 
7
7
  class AppBuilder(Builder):
@@ -18,9 +18,5 @@ class AppBuilder(Builder):
18
18
  return os.path.join(self.dir_path, DOCKERFILE_CONTEXT)
19
19
 
20
20
  @property
21
- def proxy_base(self):
22
- return 'proxy_base'
23
-
24
- @property
25
- def proxy_docker_file_path(self):
26
- return os.path.join(self.dir_path, DOCKERFILE_PROXY)
21
+ def stoobly_base(self):
22
+ return 'stoobly_base'
@@ -86,7 +86,7 @@ class Builder():
86
86
 
87
87
  def with_network(self, network):
88
88
  self.__networks[network] = {
89
- 'name': network
89
+ 'name': f"{APP_NETWORK}.{network}"
90
90
  }
91
91
  return self
92
92
 
@@ -3,7 +3,6 @@ DOCKER_COMPOSE_BASE = '.docker-compose.base.yml'
3
3
  DOCKER_COMPOSE_BASE_TEMPLATE = '.docker-compose.base.template.yml'
4
4
  DOCKER_COMPOSE_CUSTOM = 'docker-compose.yml'
5
5
  DOCKERFILE_CONTEXT = '.Dockerfile.context'
6
- DOCKERFILE_PROXY = '.Dockerfile.proxy'
7
6
  DOCKERFILE_SERVICE = 'Dockerfile.source'
8
7
  GATEWAY_NETWORK = 'gateway'
9
8
 
@@ -2,7 +2,7 @@ import os
2
2
  import pdb
3
3
 
4
4
  from ...app_config import AppConfig
5
- from ...constants import SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, STOOBLY_HOME_DIR
5
+ from ...constants import SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME, STOOBLY_HOME_DIR, WORKFLOW_NAME
6
6
  from ...service_config import ServiceConfig
7
7
  from ..app_builder import AppBuilder
8
8
  from ..builder import Builder
@@ -44,6 +44,13 @@ class ServiceBuilder(Builder):
44
44
  def configure_base_service(self):
45
45
  return self.services.get(self.configure_base)
46
46
 
47
+ @property
48
+ def extends_service(self):
49
+ if self.config.detached:
50
+ return self.app_builder.stoobly_base
51
+ else:
52
+ return self.app_builder.context_base
53
+
47
54
  @property
48
55
  def proxy_base(self):
49
56
  return f"{self.service_name}.proxy_base"
@@ -52,10 +59,6 @@ class ServiceBuilder(Builder):
52
59
  def proxy_base_service(self):
53
60
  return self.services.get(self.proxy_base)
54
61
 
55
- @property
56
- def service_mount(self):
57
- return f".:{STOOBLY_HOME_DIR}"
58
-
59
62
  @property
60
63
  def service_name(self):
61
64
  return self.__service_name
@@ -80,9 +83,8 @@ class ServiceBuilder(Builder):
80
83
  },
81
84
  'extends': {
82
85
  'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
83
- 'service': self.app_builder.proxy_base
86
+ 'service': self.extends_service
84
87
  },
85
- 'volumes': [self.service_mount]
86
88
  })
87
89
 
88
90
  args[SERVICE_HOSTNAME_ENV] = f"{SERVICE_HOSTNAME}"
@@ -90,13 +92,12 @@ class ServiceBuilder(Builder):
90
92
  def build_init_base(self):
91
93
  environment = {}
92
94
  self.with_service(self.init_base, {
93
- 'command': ['bin/.init', 'dist'],
95
+ 'command': ['bin/.init'],
94
96
  'environment': environment,
95
97
  'extends': {
96
98
  'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
97
- 'service': self.app_builder.context_base
99
+ 'service': self.extends_service
98
100
  },
99
- 'volumes': [self.service_mount]
100
101
  })
101
102
 
102
103
  def build_configure_base(self):
@@ -106,7 +107,7 @@ class ServiceBuilder(Builder):
106
107
  'environment': environment,
107
108
  'extends': {
108
109
  'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
109
- 'service': self.app_builder.context_base
110
+ 'service': self.extends_service
110
111
  }
111
112
  })
112
113
 
@@ -3,12 +3,13 @@ import pdb
3
3
 
4
4
  from typing import List
5
5
 
6
+ from stoobly_agent.config.data_dir import DATA_DIR_NAME
7
+
6
8
  from ...constants import (
7
- COMPOSE_TEMPLATE, STOOBLY_HOME_DIR, SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME_ENV,
9
+ COMPOSE_TEMPLATE, DOCKER_NAMESPACE, STOOBLY_HOME_DIR, SERVICE_HOSTNAME, SERVICE_HOSTNAME_ENV, SERVICE_NAME_ENV,
8
10
  SERVICE_PORT, SERVICE_PORT_ENV, SERVICE_SCHEME, SERVICE_SCHEME_ENV,
9
11
  WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE, WORKFLOW_CONTAINER_INIT_TEMPLATE, WORKFLOW_CONTAINER_PROXY_TEMPLATE, WORKFLOW_NAME_ENV
10
12
  )
11
- from ...templates.constants import SERVICE_HOSTNAME_BUILD_ARG
12
13
  from ..builder import Builder
13
14
  from ..service.builder import ServiceBuilder
14
15
 
@@ -21,13 +22,15 @@ class WorkflowBuilder(Builder):
21
22
 
22
23
  self.__context = '../'
23
24
  self.__profiles = [self.__workflow_name]
24
- self.__workdir = os.path.join(STOOBLY_HOME_DIR, self.workflow_name)
25
25
 
26
26
  if not service_builder:
27
27
  service_path = os.path.dirname(workflow_path)
28
28
  service_builder = ServiceBuilder(service_path)
29
29
 
30
30
  self.__service_builder = service_builder
31
+ self.__working_dir = os.path.join(
32
+ STOOBLY_HOME_DIR, DATA_DIR_NAME, DOCKER_NAMESPACE, self.service_builder.service_name, self.workflow_name
33
+ )
31
34
 
32
35
  if self.config.hostname:
33
36
  self.with_public_network()
@@ -58,13 +61,6 @@ class WorkflowBuilder(Builder):
58
61
  def context(self):
59
62
  return self.__context
60
63
 
61
- @property
62
- def context_build(self):
63
- return {
64
- 'context': self.context,
65
- 'dockerfile': self.context_docker_file_path,
66
- }
67
-
68
64
  @property
69
65
  def context_docker_file_path(self):
70
66
  return os.path.relpath(self.service_builder.app_builder.context_docker_file_path, self.service_path)
@@ -81,21 +77,6 @@ class WorkflowBuilder(Builder):
81
77
  def proxy(self):
82
78
  return WORKFLOW_CONTAINER_PROXY_TEMPLATE.format(service_name=self.namespace)
83
79
 
84
- @property
85
- def proxy_build(self):
86
- args = {}
87
- args[SERVICE_HOSTNAME_BUILD_ARG] = SERVICE_HOSTNAME
88
-
89
- return {
90
- 'args': args,
91
- 'context': self.context,
92
- 'dockerfile': self.proxy_docker_file_path,
93
- }
94
-
95
- @property
96
- def proxy_docker_file_path(self):
97
- return os.path.relpath(self.service_builder.app_builder.proxy_docker_file_path, self.service_path)
98
-
99
80
  @property
100
81
  def service_builder(self):
101
82
  return self.__service_builder
@@ -128,19 +109,21 @@ class WorkflowBuilder(Builder):
128
109
  volumes = []
129
110
 
130
111
  service = {
131
- 'build': self.context_build,
132
112
  'environment': environment,
133
113
  'extends': self.service_builder.build_extends_init_base(self.dir_path),
134
114
  'profiles': self.profiles,
135
115
  'volumes': volumes,
136
- 'working_dir': self.__workdir,
116
+ 'working_dir': self.__working_dir,
137
117
  }
138
118
 
139
119
  if self.config.hostname:
140
120
  self.__with_url_environment(environment)
141
121
 
142
122
  if self.config.detached:
123
+ # Mount named volume
143
124
  volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
125
+ # Mount docker folder
126
+ volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
144
127
 
145
128
  self.with_service(self.init, service)
146
129
 
@@ -154,13 +137,12 @@ class WorkflowBuilder(Builder):
154
137
  volumes = []
155
138
 
156
139
  service = {
157
- 'build': self.context_build,
158
140
  'depends_on': depends_on,
159
141
  'environment': environment,
160
142
  'extends': self.service_builder.build_extends_configure_base(self.dir_path),
161
143
  'profiles': self.profiles,
162
144
  'volumes': volumes,
163
- 'working_dir': self.__workdir,
145
+ 'working_dir': self.__working_dir,
164
146
  }
165
147
 
166
148
  if self.config.hostname:
@@ -173,6 +155,7 @@ class WorkflowBuilder(Builder):
173
155
 
174
156
  if self.config.detached:
175
157
  volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
158
+ volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
176
159
 
177
160
  self.with_service(self.configure, service)
178
161
 
@@ -187,14 +170,13 @@ class WorkflowBuilder(Builder):
187
170
  volumes = []
188
171
 
189
172
  service = {
190
- 'build': self.proxy_build,
191
173
  'depends_on': depends_on,
192
174
  'environment': environment,
193
175
  'extends': self.service_builder.build_extends_proxy_base(self.dir_path),
194
176
  'networks': networks,
195
177
  'profiles': self.profiles,
196
178
  'volumes': volumes,
197
- 'working_dir': self.__workdir,
179
+ 'working_dir': self.__working_dir,
198
180
  }
199
181
 
200
182
  if self.configure in self.services:
@@ -217,6 +199,7 @@ class WorkflowBuilder(Builder):
217
199
 
218
200
  if self.config.detached:
219
201
  volumes.append(f"{self.service_builder.service_name}:{STOOBLY_HOME_DIR}/.stoobly")
202
+ volumes.append(f"../..:{STOOBLY_HOME_DIR}/.stoobly/docker")
220
203
 
221
204
  self.with_service(self.proxy, service)
222
205
 
@@ -1,6 +1,7 @@
1
+ import os
1
2
  import pdb
2
3
 
3
- from ...constants import SERVICE_HOSTNAME, SERVICE_PORT
4
+ from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
4
5
  from .builder import WorkflowBuilder
5
6
 
6
7
  class MockDecorator():
@@ -20,7 +21,6 @@ class MockDecorator():
20
21
  config = self.service_builder.config
21
22
 
22
23
  command = [
23
- '--certs', f"/etc/ssl/certs/{SERVICE_HOSTNAME}-joined.pem",
24
24
  '--headless',
25
25
  '--intercept',
26
26
  '--lifecycle-hooks-path', 'lifecycle_hooks.py',
@@ -30,6 +30,10 @@ class MockDecorator():
30
30
  '--ssl-insecure'
31
31
  ]
32
32
 
33
+ if config.scheme == 'https':
34
+ command.append('--certs')
35
+ command.append(os.path.join(STOOBLY_CERTS_DIR, f"{SERVICE_HOSTNAME}-joined.pem"))
36
+
33
37
  services = self.__workflow_builder.services
34
38
  proxy_name = self.__workflow_builder.proxy
35
39
  proxy_service = services.get(proxy_name) or {}
@@ -1,8 +1,9 @@
1
+ import os
1
2
  import pdb
2
3
 
3
4
  from urllib.parse import urlparse
4
5
 
5
- from ...constants import SERVICE_HOSTNAME, SERVICE_PORT
6
+ from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
6
7
  from .builder import WorkflowBuilder
7
8
 
8
9
  class ReverseProxyDecorator():
@@ -22,7 +23,6 @@ class ReverseProxyDecorator():
22
23
  config = self.service_builder.config
23
24
 
24
25
  command = [
25
- '--certs', f"/etc/ssl/certs/{SERVICE_HOSTNAME}-joined.pem",
26
26
  '--headless',
27
27
  '--lifecycle-hooks-path', 'lifecycle_hooks.py',
28
28
  '--proxy-mode', config.proxy_mode,
@@ -30,6 +30,10 @@ class ReverseProxyDecorator():
30
30
  '--ssl-insecure'
31
31
  ]
32
32
 
33
+ if config.scheme == 'https':
34
+ command.append('--certs')
35
+ command.append(os.path.join(STOOBLY_CERTS_DIR, f"{SERVICE_HOSTNAME}-joined.pem"))
36
+
33
37
  services = self.workflow_builder.services
34
38
  proxy_name = self.workflow_builder.proxy
35
39
  proxy_service = services.get(proxy_name) or {}
@@ -14,7 +14,7 @@ class Service():
14
14
 
15
15
  @property
16
16
  def dir_path(self):
17
- return os.path.join(self.app.namespace_path, self.service_name)
17
+ return os.path.join(self.app.scaffold_namespace_path, self.service_name)
18
18
 
19
19
  @property
20
20
  def service_name(self):
@@ -33,7 +33,7 @@ class ServiceCommand(AppCommand):
33
33
  @property
34
34
  def service_path(self):
35
35
  return os.path.join(
36
- self.scaffold_dir_path,
36
+ self.data_dir_path,
37
37
  self.service_relative_path
38
38
  )
39
39
 
@@ -1,21 +1,17 @@
1
1
  import os
2
2
  import pdb
3
3
  import socket
4
- import ssl
5
4
  import time
5
+
6
6
  from collections import Counter
7
7
  from pathlib import Path
8
8
 
9
- import requests
10
9
  import yaml
11
10
  from docker.models.containers import Container
12
- from requests.adapters import HTTPAdapter
13
- from urllib3 import Retry
14
11
 
15
12
  from stoobly_agent.app.cli.scaffold.constants import (
16
13
  FIXTURES_FOLDER_NAME,
17
14
  STOOBLY_DATA_DIR,
18
- STOOBLY_HOME_DIR,
19
15
  VIRTUAL_HOST_ENV,
20
16
  VIRTUAL_PORT_ENV,
21
17
  VIRTUAL_PROTO_ENV,
@@ -39,7 +35,9 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
39
35
 
40
36
  self.workflow_name = kwargs['workflow_name']
41
37
  self.hostname = self.service_config.hostname
42
- self.service_docker_compose = ServiceDockerCompose(app_dir_path=app.dir_path, target_workflow_name=self.workflow_name, service_name=self.service_name, hostname=self.hostname)
38
+ self.service_docker_compose = ServiceDockerCompose(
39
+ app_dir_path=app.dir_path, target_workflow_name=self.workflow_name, service_name=self.service_name, hostname=self.hostname
40
+ )
43
41
 
44
42
  @property
45
43
  def fixtures_dir_path(self):
@@ -48,7 +46,7 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
48
46
  @property
49
47
  def workflow_path(self):
50
48
  return os.path.join(
51
- self.scaffold_dir_path,
49
+ self.data_dir_path,
52
50
  self.workflow_relative_path
53
51
  )
54
52
  @property
@@ -151,7 +149,7 @@ class ServiceWorkflowValidateCommand(ServiceCommand, ValidateCommand):
151
149
  return
152
150
 
153
151
  # Check contents of fixtures folder to confirm it's shared
154
- fixtures_folder_path = f"{STOOBLY_HOME_DIR}/{self.workflow_name}/{FIXTURES_FOLDER_NAME}"
152
+ fixtures_folder_path = f"{FIXTURES_FOLDER_NAME}"
155
153
  exec_result = container.exec_run(f"ls -A {fixtures_folder_path}")
156
154
  output = exec_result.output
157
155
 
@@ -1,8 +1,6 @@
1
- FROM stoobly/agent:1.2
1
+ FROM stoobly/agent:1.3
2
2
 
3
3
  ARG USER_ID
4
4
 
5
5
  # Change user id of stoobly user to that of host's user id
6
- RUN if [ -n "$USER_ID" ]; then usermod -u $USER_ID stoobly; fi
7
-
8
- COPY --chown=stoobly:stoobly . .
6
+ RUN if [ -n "$USER_ID" ]; then usermod -u $USER_ID stoobly; fi