stoobly-agent 0.34.13__py3-none-any.whl → 1.0.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 (132) hide show
  1. stoobly_agent/__init__.py +1 -1
  2. stoobly_agent/app/cli/__init__.py +1 -0
  3. stoobly_agent/app/cli/helpers/openapi_endpoint_adapter.py +9 -7
  4. stoobly_agent/app/cli/helpers/shell.py +28 -0
  5. stoobly_agent/app/cli/main_group.py +1 -1
  6. stoobly_agent/app/cli/scaffold/__init__.py +0 -0
  7. stoobly_agent/app/cli/scaffold/app.py +106 -0
  8. stoobly_agent/app/cli/scaffold/app_command.py +82 -0
  9. stoobly_agent/app/cli/scaffold/app_config.py +32 -0
  10. stoobly_agent/app/cli/scaffold/app_create_command.py +24 -0
  11. stoobly_agent/app/cli/scaffold/command.py +15 -0
  12. stoobly_agent/app/cli/scaffold/config.py +35 -0
  13. stoobly_agent/app/cli/scaffold/constants.py +35 -0
  14. stoobly_agent/app/cli/scaffold/docker/__init__.py +0 -0
  15. stoobly_agent/app/cli/scaffold/docker/app_builder.py +26 -0
  16. stoobly_agent/app/cli/scaffold/docker/builder.py +117 -0
  17. stoobly_agent/app/cli/scaffold/docker/constants.py +7 -0
  18. stoobly_agent/app/cli/scaffold/docker/service/__init__.py +0 -0
  19. stoobly_agent/app/cli/scaffold/docker/service/build_decorator.py +37 -0
  20. stoobly_agent/app/cli/scaffold/docker/service/builder.py +117 -0
  21. stoobly_agent/app/cli/scaffold/docker/service/set_gateway_ports.py +47 -0
  22. stoobly_agent/app/cli/scaffold/docker/service/types.py +4 -0
  23. stoobly_agent/app/cli/scaffold/docker/workflow/__init__.py +0 -0
  24. stoobly_agent/app/cli/scaffold/docker/workflow/build_decorator.py +28 -0
  25. stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +259 -0
  26. stoobly_agent/app/cli/scaffold/docker/workflow/decorators_factory.py +17 -0
  27. stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +40 -0
  28. stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +51 -0
  29. stoobly_agent/app/cli/scaffold/env.py +49 -0
  30. stoobly_agent/app/cli/scaffold/service.py +25 -0
  31. stoobly_agent/app/cli/scaffold/service_command.py +50 -0
  32. stoobly_agent/app/cli/scaffold/service_config.py +207 -0
  33. stoobly_agent/app/cli/scaffold/service_create_command.py +77 -0
  34. stoobly_agent/app/cli/scaffold/service_workflow.py +18 -0
  35. stoobly_agent/app/cli/scaffold/templates/__init__.py +0 -0
  36. stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +8 -0
  37. stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.proxy +35 -0
  38. stoobly_agent/app/cli/scaffold/templates/app/.Makefile +118 -0
  39. stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.base.yml +15 -0
  40. stoobly_agent/app/cli/scaffold/templates/app/Makefile +3 -0
  41. stoobly_agent/app/cli/scaffold/templates/app/build/.config.yml +1 -0
  42. stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +11 -0
  43. stoobly_agent/app/cli/scaffold/templates/app/build/mock/.docker-compose.mock.yml +22 -0
  44. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.configure +5 -0
  45. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.init +5 -0
  46. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/configure +1 -0
  47. stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/init +1 -0
  48. stoobly_agent/app/cli/scaffold/templates/app/build/record/.docker-compose.record.yml +22 -0
  49. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.configure +5 -0
  50. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.init +5 -0
  51. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/configure +1 -0
  52. stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/init +1 -0
  53. stoobly_agent/app/cli/scaffold/templates/app/build/test/.docker-compose.test.yml +22 -0
  54. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.configure +5 -0
  55. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.init +5 -0
  56. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/configure +1 -0
  57. stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/init +1 -0
  58. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.config.yml +1 -0
  59. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +17 -0
  60. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/.docker-compose.mock.yml +31 -0
  61. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/bin/.configure +10 -0
  62. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/bin/.init +5 -0
  63. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/bin/configure +1 -0
  64. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/bin/init +4 -0
  65. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/docker-compose.yml +1 -0
  66. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/.docker-compose.record.yml +31 -0
  67. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/bin/.configure +10 -0
  68. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/bin/.init +5 -0
  69. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/bin/configure +1 -0
  70. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/bin/init +4 -0
  71. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/docker-compose.yml +1 -0
  72. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/.docker-compose.test.yml +31 -0
  73. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/bin/.configure +10 -0
  74. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/bin/.init +3 -0
  75. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/bin/configure +1 -0
  76. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/bin/init +4 -0
  77. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/docker-compose.yml +1 -0
  78. stoobly_agent/app/cli/scaffold/templates/app/gateway/.config.yml +1 -0
  79. stoobly_agent/app/cli/scaffold/templates/app/gateway/.docker-compose.base.yml +11 -0
  80. stoobly_agent/app/cli/scaffold/templates/app/gateway/mock/.docker-compose.mock.yml +13 -0
  81. stoobly_agent/app/cli/scaffold/templates/app/gateway/record/.docker-compose.record.yml +13 -0
  82. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/.config.yml +1 -0
  83. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/.docker-compose.base.yml +5 -0
  84. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml +12 -0
  85. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.create +11 -0
  86. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.delete +12 -0
  87. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.disable +3 -0
  88. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.enable +10 -0
  89. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.reset +12 -0
  90. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.run +11 -0
  91. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.snapshot +12 -0
  92. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.stop +11 -0
  93. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/.docker-compose.mock.yml +12 -0
  94. stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/.docker-compose.record.yml +13 -0
  95. stoobly_agent/app/cli/scaffold/templates/constants.py +63 -0
  96. stoobly_agent/app/cli/scaffold/templates/factory.py +46 -0
  97. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.configure +3 -0
  98. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.init +3 -0
  99. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/configure +18 -0
  100. stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/init +4 -0
  101. stoobly_agent/app/cli/scaffold/templates/workflow/mock/fixtures/.keep +0 -0
  102. stoobly_agent/app/cli/scaffold/templates/workflow/mock/fixtures.yml +5 -0
  103. stoobly_agent/app/cli/scaffold/templates/workflow/mock/lifecycle_hooks.py +12 -0
  104. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.configure +3 -0
  105. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.init +3 -0
  106. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/configure +29 -0
  107. stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/init +4 -0
  108. stoobly_agent/app/cli/scaffold/templates/workflow/record/lifecycle_hooks.py +12 -0
  109. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.configure +3 -0
  110. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.init +3 -0
  111. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/configure +18 -0
  112. stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/init +4 -0
  113. stoobly_agent/app/cli/scaffold/templates/workflow/test/fixtures/.keep +0 -0
  114. stoobly_agent/app/cli/scaffold/templates/workflow/test/fixtures.yml +5 -0
  115. stoobly_agent/app/cli/scaffold/templates/workflow/test/lifecycle_hooks.py +12 -0
  116. stoobly_agent/app/cli/scaffold/workflow.py +49 -0
  117. stoobly_agent/app/cli/scaffold/workflow_command.py +137 -0
  118. stoobly_agent/app/cli/scaffold/workflow_copy_command.py +45 -0
  119. stoobly_agent/app/cli/scaffold/workflow_create_command.py +94 -0
  120. stoobly_agent/app/cli/scaffold/workflow_log_command.py +21 -0
  121. stoobly_agent/app/cli/scaffold/workflow_run_command.py +134 -0
  122. stoobly_agent/app/cli/scaffold_cli.py +392 -0
  123. stoobly_agent/cli.py +3 -2
  124. stoobly_agent/config/data_dir.py +40 -14
  125. stoobly_agent/lib/logger.py +3 -2
  126. stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
  127. stoobly_agent/test/config/data_dir_test.py +4 -4
  128. {stoobly_agent-0.34.13.dist-info → stoobly_agent-1.0.0.dist-info}/METADATA +8 -7
  129. {stoobly_agent-0.34.13.dist-info → stoobly_agent-1.0.0.dist-info}/RECORD +132 -14
  130. {stoobly_agent-0.34.13.dist-info → stoobly_agent-1.0.0.dist-info}/WHEEL +1 -1
  131. {stoobly_agent-0.34.13.dist-info → stoobly_agent-1.0.0.dist-info}/LICENSE +0 -0
  132. {stoobly_agent-0.34.13.dist-info → stoobly_agent-1.0.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,207 @@
1
+ # Wraps the .config.yml file in the service folder
2
+
3
+ import dns.resolver
4
+ import pdb
5
+ import subprocess
6
+ import re
7
+
8
+ from .config import Config
9
+ from .constants import (
10
+ SERVICE_DETACHED_ENV,
11
+ SERVICE_DOCKER_COMPOSE_PATH_ENV,
12
+ SERVICE_HOSTNAME_ENV,
13
+ SERVICE_DNS_ENV,
14
+ SERVICE_PRIORITY_ENV,
15
+ SERVICE_PORT_ENV,
16
+ SERVICE_PROXY_MODE_ENV,
17
+ SERVICE_SCHEME_ENV
18
+ )
19
+
20
+ class ServiceConfig(Config):
21
+
22
+ def __init__(self, dir: str, **kwargs):
23
+ super().__init__(dir)
24
+
25
+ self.__detached = None
26
+ self.__docker_compose_path = None
27
+ self.__hostname = None
28
+ self.__dns = None
29
+ self.__port = None
30
+ self.__priority = None
31
+ self.__proxy_mode = None
32
+ self.__scheme = None
33
+
34
+ self.load()
35
+
36
+ if 'detached' in kwargs:
37
+ self.__detached = bool(kwargs.get('detached'))
38
+
39
+ if 'hostname' in kwargs:
40
+ self.__hostname = kwargs.get('hostname')
41
+
42
+ if 'port' in kwargs:
43
+ self.__port = kwargs.get('port')
44
+
45
+ if 'priority' in kwargs:
46
+ self.__priority = kwargs.get('priority')
47
+
48
+ if 'proxy_mode' in kwargs:
49
+ self.__proxy_mode = kwargs.get('proxy_mode')
50
+
51
+ if 'scheme' in kwargs:
52
+ self.__scheme = kwargs.get('scheme')
53
+
54
+ @property
55
+ def detached(self):
56
+ return self.__detached
57
+
58
+ @detached.setter
59
+ def detached(self, v):
60
+ self.__detached = v
61
+
62
+ @property
63
+ def docker_compose_path(self):
64
+ return self.__docker_compose_path
65
+
66
+ @docker_compose_path.setter
67
+ def docker_compose_path(self, v):
68
+ self.__docker_compose_path = v
69
+
70
+ @property
71
+ def hostname(self):
72
+ return self.__hostname
73
+
74
+ @hostname.setter
75
+ def hostname(self, v):
76
+ self.__hostname = v
77
+
78
+ @property
79
+ def dns(self):
80
+ # If hostname is set then the service is external and we will need to configure the container's DNS.
81
+ # If we don't configure the container's DNS, then Docker's embedded DNS will potentially
82
+ # use configuration from the host's /etc/hosts file. The user may have configured their
83
+ # /etc/hosts file to resolve requests to localhost
84
+ #
85
+ # See:
86
+ # https://forums.docker.com/t/docker-127-0-0-11-resolver-should-use-host-etc-hosts-file/55157
87
+ # https://docs.docker.com/network/#dns-services
88
+ #
89
+ # TODO: ideally we want to know if the service is built locally, if so, then no need to set DNS
90
+ # since Docker's embedded DNS will resolve to it
91
+ if self.hostname and not self.__dns:
92
+ nameservers = self.__find_dns()
93
+ self.__dns = nameservers[0] if nameservers else None
94
+ return self.__dns
95
+
96
+ @dns.setter
97
+ def dns(self, v):
98
+ self.__dns = v
99
+
100
+ @property
101
+ def port(self):
102
+ return self.__port
103
+
104
+ @port.setter
105
+ def port(self, v):
106
+ self.__port = v
107
+
108
+ @property
109
+ def priority(self):
110
+ _priority = self.__priority
111
+ _priority = float('inf') if _priority == None else float(_priority)
112
+
113
+ if _priority == float('inf'):
114
+ return _priority
115
+
116
+ return float(_priority)
117
+
118
+ @priority.setter
119
+ def priority(self, v):
120
+ self.__priority = v
121
+
122
+ @property
123
+ def proxy_mode(self):
124
+ if self.__proxy_mode:
125
+ return self.__proxy_mode
126
+
127
+ return f"reverse:{self.scheme}://{self.hostname}"
128
+
129
+ @proxy_mode.setter
130
+ def proxy_mode(self, v):
131
+ self.__proxy_mode = v
132
+
133
+ @property
134
+ def scheme(self):
135
+ return self.__scheme or 'https'
136
+
137
+ @scheme.setter
138
+ def scheme(self, v):
139
+ self.__scheme = v
140
+
141
+ def load(self, config = None):
142
+ config = config or self.read()
143
+
144
+ # Do not load dns from config, have it dynamically determined
145
+ #self.dns = config.get(SERVICE_DNS_ENV)
146
+
147
+ self.detached = config.get(SERVICE_DETACHED_ENV)
148
+ self.docker_compose_path = config.get(SERVICE_DOCKER_COMPOSE_PATH_ENV)
149
+ self.hostname = config.get(SERVICE_HOSTNAME_ENV)
150
+ self.port = config.get(SERVICE_PORT_ENV)
151
+ self.priority = config.get(SERVICE_PRIORITY_ENV)
152
+ self.proxy_mode = config.get(SERVICE_PROXY_MODE_ENV)
153
+ self.scheme = config.get(SERVICE_SCHEME_ENV)
154
+
155
+ def write(self):
156
+ config = {}
157
+
158
+ if self.docker_compose_path:
159
+ config[SERVICE_DOCKER_COMPOSE_PATH_ENV] = self.docker_compose_path
160
+
161
+ if self.hostname:
162
+ config[SERVICE_HOSTNAME_ENV] = self.hostname
163
+
164
+ if self.dns:
165
+ config[SERVICE_DNS_ENV] = self.dns
166
+
167
+ if self.port:
168
+ config[SERVICE_PORT_ENV] = self.port
169
+
170
+ if self.priority:
171
+ config[SERVICE_PRIORITY_ENV] = self.priority
172
+
173
+ if self.scheme:
174
+ config[SERVICE_SCHEME_ENV] = self.scheme
175
+
176
+ config[SERVICE_DETACHED_ENV] = bool(self.detached)
177
+
178
+ config[SERVICE_PROXY_MODE_ENV] = self.proxy_mode
179
+
180
+ super().write(config)
181
+
182
+ def __find_dns(self):
183
+ dns_resolver = dns.resolver.Resolver()
184
+ nameservers = dns_resolver.nameservers
185
+
186
+ # If systemd-resolved is not used
187
+ if nameservers != ['127.0.0.53']:
188
+ return nameservers
189
+
190
+ # Run the `resolvectl status` command and capture its output
191
+ result = subprocess.run(['resolvectl', 'status'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
192
+
193
+ # Check if the command ran successfully
194
+ if result.returncode != 0:
195
+ return []
196
+
197
+ # Extract the DNS servers using a regular expression
198
+ #dns_servers = re.findall(r'DNS Servers: ([\d.]+(?:, [\d.]+)*)', result.stdout)
199
+ pattern = re.compile('DNS Servers:(.*?)DNS Domain', re.DOTALL)
200
+ match = re.findall(pattern, result.stdout)
201
+
202
+ if not match:
203
+ return []
204
+
205
+ # Split the DNS servers string into a list
206
+ dns_servers = match[0].strip().split("\n")
207
+ return list(map(lambda dns_server: dns_server.strip(), dns_servers))
@@ -0,0 +1,77 @@
1
+ import os
2
+ import pdb
3
+ import shutil
4
+
5
+ from .app import App
6
+ from .constants import WORKFLOW_MOCK_TYPE, WORKFLOW_RECORD_TYPE, WORKFLOW_TEST_TYPE
7
+ from .docker.service.builder import ServiceBuilder
8
+ from .docker.workflow.decorators_factory import get_workflow_decorators
9
+ from .service_command import ServiceCommand
10
+ from .workflow_create_command import WorkflowCreateCommand
11
+
12
+ class ServiceCreateCommand(ServiceCommand):
13
+
14
+ def __init__(self, app: App, **kwargs):
15
+ super().__init__(app, **kwargs)
16
+
17
+ self.__env_vars = kwargs.get('env') or []
18
+ self.__workflows = kwargs.get('workflow') or []
19
+
20
+ @property
21
+ def env_vars(self):
22
+ return self.__env_vars
23
+
24
+ @property
25
+ def workflows(self):
26
+ return self.__workflows
27
+
28
+ def build(self):
29
+ service_builder = ServiceBuilder(self.service_config)
30
+ service_decorators = []
31
+
32
+ for service_decorator in service_decorators:
33
+ service_decorator(service_builder).decorate()
34
+
35
+ service_builder.write()
36
+
37
+ workflow_kwargs = {
38
+ 'app_dir_path': self.app_dir_path,
39
+ 'env': self.env_vars,
40
+ 'namespace': self.namespace,
41
+ 'service_name': self.service_name,
42
+ }
43
+
44
+ if WORKFLOW_MOCK_TYPE in self.workflows:
45
+ self.__build_with_mock_workflow(service_builder, **workflow_kwargs)
46
+
47
+ if WORKFLOW_RECORD_TYPE in self.workflows:
48
+ self.__build_with_record_workflow(service_builder, **workflow_kwargs)
49
+
50
+ if WORKFLOW_TEST_TYPE in self.workflows:
51
+ self.__build_with_test_workflow(service_builder, **workflow_kwargs)
52
+
53
+ self.service_config.write()
54
+
55
+ def reset(self):
56
+ dest = self.service_path
57
+
58
+ if os.path.exists(dest):
59
+ shutil.rmtree(dest)
60
+
61
+ def __build_with_mock_workflow(self, service_builder: ServiceBuilder, **kwargs):
62
+ mock_workflow = WorkflowCreateCommand(self.app, **{ **kwargs, **{ 'workflow_name': WORKFLOW_MOCK_TYPE }})
63
+
64
+ workflow_decorators = get_workflow_decorators(WORKFLOW_MOCK_TYPE, self.service_config)
65
+ mock_workflow.build(service_builder=service_builder, workflow_decorators=workflow_decorators)
66
+
67
+ def __build_with_record_workflow(self, service_builder: ServiceBuilder, **kwargs):
68
+ record_workflow = WorkflowCreateCommand(self.app, **{ **kwargs, **{ 'workflow_name': WORKFLOW_RECORD_TYPE }})
69
+
70
+ workflow_decorators = get_workflow_decorators(WORKFLOW_RECORD_TYPE, self.service_config)
71
+ record_workflow.build(service_builder=service_builder, workflow_decorators=workflow_decorators)
72
+
73
+ def __build_with_test_workflow(self, service_builder: ServiceBuilder, **kwargs):
74
+ mock_workflow = WorkflowCreateCommand(self.app, **{ **kwargs, **{ 'workflow_name': WORKFLOW_TEST_TYPE }})
75
+
76
+ workflow_decorators = get_workflow_decorators(WORKFLOW_TEST_TYPE, self.service_config)
77
+ mock_workflow.build(service_builder=service_builder, workflow_decorators=workflow_decorators)
@@ -0,0 +1,18 @@
1
+ import os
2
+
3
+ from .app import App
4
+ from .workflow import Workflow
5
+
6
+ class ServiceWorkflow(Workflow):
7
+
8
+ def __init__(self, service_name: str, workflow_name: str, app: App):
9
+ super().__init__(workflow_name, app)
10
+ self._service_name = service_name
11
+
12
+ @property
13
+ def path(self):
14
+ return os.path.join(self.app.scaffold_namespace_path, self.service_name, self.workflow_name)
15
+
16
+ @property
17
+ def service_name(self):
18
+ return self._service_name
File without changes
@@ -0,0 +1,8 @@
1
+ FROM stoobly/agent:0.34
2
+
3
+ ARG USER_ID
4
+
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 . .
@@ -0,0 +1,35 @@
1
+ FROM ubuntu:23.10 AS build
2
+
3
+ WORKDIR /tmp
4
+
5
+ RUN apt-get update && apt-get install -y curl
6
+ RUN curl -JLO "https://dl.filippo.io/mkcert/v1.4.4?for=linux/amd64" && \
7
+ chmod +x mkcert-v1.4.4-linux-amd64
8
+
9
+ FROM ubuntu:23.10 AS cert
10
+
11
+ ARG SERVICE_HOSTNAME
12
+
13
+ COPY --from=build /tmp/mkcert-v1.4.4-linux-amd64 /bin/mkcert
14
+
15
+ RUN useradd -m mkcert
16
+
17
+ USER mkcert
18
+ WORKDIR /home/mkcert
19
+
20
+ RUN mkcert $SERVICE_HOSTNAME && mkcert -pkcs12 $SERVICE_HOSTNAME && cat $SERVICE_HOSTNAME.pem >> $SERVICE_HOSTNAME-joined.pem && cat $SERVICE_HOSTNAME-key.pem >> $SERVICE_HOSTNAME-joined.pem
21
+
22
+ FROM stoobly/agent:0.34
23
+
24
+ ARG USER_ID
25
+ ARG SERVICE_HOSTNAME
26
+
27
+ # Allow running stoobly on port 443
28
+ RUN apt-get update && apt-get install -y curl libcap2-bin
29
+ RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/python3.8
30
+
31
+ # Change user id of stoobly user to that of host's user id
32
+ RUN if [ -n "$USER_ID" ]; then groupmod -g $USER_ID stoobly; usermod -u $USER_ID stoobly; fi
33
+
34
+ COPY --chown=stoobly:stoobly . .
35
+ COPY --chown=stoobly:stoobly --from=cert /home/mkcert/$SERVICE_HOSTNAME-joined.pem .
@@ -0,0 +1,118 @@
1
+ # Overridable Environment Variables
2
+ #
3
+ # STOOBLY_APP_DIR: path to the application source code directory
4
+ # STOOBLY_CONTEXT_DIR: path to the folder containing the .stoobly folder
5
+ # STOOBLY_CERTS_DIR: path to a folder to store certs
6
+ # STOOBLY_WORKFLOW_RUN_OPTIONS: extra options to pass to 'stoobly-agent scaffold workflow run' command
7
+
8
+ # Constants
9
+ DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
10
+ WORKFLOW_NAME := exec
11
+
12
+ CONTEXT_DIR_DEFAULT := $(realpath $(DIR)/../..)
13
+
14
+ # Configuration
15
+ app_dir=$$(realpath "$${STOOBLY_APP_DIR:-$(CONTEXT_DIR_DEFAULT)}")
16
+ certs_dir=$$(realpath "$${STOOBLY_CERTS_DIR:-$(app_data_dir)/certs}")
17
+ context_dir=$$(realpath "$${STOOBLY_CONTEXT_DIR:-$(CONTEXT_DIR_DEFAULT)}")
18
+ workflow_run_options=$${STOOBLY_WORKFLOW_RUN_OPTIONS:+$$STOOBLY_WORKFLOW_RUN_OPTIONS }
19
+
20
+ app_data_dir=$(app_dir)/.stoobly
21
+ data_dir=$(context_dir)/.stoobly
22
+
23
+ # Commands
24
+ docker_compose_command=docker compose
25
+ source_env=set -a; [ -f .env ] && source .env; set +a
26
+
27
+ docker_compose_file_path=$(app_data_dir)/docker/stoobly-ui/exec/.docker-compose.exec.yml
28
+ stoobly_exec_args=--profile $(WORKFLOW_NAME) -p $(WORKFLOW_NAME) up --build --remove-orphans
29
+ stoobly_exec_env=export CONTEXT_DIR=$(context_dir) && export USER_ID=$$UID
30
+ stoobly_exec=$(stoobly_exec_env) && $(source_env) && $(docker_compose_command) -f "$(docker_compose_file_path)" $(stoobly_exec_args)
31
+
32
+ # Because scaffold is stored in the APP_DIR, when running a scaffold command from within a container,
33
+ # it needs access to APP_DIR rather than CONTEXT_DIR
34
+ stoobly_exec_run_env=export USER_ID=$$UID
35
+ stoobly_exec_run=$(stoobly_exec_run_env) && $(source_env) && CONTEXT_DIR=$(app_dir) $(docker_compose_command) -f "$(docker_compose_file_path)" $(stoobly_exec_args)
36
+
37
+ run_script=$(app_data_dir)/tmp/run.sh
38
+ run_env=export APP_DIR="$(app_dir)" && export CERTS_DIR="$(certs_dir)" && export CONTEXT_DIR="$(context_dir)"
39
+ workflow_run=$(run_env) && $(source_env) && bash "$(run_script)"
40
+
41
+ cert:
42
+ if [ -z "$$(which mkcert)" ]; then \
43
+ echo "Error: missing mkcert command"; \
44
+ else \
45
+ mkdir -p "$(certs_dir)" && \
46
+ cd "$(certs_dir)" && \
47
+ mkcert --install && \
48
+ mkcert $(hostname) && \
49
+ cp $(hostname).pem $(hostname).crt && \
50
+ cp $(hostname)-key.pem $(hostname).key; \
51
+ fi
52
+ intercept/disable:
53
+ export EXEC_COMMAND=bin/.disable && \
54
+ $(stoobly_exec)
55
+ intercept/enable:
56
+ export EXEC_COMMAND=bin/.enable && \
57
+ export EXEC_ARGS=$(scenario_key) && \
58
+ $(stoobly_exec)
59
+ mock:
60
+ export EXEC_COMMAND=bin/.run && \
61
+ export EXEC_OPTIONS="$(workflow_run_options)$(options)" && \
62
+ export EXEC_ARGS="mock" && \
63
+ $(stoobly_exec_run) && \
64
+ $(workflow_run)
65
+ mock/stop:
66
+ export EXEC_COMMAND=bin/.stop && \
67
+ export EXEC_OPTIONS="$(options)" && \
68
+ export EXEC_ARGS="mock" && \
69
+ $(stoobly_exec_run) && \
70
+ $(workflow_run)
71
+ record:
72
+ export EXEC_COMMAND=bin/.run && \
73
+ export EXEC_OPTIONS="$(workflow_run_options)$(options)" && \
74
+ export EXEC_ARGS="record" && \
75
+ $(stoobly_exec_run) && \
76
+ $(workflow_run)
77
+ record/stop:
78
+ export EXEC_COMMAND=bin/.stop && \
79
+ export EXEC_OPTIONS="$(options)" && \
80
+ export EXEC_ARGS="record" && \
81
+ $(stoobly_exec_run) && \
82
+ $(workflow_run)
83
+ scenario/create:
84
+ # Create a scenario
85
+ export EXEC_COMMAND=bin/.create && \
86
+ export EXEC_OPTIONS="$(options)" && \
87
+ export EXEC_ARGS="$(name)" && \
88
+ $(stoobly_exec)
89
+ scenario/delete:
90
+ # Delete a scenario
91
+ export EXEC_COMMAND=bin/.delete && \
92
+ export EXEC_OPTIONS="$(options)" && \
93
+ export EXEC_ARGS="$(key)" && \
94
+ $(stoobly_exec)
95
+ scenario/reset:
96
+ # Resets a scenario to its last snapshot
97
+ export EXEC_COMMAND=bin/.reset && \:
98
+ export EXEC_OPTIONS="$(options)" && \
99
+ export EXEC_ARGS="$(key)" && \
100
+ $(stoobly_exec)
101
+ scenario/snapshot:
102
+ # Create committable files for a scenario
103
+ export EXEC_COMMAND=bin/.snapshot && \
104
+ export EXEC_OPTIONS="$(options)" && \
105
+ export EXEC_ARGS="$(key)" && \
106
+ $(stoobly_exec)
107
+ test:
108
+ export EXEC_COMMAND=bin/.run && \
109
+ export EXEC_OPTIONS="$(workflow_run_options)$(options)" && \
110
+ export EXEC_ARGS="test" && \
111
+ $(stoobly_exec_run) && \
112
+ $(workflow_run)
113
+ test/stop:
114
+ export EXEC_COMMAND=bin/.stop && \
115
+ export EXEC_OPTIONS="$(options)" && \
116
+ export EXEC_ARGS="test" && \
117
+ $(stoobly_exec_run) && \
118
+ $(workflow_run)
@@ -0,0 +1,15 @@
1
+ services:
2
+ context_base:
3
+ build:
4
+ args:
5
+ USER_ID: ${USER_ID}
6
+ dockerfile: ./.Dockerfile.context
7
+ volumes:
8
+ - ${CONTEXT_DIR}/.stoobly:/home/stoobly/.stoobly
9
+ proxy_base:
10
+ build:
11
+ args:
12
+ USER_ID: ${USER_ID}
13
+ dockerfile: ./.Dockerfile.proxy
14
+ volumes:
15
+ - ${CONTEXT_DIR}/.stoobly:/home/stoobly/.stoobly
@@ -0,0 +1,3 @@
1
+ DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
2
+
3
+ include $(DIR)/.Makefile
@@ -0,0 +1 @@
1
+ SERVICE_PRIORITY: 0
@@ -0,0 +1,11 @@
1
+ services:
2
+ build.init_base:
3
+ command: ['bin/.init']
4
+ extends:
5
+ file: ../.docker-compose.base.yml
6
+ service: proxy_base
7
+ build.configure_base:
8
+ command: ['bin/.configure']
9
+ extends:
10
+ file: ../.docker-compose.base.yml
11
+ service: proxy_base
@@ -0,0 +1,22 @@
1
+ services:
2
+ build.init:
3
+ build:
4
+ context: ./
5
+ dockerfile: ../../.Dockerfile.context
6
+ extends:
7
+ file: ../.docker-compose.base.yml
8
+ service: build.init_base
9
+ profiles:
10
+ - mock
11
+ build.configure:
12
+ build:
13
+ context: ./
14
+ dockerfile: ../../.Dockerfile.context
15
+ depends_on:
16
+ build.init:
17
+ condition: service_completed_successfully
18
+ extends:
19
+ file: ../.docker-compose.base.yml
20
+ service: build.configure_base
21
+ profiles:
22
+ - mock
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent config reset
4
+
5
+ cd $(dirname -- "$0") && ./configure
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent snapshot apply
4
+
5
+ cd $(dirname -- "$0") && ./init
@@ -0,0 +1,22 @@
1
+ services:
2
+ build.init:
3
+ build:
4
+ context: ./
5
+ dockerfile: ../../.Dockerfile.context
6
+ extends:
7
+ file: ../.docker-compose.base.yml
8
+ service: build.init_base
9
+ profiles:
10
+ - record
11
+ build.configure:
12
+ build:
13
+ context: ./
14
+ dockerfile: ../../.Dockerfile.context
15
+ depends_on:
16
+ build.init:
17
+ condition: service_completed_successfully
18
+ extends:
19
+ file: ../.docker-compose.base.yml
20
+ service: build.configure_base
21
+ profiles:
22
+ - record
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent config reset
4
+
5
+ cd $(dirname -- "$0") && ./configure
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent snapshot apply
4
+
5
+ cd $(dirname -- "$0") && ./init
@@ -0,0 +1,22 @@
1
+ services:
2
+ build.init:
3
+ build:
4
+ context: ./
5
+ dockerfile: ../../.Dockerfile.context
6
+ extends:
7
+ file: ../.docker-compose.base.yml
8
+ service: build.init_base
9
+ profiles:
10
+ - test
11
+ build.configure:
12
+ build:
13
+ context: ./
14
+ dockerfile: ../../.Dockerfile.context
15
+ depends_on:
16
+ build.init:
17
+ condition: service_completed_successfully
18
+ extends:
19
+ file: ../.docker-compose.base.yml
20
+ service: build.configure_base
21
+ profiles:
22
+ - test
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent config reset
4
+
5
+ cd $(dirname -- "$0") && ./configure
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ stoobly-agent snapshot apply
4
+
5
+ cd $(dirname -- "$0") && ./init
@@ -0,0 +1 @@
1
+ SERVICE_PRIORITY: 10.0
@@ -0,0 +1,17 @@
1
+ networks: {}
2
+ services:
3
+ entrypoint.configure_base:
4
+ command:
5
+ - bin/.configure
6
+ environment: {}
7
+ extends:
8
+ file: ../.docker-compose.base.yml
9
+ service: context_base
10
+ entrypoint.init_base:
11
+ command:
12
+ - bin/.init
13
+ - dist
14
+ environment: {}
15
+ extends:
16
+ file: ../.docker-compose.base.yml
17
+ service: context_base