fujin-cli 0.10.0__py3-none-any.whl → 0.11.5__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.
Potentially problematic release.
This version of fujin-cli might be problematic. Click here for more details.
- fujin/__main__.py +2 -2
- fujin/commands/init.py +1 -1
- fujin/config.py +46 -41
- fujin/secrets/__init__.py +7 -1
- fujin/secrets/system.py +19 -0
- fujin/templates/granian/web.service +22 -0
- fujin/templates/gunicorn/web.service +25 -0
- fujin/templates/gunicorn/web.socket +11 -0
- fujin/templates/simple.service +2 -1
- fujin/templates/web.service +0 -3
- {fujin_cli-0.10.0.dist-info → fujin_cli-0.11.5.dist-info}/METADATA +3 -2
- {fujin_cli-0.10.0.dist-info → fujin_cli-0.11.5.dist-info}/RECORD +15 -11
- {fujin_cli-0.10.0.dist-info → fujin_cli-0.11.5.dist-info}/WHEEL +1 -1
- {fujin_cli-0.10.0.dist-info → fujin_cli-0.11.5.dist-info}/entry_points.txt +0 -0
- {fujin_cli-0.10.0.dist-info → fujin_cli-0.11.5.dist-info}/licenses/LICENSE.txt +0 -0
fujin/__main__.py
CHANGED
|
@@ -50,9 +50,9 @@ class Fujin:
|
|
|
50
50
|
def main():
|
|
51
51
|
alias_cmd = _parse_aliases()
|
|
52
52
|
if alias_cmd:
|
|
53
|
-
cappa.invoke(Fujin, argv=alias_cmd)
|
|
53
|
+
cappa.invoke(Fujin, argv=alias_cmd, version="0.11.5")
|
|
54
54
|
else:
|
|
55
|
-
cappa.invoke(Fujin)
|
|
55
|
+
cappa.invoke(Fujin, version="0.11.5")
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def _parse_aliases() -> list[str] | None:
|
fujin/commands/init.py
CHANGED
fujin/config.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Fujin uses a
|
|
2
|
+
Fujin uses a **fujin.toml** file at the root of your project for configuration. Below are all available configuration options.
|
|
3
3
|
|
|
4
4
|
app
|
|
5
5
|
---
|
|
@@ -7,16 +7,16 @@ The name of your project or application. Must be a valid Python package name.
|
|
|
7
7
|
|
|
8
8
|
version
|
|
9
9
|
--------
|
|
10
|
-
The version of your project to build and deploy. If not specified, automatically parsed from
|
|
10
|
+
The version of your project to build and deploy. If not specified, automatically parsed from **pyproject.toml** under *project.version*.
|
|
11
11
|
|
|
12
12
|
python_version
|
|
13
13
|
--------------
|
|
14
|
-
The Python version for your virtualenv. If not specified, automatically parsed from
|
|
15
|
-
required if the installation mode is set to
|
|
14
|
+
The Python version for your virtualenv. If not specified, automatically parsed from **.python-version** file. This is only
|
|
15
|
+
required if the installation mode is set to **python-package**
|
|
16
16
|
|
|
17
17
|
requirements
|
|
18
18
|
------------
|
|
19
|
-
Optional path to your requirements file. This will only be used when the installation mode is set to
|
|
19
|
+
Optional path to your requirements file. This will only be used when the installation mode is set to *python-package*
|
|
20
20
|
|
|
21
21
|
versions_to_keep
|
|
22
22
|
----------------
|
|
@@ -30,32 +30,28 @@ The command to use to build your project's distribution file.
|
|
|
30
30
|
distfile
|
|
31
31
|
--------
|
|
32
32
|
Path to your project's distribution file. This should be the main artifact containing everything needed to run your project on the server.
|
|
33
|
-
Supports version placeholder, e.g.,
|
|
33
|
+
Supports version placeholder, e.g., **dist/app_name-{version}-py3-none-any.whl**
|
|
34
34
|
|
|
35
35
|
installation_mode
|
|
36
36
|
-----------------
|
|
37
37
|
|
|
38
|
-
Indicates whether the
|
|
39
|
-
The
|
|
40
|
-
|
|
38
|
+
Indicates whether the *distfile* is a Python package or a self-contained executable. The possible values are *python-package* and *binary*.
|
|
39
|
+
The *binary* option disables specific Python-related features, such as virtual environment creation and requirements installation. ``fujin`` will assume the provided
|
|
40
|
+
*distfile* already contains all the necessary dependencies to run your program.
|
|
41
41
|
|
|
42
42
|
release_command
|
|
43
43
|
---------------
|
|
44
|
-
Optional command to run at the end of deployment (e.g., database migrations).
|
|
44
|
+
Optional command to run at the end of deployment (e.g., database migrations) before your application is started.
|
|
45
45
|
|
|
46
46
|
secrets
|
|
47
47
|
-------
|
|
48
48
|
|
|
49
|
-
Optional secrets configuration. If set,
|
|
49
|
+
Optional secrets configuration. If set, ``fujin`` will load secrets from the specified secret management service.
|
|
50
50
|
Check out the `secrets </secrets.html>`_ page for more information.
|
|
51
51
|
|
|
52
52
|
adapter
|
|
53
53
|
~~~~~~~
|
|
54
|
-
The secret management service to use.
|
|
55
|
-
|
|
56
|
-
- ``bitwarden``
|
|
57
|
-
- ``1password``
|
|
58
|
-
- ``doppler``
|
|
54
|
+
The secret management service to use. The currently available options are *bitwarden*, *1password*, *doppler*
|
|
59
55
|
|
|
60
56
|
password_env
|
|
61
57
|
~~~~~~~~~~~~
|
|
@@ -64,35 +60,39 @@ Environment variable containing the password for the service account. This is on
|
|
|
64
60
|
Webserver
|
|
65
61
|
---------
|
|
66
62
|
|
|
63
|
+
Web server configurations.
|
|
64
|
+
|
|
67
65
|
type
|
|
68
66
|
~~~~
|
|
69
67
|
The reverse proxy implementation to use. Available options:
|
|
70
68
|
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
69
|
+
- *fujin.proxies.caddy* (default)
|
|
70
|
+
- *fujin.proxies.nginx*
|
|
71
|
+
- *fujin.proxies.dummy* (disables proxy)
|
|
74
72
|
|
|
75
73
|
upstream
|
|
76
74
|
~~~~~~~~
|
|
77
75
|
The address where your web application listens for requests. Supports any value compatible with your chosen web proxy:
|
|
78
76
|
|
|
79
|
-
- HTTP address (e.g.,
|
|
80
|
-
- Unix socket (e.g.,
|
|
77
|
+
- HTTP address (e.g., *localhost:8000* )
|
|
78
|
+
- Unix socket caddy (e.g., *unix//run/project.sock* )
|
|
79
|
+
- Unix socket nginx (e.g., *http://unix:/run/project.sock* )
|
|
81
80
|
|
|
82
81
|
certbot_email
|
|
83
82
|
~~~~~~~~~~~~~
|
|
84
|
-
Required when Nginx is used as a proxy
|
|
83
|
+
Required when Nginx is used as a proxy to obtain SSL certificates.
|
|
85
84
|
|
|
86
85
|
statics
|
|
87
86
|
~~~~~~~
|
|
88
87
|
|
|
89
88
|
Defines the mapping of URL paths to local directories for serving static files. The syntax and support for static
|
|
90
89
|
file serving depend on the selected reverse proxy. The directories you map should be accessible by the web server, meaning
|
|
91
|
-
with read permissions for the
|
|
90
|
+
with read permissions for the *www-data* group; a reliable choice is **/var/www**.
|
|
92
91
|
|
|
93
92
|
Example:
|
|
94
93
|
|
|
95
94
|
.. code-block:: toml
|
|
95
|
+
:caption: fujin.toml
|
|
96
96
|
|
|
97
97
|
[webserver]
|
|
98
98
|
upstream = "unix//run/project.sock"
|
|
@@ -103,12 +103,12 @@ processes
|
|
|
103
103
|
---------
|
|
104
104
|
|
|
105
105
|
A mapping of process names to commands that will be managed by the process manager. Define as many processes as needed, but
|
|
106
|
-
when using any proxy other than
|
|
107
|
-
setting on the host to understand how ``app_dir`` is determined.
|
|
106
|
+
when using any proxy other than *fujin.proxies.dummy*, a *web* process must be declared.
|
|
108
107
|
|
|
109
108
|
Example:
|
|
110
109
|
|
|
111
110
|
.. code-block:: toml
|
|
111
|
+
:caption: fujin.toml
|
|
112
112
|
|
|
113
113
|
[processes]
|
|
114
114
|
web = ".venv/bin/gunicorn myproject.wsgi:application"
|
|
@@ -116,7 +116,8 @@ Example:
|
|
|
116
116
|
|
|
117
117
|
.. note::
|
|
118
118
|
|
|
119
|
-
Commands are relative to your
|
|
119
|
+
Commands are relative to your *app_dir*. When generating systemd service files, the full path is automatically constructed.
|
|
120
|
+
Refer to the *apps_dir* setting on the host to understand how *app_dir* is determined.
|
|
120
121
|
Here are the templates for the service files:
|
|
121
122
|
|
|
122
123
|
- `web.service <https://github.com/falcopackages/fujin/blob/main/src/fujin/templates/web.service>`_
|
|
@@ -128,7 +129,7 @@ Host Configuration
|
|
|
128
129
|
|
|
129
130
|
ip
|
|
130
131
|
~~
|
|
131
|
-
The IP address or anything that resolves to the remote host IP's. This is use to communicate via ssh with the server, if omitted it's value will default to the one of the
|
|
132
|
+
The IP address or anything that resolves to the remote host IP's. This is use to communicate via ssh with the server, if omitted it's value will default to the one of the *domain_name*.
|
|
132
133
|
|
|
133
134
|
domain_name
|
|
134
135
|
~~~~~~~~~~~
|
|
@@ -142,23 +143,23 @@ The login user for running remote tasks. Should have passwordless sudo access fo
|
|
|
142
143
|
|
|
143
144
|
You can create a user with these requirements using the ``fujin server create-user`` command.
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
envfile
|
|
147
|
+
~~~~~~~
|
|
147
148
|
Path to the production environment file that will be copied to the host.
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
env
|
|
151
|
+
~~~
|
|
151
152
|
A string containing the production environment variables, ideal for scenarios where most variables are retrieved from secrets and you prefer not to use a separate file.
|
|
152
153
|
|
|
153
154
|
.. important::
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
*envfile* and *env* are mutually exclusive—you can define only one.
|
|
156
157
|
|
|
157
158
|
apps_dir
|
|
158
159
|
~~~~~~~~
|
|
159
160
|
|
|
160
161
|
Base directory for project storage on the host. Path is relative to user's home directory.
|
|
161
|
-
Default:
|
|
162
|
+
Default: **.local/share/fujin**. This value determines your project's **app_dir**, which is **{apps_dir}/{app}**.
|
|
162
163
|
|
|
163
164
|
password_env
|
|
164
165
|
~~~~~~~~~~~~
|
|
@@ -168,8 +169,7 @@ Environment variable containing the user's password. Only needed if the user can
|
|
|
168
169
|
ssh_port
|
|
169
170
|
~~~~~~~~
|
|
170
171
|
|
|
171
|
-
SSH port for connecting to the host.
|
|
172
|
-
Default: ``22``
|
|
172
|
+
SSH port for connecting to the host. Default to **22**.
|
|
173
173
|
|
|
174
174
|
key_filename
|
|
175
175
|
~~~~~~~~~~~~
|
|
@@ -184,6 +184,7 @@ A mapping of shortcut names to Fujin commands. Allows you to create convenient s
|
|
|
184
184
|
Example:
|
|
185
185
|
|
|
186
186
|
.. code-block:: toml
|
|
187
|
+
:caption: fujin.toml
|
|
187
188
|
|
|
188
189
|
[aliases]
|
|
189
190
|
console = "app exec -i shell_plus" # open an interactive django shell
|
|
@@ -223,6 +224,7 @@ class SecretAdapter(StrEnum):
|
|
|
223
224
|
BITWARDEN = "bitwarden"
|
|
224
225
|
ONE_PASSWORD = "1password"
|
|
225
226
|
DOPPLER = "doppler"
|
|
227
|
+
SYSTEM = "system"
|
|
226
228
|
|
|
227
229
|
|
|
228
230
|
class SecretConfig(msgspec.Struct):
|
|
@@ -246,7 +248,10 @@ class Config(msgspec.Struct, kw_only=True):
|
|
|
246
248
|
requirements: str | None = None
|
|
247
249
|
hooks: HooksDict = msgspec.field(default_factory=dict)
|
|
248
250
|
local_config_dir: Path = Path(".fujin")
|
|
249
|
-
secret_config: SecretConfig | None = msgspec.field(
|
|
251
|
+
secret_config: SecretConfig | None = msgspec.field(
|
|
252
|
+
name="secrets",
|
|
253
|
+
default_factory=lambda: SecretConfig(adapter=SecretAdapter.SYSTEM),
|
|
254
|
+
)
|
|
250
255
|
|
|
251
256
|
def __post_init__(self):
|
|
252
257
|
if self.installation_mode == InstallationMode.PY_PACKAGE:
|
|
@@ -285,8 +290,8 @@ class HostConfig(msgspec.Struct, kw_only=True):
|
|
|
285
290
|
ip: str | None = None
|
|
286
291
|
domain_name: str
|
|
287
292
|
user: str
|
|
288
|
-
_env_file: str = msgspec.field(name="envfile", default=
|
|
289
|
-
env_content: str = ""
|
|
293
|
+
_env_file: str | None = msgspec.field(name="envfile", default=None)
|
|
294
|
+
env_content: str | None = msgspec.field(name="env", default=None)
|
|
290
295
|
apps_dir: str = ".local/share/fujin"
|
|
291
296
|
password_env: str | None = None
|
|
292
297
|
ssh_port: int = 22
|
|
@@ -295,14 +300,14 @@ class HostConfig(msgspec.Struct, kw_only=True):
|
|
|
295
300
|
def __post_init__(self):
|
|
296
301
|
if self._env_file and self.env_content:
|
|
297
302
|
raise ImproperlyConfiguredError(
|
|
298
|
-
"Cannot set both '
|
|
303
|
+
"Cannot set both 'env' and 'envfile' properties."
|
|
299
304
|
)
|
|
300
|
-
if
|
|
305
|
+
if self._env_file:
|
|
301
306
|
envfile = Path(self._env_file)
|
|
302
307
|
if not envfile.exists():
|
|
303
308
|
raise ImproperlyConfiguredError(f"{self._env_file} not found")
|
|
304
309
|
self.env_content = envfile.read_text()
|
|
305
|
-
self.env_content = self.env_content.strip()
|
|
310
|
+
self.env_content = self.env_content.strip() if self.env_content else ""
|
|
306
311
|
self.apps_dir = f"/home/{self.user}/{self.apps_dir}"
|
|
307
312
|
self.ip = self.ip or self.domain_name
|
|
308
313
|
|
fujin/secrets/__init__.py
CHANGED
|
@@ -12,11 +12,13 @@ from fujin.config import SecretConfig
|
|
|
12
12
|
from .bitwarden import bitwarden
|
|
13
13
|
from .dopppler import doppler
|
|
14
14
|
from .onepassword import one_password
|
|
15
|
+
from .system import system
|
|
15
16
|
|
|
16
17
|
secret_reader = Callable[[str], str]
|
|
17
18
|
secret_adapter_context = Callable[[SecretConfig], ContextManager[secret_reader]]
|
|
18
19
|
|
|
19
20
|
adapter_to_context: dict[SecretAdapter, secret_adapter_context] = {
|
|
21
|
+
SecretAdapter.SYSTEM: system,
|
|
20
22
|
SecretAdapter.BITWARDEN: bitwarden,
|
|
21
23
|
SecretAdapter.ONE_PASSWORD: one_password,
|
|
22
24
|
SecretAdapter.DOPPLER: doppler,
|
|
@@ -24,6 +26,8 @@ adapter_to_context: dict[SecretAdapter, secret_adapter_context] = {
|
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
def resolve_secrets(env_content: str, secret_config: SecretConfig) -> str:
|
|
29
|
+
if not env_content: # this is really for empty string
|
|
30
|
+
return ""
|
|
27
31
|
with closing(StringIO(env_content)) as buffer:
|
|
28
32
|
env_dict = dotenv_values(stream=buffer)
|
|
29
33
|
secrets = {key: value for key, value in env_dict.items() if value.startswith("$")}
|
|
@@ -33,7 +37,9 @@ def resolve_secrets(env_content: str, secret_config: SecretConfig) -> str:
|
|
|
33
37
|
parsed_secrets = {}
|
|
34
38
|
with adapter_context(secret_config) as reader:
|
|
35
39
|
for key, secret in secrets.items():
|
|
36
|
-
parsed_secrets[key] = gevent.spawn(
|
|
40
|
+
parsed_secrets[key] = gevent.spawn(
|
|
41
|
+
reader, secret[1:]
|
|
42
|
+
) # remove the leading $
|
|
37
43
|
gevent.joinall(parsed_secrets.values())
|
|
38
44
|
env_dict.update({key: thread.value for key, thread in parsed_secrets.items()})
|
|
39
45
|
return "\n".join(f'{key}="{value}"' for key, value in env_dict.items())
|
fujin/secrets/system.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from typing import Generator
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from fujin.config import SecretConfig
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from . import secret_reader
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@contextmanager
|
|
15
|
+
def system(_: SecretConfig) -> Generator[secret_reader, None, None]:
|
|
16
|
+
try:
|
|
17
|
+
yield os.getenv
|
|
18
|
+
finally:
|
|
19
|
+
pass
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# All options are documented here https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
|
|
2
|
+
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
|
+
[Unit]
|
|
4
|
+
Description={app_name} daemon
|
|
5
|
+
After=network.target
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
User={user}
|
|
9
|
+
Group={user}
|
|
10
|
+
RuntimeDirectory={app_name}
|
|
11
|
+
WorkingDirectory={app_dir}
|
|
12
|
+
ExecStart={app_dir}/{command}
|
|
13
|
+
EnvironmentFile={app_dir}/.env
|
|
14
|
+
ExecReload=/bin/kill -s HUP $MAINPID
|
|
15
|
+
KillMode=mixed
|
|
16
|
+
TimeoutStopSec=5
|
|
17
|
+
PrivateTmp=true
|
|
18
|
+
# if your app does not need administrative capabilities, let systemd know
|
|
19
|
+
ProtectSystem=strict
|
|
20
|
+
|
|
21
|
+
[Install]
|
|
22
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# All options are documented here https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
|
|
2
|
+
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
|
+
[Unit]
|
|
4
|
+
Description={app_name} daemon
|
|
5
|
+
Requires={app_name}.socket
|
|
6
|
+
After=network.target
|
|
7
|
+
|
|
8
|
+
[Service]
|
|
9
|
+
Type=notify
|
|
10
|
+
NotifyAccess=main
|
|
11
|
+
User={user}
|
|
12
|
+
Group={user}
|
|
13
|
+
RuntimeDirectory={app_name}
|
|
14
|
+
WorkingDirectory={app_dir}
|
|
15
|
+
ExecStart={app_dir}/{command}
|
|
16
|
+
EnvironmentFile={app_dir}/.env
|
|
17
|
+
ExecReload=/bin/kill -s HUP $MAINPID
|
|
18
|
+
KillMode=mixed
|
|
19
|
+
TimeoutStopSec=5
|
|
20
|
+
PrivateTmp=true
|
|
21
|
+
# if your app does not need administrative capabilities, let systemd know
|
|
22
|
+
ProtectSystem=strict
|
|
23
|
+
|
|
24
|
+
[Install]
|
|
25
|
+
WantedBy=multi-user.target
|
fujin/templates/simple.service
CHANGED
fujin/templates/web.service
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
3
|
[Unit]
|
|
4
4
|
Description={app_name} daemon
|
|
5
|
-
Requires={app_name}.socket
|
|
6
5
|
After=network.target
|
|
7
6
|
|
|
8
7
|
[Service]
|
|
9
|
-
#Type=notify
|
|
10
|
-
#NotifyAccess=main
|
|
11
8
|
User={user}
|
|
12
9
|
Group={user}
|
|
13
10
|
RuntimeDirectory={app_name}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: fujin-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.5
|
|
4
4
|
Summary: Get your project up and running in a few minutes on your own vps.
|
|
5
5
|
Project-URL: Documentation, https://github.com/falcopackages/fujin#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/falcopackages/fujin/issues
|
|
7
7
|
Project-URL: Source, https://github.com/falcopackages/fujin
|
|
8
8
|
Author-email: Tobi DEGNON <tobidegnon@proton.me>
|
|
9
|
+
License-File: LICENSE.txt
|
|
9
10
|
Keywords: caddy,deployment,django,fastapi,litestar,python,systemd
|
|
10
11
|
Classifier: Development Status :: 3 - Alpha
|
|
11
12
|
Classifier: Intended Audience :: Developers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
fujin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
fujin/__main__.py,sha256=
|
|
3
|
-
fujin/config.py,sha256=
|
|
2
|
+
fujin/__main__.py,sha256=e9T-E4qC1sIw315_sKpSVCYKScZFYCfig8ShNRyNagM,1849
|
|
3
|
+
fujin/config.py,sha256=t7UnhQMl-wYDyFCIcOC5lLdfpSmYWDIRPHvozoSoVME,11707
|
|
4
4
|
fujin/connection.py,sha256=LL7LhX9p0X9FmiGdlSroD3Ht216QY0Kd51xkSrXmM3s,2479
|
|
5
5
|
fujin/errors.py,sha256=74Rh-Sgql1YspPdR_akQ2G3xZ48zecyafYCptpaFo1A,73
|
|
6
6
|
fujin/hooks.py,sha256=EDVYNozlDJ5kc1xHtZrXgtuKplUMEMPTp65TLMP02Ek,1449
|
|
@@ -12,7 +12,7 @@ fujin/commands/config.py,sha256=WymGla-H2yduhLcYE1Nb6IJaFIj0S0KIhV9fBDCKsAw,2779
|
|
|
12
12
|
fujin/commands/deploy.py,sha256=AylcVNX47ekf-AFfQrYcSh86I3qltADEgjPtV9lQAfE,5831
|
|
13
13
|
fujin/commands/docs.py,sha256=b5FZ8AgoAfn4q4BueEQvM2w5HCuh8-rwBqv_CRFVU8E,349
|
|
14
14
|
fujin/commands/down.py,sha256=aw_mxl_TMC66plKTXwlYP1W2XQBmHeROltQqOpQssyE,1577
|
|
15
|
-
fujin/commands/init.py,sha256=
|
|
15
|
+
fujin/commands/init.py,sha256=9yrja4YYFlJqEarN0ekg6yPd5niifPwvQ4i4wnC55a0,4007
|
|
16
16
|
fujin/commands/printenv.py,sha256=bS2mIgk7zd_w3yDhZLTa1PkHIzuSbBWjnYyM8CUjX0k,523
|
|
17
17
|
fujin/commands/proxy.py,sha256=ajXwboS0gDDiMWW7b9rtWU6WPF1h7JYYeycDyU-hQfg,3053
|
|
18
18
|
fujin/commands/prune.py,sha256=3Y0ZpgoI8eb_FVD6XMmZK9lEp2delKUeJdK09kv9_08,1509
|
|
@@ -24,15 +24,19 @@ fujin/proxies/__init__.py,sha256=UuWYU175tkdaz1WWRCDDpQgGfFVYYNR9PBxA3lTCNr0,695
|
|
|
24
24
|
fujin/proxies/caddy.py,sha256=H52D7cGEEGcxDaXxvClnny9lAat_h1G9dYlIlf6gwKo,7933
|
|
25
25
|
fujin/proxies/dummy.py,sha256=qBKSn8XNEA9SVwB7GzRNX2l9Iw6tUjo2CFqZjWi0FjY,465
|
|
26
26
|
fujin/proxies/nginx.py,sha256=BNJNLxLLRVAmBIGVCk8pb16iiSJsOI9jXOZhdSQGtX8,4151
|
|
27
|
-
fujin/secrets/__init__.py,sha256=
|
|
27
|
+
fujin/secrets/__init__.py,sha256=nicjIkcEX22rSD-Fleg0jG2IaBtvEq1dbkcfZ7lGlGI,1633
|
|
28
28
|
fujin/secrets/bitwarden.py,sha256=01GZL5hYwZzL6yXy5ab3L3kgBFBeOT8i3Yg9GC8YwFU,2008
|
|
29
29
|
fujin/secrets/dopppler.py,sha256=t5SGfyuA0RxsD9uvrAu4cG2TBDIUgB5gb6XYXPrd61Y,724
|
|
30
30
|
fujin/secrets/onepassword.py,sha256=6Xj3XWttKfcjMbcoMZvXVpJW1KHxlD785DysmX_mqvk,654
|
|
31
|
-
fujin/
|
|
32
|
-
fujin/templates/
|
|
31
|
+
fujin/secrets/system.py,sha256=Z5uNc2V3rcR75ffBnOsJywndoWuDcih88O9nPXIJ3U0,382
|
|
32
|
+
fujin/templates/simple.service,sha256=ySlLqF354UCvlQaJcEVj4jf4hK7aKAq9qseE6pmtXJI,350
|
|
33
|
+
fujin/templates/web.service,sha256=D3vHOHdP3wrZueKuhlhkB4syOCVvGSciDsNsmU_Bp68,626
|
|
33
34
|
fujin/templates/web.socket,sha256=2lJsiOHlMJL0YlN7YBLLnr5zqsytPEt81yP34nk0dmc,173
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
fujin_cli-0.
|
|
38
|
-
fujin_cli-0.
|
|
35
|
+
fujin/templates/granian/web.service,sha256=D3vHOHdP3wrZueKuhlhkB4syOCVvGSciDsNsmU_Bp68,626
|
|
36
|
+
fujin/templates/gunicorn/web.service,sha256=EfTJQP4VvwlOTDyVCch5Y7iVhpPvZVaRWE6MHI4_z4k,683
|
|
37
|
+
fujin/templates/gunicorn/web.socket,sha256=2lJsiOHlMJL0YlN7YBLLnr5zqsytPEt81yP34nk0dmc,173
|
|
38
|
+
fujin_cli-0.11.5.dist-info/METADATA,sha256=SMsJ4wtSPlaJJtLU1erFIYzE8gZWp5Bw5fB-ZpCeYI8,4603
|
|
39
|
+
fujin_cli-0.11.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
40
|
+
fujin_cli-0.11.5.dist-info/entry_points.txt,sha256=Y_TBtKt3j11qhwquMexZR5yqnDEqOBDACtresqQFE-s,46
|
|
41
|
+
fujin_cli-0.11.5.dist-info/licenses/LICENSE.txt,sha256=0QF8XfuH0zkIHhSet6teXfiCze6JSdr8inRkmLLTDyo,1099
|
|
42
|
+
fujin_cli-0.11.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|