plonex 0.0.1a0__tar.gz
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.
- plonex-0.0.1a0/PKG-INFO +1558 -0
- plonex-0.0.1a0/README.md +1508 -0
- plonex-0.0.1a0/pyproject.toml +142 -0
- plonex-0.0.1a0/pyproject.toml.orig +122 -0
- plonex-0.0.1a0/src/plonex/__init__.py +1 -0
- plonex-0.0.1a0/src/plonex/_logger.py +49 -0
- plonex-0.0.1a0/src/plonex/base.py +969 -0
- plonex-0.0.1a0/src/plonex/cli/__init__.py +231 -0
- plonex-0.0.1a0/src/plonex/cli/__main__.py +4 -0
- plonex-0.0.1a0/src/plonex/cli/aliases.py +96 -0
- plonex-0.0.1a0/src/plonex/cli/commands.py +134 -0
- plonex-0.0.1a0/src/plonex/cli/cron.py +122 -0
- plonex-0.0.1a0/src/plonex/cli/db.py +87 -0
- plonex-0.0.1a0/src/plonex/cli/dependencies.py +106 -0
- plonex-0.0.1a0/src/plonex/cli/describe.py +52 -0
- plonex-0.0.1a0/src/plonex/cli/job_view.py +39 -0
- plonex-0.0.1a0/src/plonex/cli/jobs.py +355 -0
- plonex-0.0.1a0/src/plonex/cli/options.py +28 -0
- plonex-0.0.1a0/src/plonex/cli/parser.py +203 -0
- plonex-0.0.1a0/src/plonex/cli/runtime.py +269 -0
- plonex-0.0.1a0/src/plonex/cli/setup_info.py +529 -0
- plonex-0.0.1a0/src/plonex/cli/shell.py +340 -0
- plonex-0.0.1a0/src/plonex/cli/testing.py +129 -0
- plonex-0.0.1a0/src/plonex/config.py +165 -0
- plonex-0.0.1a0/src/plonex/configuration.py +164 -0
- plonex-0.0.1a0/src/plonex/environment.py +47 -0
- plonex-0.0.1a0/src/plonex/files.py +73 -0
- plonex-0.0.1a0/src/plonex/inspection.py +211 -0
- plonex-0.0.1a0/src/plonex/preparation/__init__.py +1 -0
- plonex-0.0.1a0/src/plonex/preparation/dependencies.py +348 -0
- plonex-0.0.1a0/src/plonex/preparation/engine.py +263 -0
- plonex-0.0.1a0/src/plonex/preparation/supervisor.py +375 -0
- plonex-0.0.1a0/src/plonex/presentation.py +52 -0
- plonex-0.0.1a0/src/plonex/services/__init__.py +41 -0
- plonex-0.0.1a0/src/plonex/services/adduser/__init__.py +48 -0
- plonex-0.0.1a0/src/plonex/services/compile/__init__.py +24 -0
- plonex-0.0.1a0/src/plonex/services/cron/__init__.py +357 -0
- plonex-0.0.1a0/src/plonex/services/cron/browser.py +114 -0
- plonex-0.0.1a0/src/plonex/services/cron/configure.zcml +15 -0
- plonex-0.0.1a0/src/plonex/services/cron/installation.py +56 -0
- plonex-0.0.1a0/src/plonex/services/cron/model.py +226 -0
- plonex-0.0.1a0/src/plonex/services/cron/plone_runner.py +48 -0
- plonex-0.0.1a0/src/plonex/services/cron/profiles/default/controlpanel.xml +8 -0
- plonex-0.0.1a0/src/plonex/services/cron/runner.py +303 -0
- plonex-0.0.1a0/src/plonex/services/cron/runtime.py +449 -0
- plonex-0.0.1a0/src/plonex/services/describe/__init__.py +452 -0
- plonex-0.0.1a0/src/plonex/services/describe/formatting.py +180 -0
- plonex-0.0.1a0/src/plonex/services/describe/report.py +819 -0
- plonex-0.0.1a0/src/plonex/services/describe/templates/plonex_description.md.j2 +124 -0
- plonex-0.0.1a0/src/plonex/services/describe/templates/report.html.j2 +47 -0
- plonex-0.0.1a0/src/plonex/services/directory/__init__.py +21 -0
- plonex-0.0.1a0/src/plonex/services/doctor/__init__.py +751 -0
- plonex-0.0.1a0/src/plonex/services/edit/__init__.py +184 -0
- plonex-0.0.1a0/src/plonex/services/edit/tui.py +85 -0
- plonex-0.0.1a0/src/plonex/services/init/__init__.py +119 -0
- plonex-0.0.1a0/src/plonex/services/init/templates/plonex.yml.j2 +87 -0
- plonex-0.0.1a0/src/plonex/services/install/__init__.py +994 -0
- plonex-0.0.1a0/src/plonex/services/install/preview.py +160 -0
- plonex-0.0.1a0/src/plonex/services/install/report.py +120 -0
- plonex-0.0.1a0/src/plonex/services/invocation.py +119 -0
- plonex-0.0.1a0/src/plonex/services/legacy/__init__.py +146 -0
- plonex-0.0.1a0/src/plonex/services/profile/__init__.py +74 -0
- plonex-0.0.1a0/src/plonex/services/pytest/__init__.py +28 -0
- plonex-0.0.1a0/src/plonex/services/registry.py +88 -0
- plonex-0.0.1a0/src/plonex/services/robotserver/__init__.py +32 -0
- plonex-0.0.1a0/src/plonex/services/robottest/__init__.py +38 -0
- plonex-0.0.1a0/src/plonex/services/runwsgi/__init__.py +102 -0
- plonex-0.0.1a0/src/plonex/services/runwsgi/templates/wsgi.ini.j2 +80 -0
- plonex-0.0.1a0/src/plonex/services/snapshot/__init__.py +532 -0
- plonex-0.0.1a0/src/plonex/services/sources/__init__.py +789 -0
- plonex-0.0.1a0/src/plonex/services/sources/installation.py +204 -0
- plonex-0.0.1a0/src/plonex/services/sources/testing.py +71 -0
- plonex-0.0.1a0/src/plonex/services/supervisor/__init__.py +250 -0
- plonex-0.0.1a0/src/plonex/services/supervisor/templates/program.conf.j2 +7 -0
- plonex-0.0.1a0/src/plonex/services/supervisor/templates/supervisord.conf.j2 +25 -0
- plonex-0.0.1a0/src/plonex/services/template/__init__.py +94 -0
- plonex-0.0.1a0/src/plonex/services/upgrade/__init__.py +197 -0
- plonex-0.0.1a0/src/plonex/services/zconsole/__init__.py +40 -0
- plonex-0.0.1a0/src/plonex/services/zeoserver/__init__.py +105 -0
- plonex-0.0.1a0/src/plonex/services/zeoserver/backup.py +198 -0
- plonex-0.0.1a0/src/plonex/services/zeoserver/templates/zeo.conf.j2 +21 -0
- plonex-0.0.1a0/src/plonex/services/zope_configuration/templates/__init__.py +0 -0
- plonex-0.0.1a0/src/plonex/services/zope_configuration/templates/site.zcml.j2 +27 -0
- plonex-0.0.1a0/src/plonex/services/zope_configuration/templates/zope.conf.j2 +34 -0
- plonex-0.0.1a0/src/plonex/services/zopetest/__init__.py +42 -0
plonex-0.0.1a0/PKG-INFO
ADDED
|
@@ -0,0 +1,1558 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: plonex
|
|
3
|
+
Version: 0.0.1a0
|
|
4
|
+
Summary: Deploy a manage Plone site based on some configuration files
|
|
5
|
+
Keywords: plone,deployment
|
|
6
|
+
Author: Alessandro Pisa
|
|
7
|
+
Author-email: Alessandro Pisa <pisa@syslab.com>
|
|
8
|
+
License: GPL-3.0
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Dist: doit>=0.36,<0.37
|
|
21
|
+
Requires-Dist: argcomplete
|
|
22
|
+
Requires-Dist: jinja2
|
|
23
|
+
Requires-Dist: packaging
|
|
24
|
+
Requires-Dist: pip-requirements-parser
|
|
25
|
+
Requires-Dist: pygments>=2.13,<3
|
|
26
|
+
Requires-Dist: pyyaml
|
|
27
|
+
Requires-Dist: requests
|
|
28
|
+
Requires-Dist: rich
|
|
29
|
+
Requires-Dist: rich-argparse
|
|
30
|
+
Requires-Dist: sh
|
|
31
|
+
Requires-Dist: types-pyyaml
|
|
32
|
+
Requires-Dist: types-requests
|
|
33
|
+
Requires-Dist: types-setuptools
|
|
34
|
+
Requires-Dist: mypy ; extra == 'test'
|
|
35
|
+
Requires-Dist: pytest ; extra == 'test'
|
|
36
|
+
Requires-Dist: pytest-cov ; extra == 'test'
|
|
37
|
+
Requires-Dist: supervisor ; extra == 'test'
|
|
38
|
+
Requires-Dist: huey[stats]>=3.5,<4 ; extra == 'test'
|
|
39
|
+
Requires-Dist: zodb ; extra == 'test'
|
|
40
|
+
Maintainer: Alessandro Pisa
|
|
41
|
+
Maintainer-email: Alessandro Pisa <pisa@syslab.com>
|
|
42
|
+
Requires-Python: >=3.11
|
|
43
|
+
Project-URL: Homepage, https://github.com/collective/plonex
|
|
44
|
+
Project-URL: Documentation, https://plonex.readthedocs.io/
|
|
45
|
+
Project-URL: Repository, https://github.com/collective/plonex
|
|
46
|
+
Project-URL: Issues, https://github.com/collective/plonex/issues
|
|
47
|
+
Project-URL: Changelog, https://github.com/collective/plonex/blob/main/CHANGES.md
|
|
48
|
+
Provides-Extra: test
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
|
|
51
|
+
# plonex
|
|
52
|
+
|
|
53
|
+
Plone deployment CLI.
|
|
54
|
+
|
|
55
|
+
`plonex` is a helper tool designed to simplify everyday project operations with Plone.
|
|
56
|
+
|
|
57
|
+
Read the [documentation](https://plonex.readthedocs.io/) for guides and reference material.
|
|
58
|
+
|
|
59
|
+
> [!NOTE]
|
|
60
|
+
> At the moment `plonex` is in early development and may have breaking changes. Use with caution and report issues.
|
|
61
|
+
|
|
62
|
+
## Quickstart
|
|
63
|
+
|
|
64
|
+
If you just want to test `plonex`, you can initialize a new project and run the ZEO server and client with these commands:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
plonex project init myproject
|
|
68
|
+
cd myproject
|
|
69
|
+
plonex supervisor start
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The generated configuration starts ZEO and the WSGI client under Supervisor in
|
|
73
|
+
the background. Use `plonex supervisor status` to check them. Runtime files are
|
|
74
|
+
generated from your YAML configuration.
|
|
75
|
+
|
|
76
|
+
Your site will be available at `http://localhost:8080`.
|
|
77
|
+
|
|
78
|
+
## The magic behind the scenes
|
|
79
|
+
|
|
80
|
+
When you run a command, `plonex` does more than simply spawn a process:
|
|
81
|
+
|
|
82
|
+
- it finds the correct project root (a parent folder containing a file named `etc/plonex.yml`)
|
|
83
|
+
- it loads and merges configuration from all supported files
|
|
84
|
+
- it prepares temporary/generated config files when needed
|
|
85
|
+
- it exports environment variables defined in configuration
|
|
86
|
+
- it runs the appropriate executable from your virtualenv
|
|
87
|
+
|
|
88
|
+
This means commands are reproducible and configuration-driven.
|
|
89
|
+
You change behavior in YAML files (or CLI flags), and `plonex` applies that
|
|
90
|
+
consistently across services.
|
|
91
|
+
|
|
92
|
+
## Command layout
|
|
93
|
+
|
|
94
|
+
Use `plonex RESOURCE ACTION [options]` across the CLI:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
plonex project compile
|
|
98
|
+
plonex sources list
|
|
99
|
+
plonex sources update
|
|
100
|
+
plonex dependencies install --update-sources
|
|
101
|
+
plonex dependencies sync
|
|
102
|
+
plonex instance debug
|
|
103
|
+
plonex db backup
|
|
104
|
+
plonex test pytest my.package -k login
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`project`, `dependencies`, `sources`, `instance`, `supervisor`, `db`, `cron`, and `test`
|
|
108
|
+
provide command families. `shell` and `options` provide interactive access and
|
|
109
|
+
inspection. Each operation has one built-in spelling. Removed shortcuts and flags are listed
|
|
110
|
+
in the [CLI structure and migration guide](docs/cli.md). Bare command families show help.
|
|
111
|
+
|
|
112
|
+
## Autocomplete
|
|
113
|
+
|
|
114
|
+
Add this to your shell startup file:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
eval "$(register-python-argcomplete plonex)"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Interactive shell
|
|
121
|
+
|
|
122
|
+
Start a prompt for your current project with `plonex shell`, or choose a project:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
plonex shell --target /path/to/project
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Enter the same commands and arguments you use at the command line, without the
|
|
129
|
+
`plonex` prefix:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
plonex[myproject]> supervisor status
|
|
133
|
+
plonex[myproject]> dependencies sync
|
|
134
|
+
plonex[myproject]> sources list "plone.*"
|
|
135
|
+
plonex[myproject]> test robot tests/robot/example.robot --test "Login works"
|
|
136
|
+
plonex[myproject]> help dependencies
|
|
137
|
+
plonex[myproject]> exit
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- Tab completes commands, subcommands, flags, and paths when readline is available.
|
|
141
|
+
- Up/Down recall commands from this project's current and previous sessions.
|
|
142
|
+
- `history` lists remembered commands. History is stored in
|
|
143
|
+
`var/plonex-shell-history` under the target project with owner-only permissions.
|
|
144
|
+
Commands with recognizable credentials are omitted, but avoid placing secrets
|
|
145
|
+
in command arguments: detection cannot recognize every possible secret.
|
|
146
|
+
- `help` lists commands; `help COMMAND` and `COMMAND --help` show command help.
|
|
147
|
+
- `exit`, `quit`, or Ctrl-D leave the shell. Ctrl-C cancels the current input or
|
|
148
|
+
interrupts a running command and returns to the prompt.
|
|
149
|
+
- In an interactive terminal, Ctrl-Z returns to the prompt **without stopping the
|
|
150
|
+
current command**. The server stays available for requests and upgrades.
|
|
151
|
+
- Blank lines and lines beginning with `#` are ignored.
|
|
152
|
+
- Quoting, escaped spaces, and `--` work as they do in the CLI. Arguments are
|
|
153
|
+
passed directly to plonex; pipes, redirects, variable expansion, and wildcard
|
|
154
|
+
expansion are not interpreted by this prompt.
|
|
155
|
+
|
|
156
|
+
The shell uses the selected project as its working directory. Each command runs
|
|
157
|
+
in a fresh process using the same Python installation as plonex, so configuration
|
|
158
|
+
is reloaded and command-specific environment variables do not leak into later
|
|
159
|
+
commands. Errors leave the prompt open.
|
|
160
|
+
|
|
161
|
+
Startup `--verbose` or `--quiet` flags become session defaults. An explicit `-v`
|
|
162
|
+
or `-q` on a command overrides those defaults for that command. To run a command
|
|
163
|
+
against another project without changing the session target, use
|
|
164
|
+
`--target /other/project COMMAND`. The optional `plonex` prefix is also accepted.
|
|
165
|
+
|
|
166
|
+
### Keeping a foreground instance running
|
|
167
|
+
|
|
168
|
+
You can return to the prompt to run an upgrade, then reconnect to the same
|
|
169
|
+
instance:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
plonex[myproject]> instance debug
|
|
173
|
+
... instance starts; press Ctrl-Z ...
|
|
174
|
+
plonex[myproject]> db upgrade
|
|
175
|
+
plonex[myproject]> fg
|
|
176
|
+
... back to the same instance and its live output ...
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The shell keeps detached commands running and records their output under
|
|
180
|
+
`var/log/shell/` (or your configured `var_folder`). Background logs do not print
|
|
181
|
+
over the prompt. On reconnect, the shell shows up to 64 KiB of output you missed,
|
|
182
|
+
then streams live output. Full logs remain on disk.
|
|
183
|
+
|
|
184
|
+
- `jobs`: show a Markdown-style table of job IDs, service names, coloured states,
|
|
185
|
+
process IDs, commands, and log locations. Running jobs are green, successful
|
|
186
|
+
exits cyan, failures red, and signal exits yellow. Terminal colour settings,
|
|
187
|
+
including `NO_COLOR`, are respected.
|
|
188
|
+
- `jobs --markdown`: export a plain Markdown table without ANSI colour codes.
|
|
189
|
+
- `fg` or `attach`: reconnect to the most recent running job.
|
|
190
|
+
- `fg %1` or `attach %1`: reconnect to a specific job.
|
|
191
|
+
- `logs %1`: show that job's latest output without reconnecting.
|
|
192
|
+
- `options %1`: inspect the resolved service options captured when that job started.
|
|
193
|
+
- `bg %1`: leave or resume a job in the background.
|
|
194
|
+
- `kill %1`: stop the job and its foreground process group.
|
|
195
|
+
- `instance debug &`: start an instance directly in the background. A trailing, unquoted
|
|
196
|
+
`&` preceded by a space works with other plonex commands too.
|
|
197
|
+
|
|
198
|
+
Job IDs also accept plain numbers. Commands that take a job ID default to the
|
|
199
|
+
most recent running job. `instance debug --port 8081` starts another instance.
|
|
200
|
+
Ctrl-C while attached stops the foreground command; Ctrl-Z detaches it.
|
|
201
|
+
Exiting the shell stops jobs it owns, including detached instances. Job control
|
|
202
|
+
requires an interactive terminal; piped shell commands retain their usual behavior.
|
|
203
|
+
|
|
204
|
+
### Inspecting service and job options
|
|
205
|
+
|
|
206
|
+
Preview a service using the same defaults, merged configuration, aliases, and
|
|
207
|
+
argument handling as normal execution:
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
plonex options instance debug --port 8081
|
|
211
|
+
plonex options instance start --name worker --config etc/worker.yml
|
|
212
|
+
plonex options test pytest my.package -k login
|
|
213
|
+
plonex options --markdown dependencies sync
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The report includes service constructor arguments, command flags, configuration
|
|
217
|
+
file locations, and resolved options, including nested environment settings.
|
|
218
|
+
The service is constructed but not entered or run: inspection does not launch
|
|
219
|
+
the service, install dependencies, or render runtime files. Existing constructors
|
|
220
|
+
may create directories, and normal configuration resolution still applies,
|
|
221
|
+
including fetching remote Git profiles when configured.
|
|
222
|
+
|
|
223
|
+
In the shell, use a job ID to see its **startup snapshot**, or a command to
|
|
224
|
+
preview **current configuration**:
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
plonex[myproject]> jobs
|
|
228
|
+
plonex[myproject]> options %1
|
|
229
|
+
plonex[myproject]> options %1 --markdown
|
|
230
|
+
plonex[myproject]> options instance debug --port 8082
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Job snapshots are captured by the service process before it exports environment
|
|
234
|
+
variables or runs helper services. They remain available after the job exits and
|
|
235
|
+
do not change when YAML files are edited. A snapshot may be unavailable while a
|
|
236
|
+
job is starting, or if it fails before entering its service. Help/version jobs
|
|
237
|
+
do not have service options.
|
|
238
|
+
|
|
239
|
+
Inspection masks conventional password, token, and secret keys, known credential
|
|
240
|
+
arguments, and passwords in URLs. Snapshots are stored with owner-only file
|
|
241
|
+
permissions next to job logs. Ordinary process output in log files is unchanged.
|
|
242
|
+
|
|
243
|
+
## Project aliases
|
|
244
|
+
|
|
245
|
+
Define shortcuts in `etc/plonex.yml`:
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
aliases:
|
|
249
|
+
start: supervisor start
|
|
250
|
+
stop: supervisor stop
|
|
251
|
+
test_whatever: pytest my.package
|
|
252
|
+
test_unit: [pytest, my.package, -k, "not integration"]
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Then run them as ordinary commands:
|
|
256
|
+
|
|
257
|
+
```sh
|
|
258
|
+
plonex start
|
|
259
|
+
plonex test_whatever -k login -x
|
|
260
|
+
plonex --target /path/to/project test_unit -q
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
An alias is one command, expressed as a quoted command string or a list of
|
|
264
|
+
argument tokens. Extra arguments are appended to its expansion. In the examples,
|
|
265
|
+
`test_whatever -k login -x` runs `pytest my.package -k login -x`. Values may
|
|
266
|
+
optionally start with `plonex`. Quotes preserve arguments containing spaces;
|
|
267
|
+
commands are not evaluated as shell code.
|
|
268
|
+
|
|
269
|
+
Aliases can refer to other aliases, but loops produce an error. Built-in command
|
|
270
|
+
names and shell commands such as `help`, `history`, `exit`, `jobs`, and `attach` cannot be replaced.
|
|
271
|
+
Aliases appear in project help and Tab completion, work in `plonex shell`, and can
|
|
272
|
+
be used by `default_action` or `default_actions`. Edits take effect on the next
|
|
273
|
+
shell command or completion.
|
|
274
|
+
|
|
275
|
+
Aliases use the same profile and local configuration precedence as other
|
|
276
|
+
options. To extend or override individual aliases inherited from a profile, use
|
|
277
|
+
the existing `+` mapping syntax:
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
+aliases:
|
|
281
|
+
test_whatever: pytest my.other_package
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Global options
|
|
285
|
+
|
|
286
|
+
All commands accept these options:
|
|
287
|
+
|
|
288
|
+
```text
|
|
289
|
+
plonex [--target PATH] [--verbose] [--quiet] [--version] <command> ...
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- `-t, --target`: target project folder (defaults to current directory).
|
|
293
|
+
- `-v, --verbose`: set log level to `DEBUG`.
|
|
294
|
+
- `-q, --quiet`: reduce log output (`WARNING` and above).
|
|
295
|
+
- `-V, --version`: print installed plonex version.
|
|
296
|
+
|
|
297
|
+
For all commands except `init`, `plonex` resolves the target by walking upward until it finds `etc/plonex.yml`.
|
|
298
|
+
|
|
299
|
+
If you run `plonex` without a command, it displays the help message unless a
|
|
300
|
+
default action is configured in `etc/plonex.yml`.
|
|
301
|
+
|
|
302
|
+
## How to think about plonex
|
|
303
|
+
|
|
304
|
+
`plonex` separates intent from implementation.
|
|
305
|
+
You declare intent with simple commands such as `plonex instance start` or
|
|
306
|
+
`plonex db pack`, and `plonex` translates that into the correct low-level command,
|
|
307
|
+
with the correct paths, environment variables, and generated configuration files.
|
|
308
|
+
|
|
309
|
+
This approach has a few practical benefits:
|
|
310
|
+
|
|
311
|
+
- You do not need to remember long binary paths or many flags.
|
|
312
|
+
- Team members can share the same commands while keeping local overrides in YAML.
|
|
313
|
+
- Automation in CI can reuse exactly the same command set used locally.
|
|
314
|
+
|
|
315
|
+
In other words, `plonex` behaves like an orchestration layer over project runtime
|
|
316
|
+
tools, while still letting you control details through configuration.
|
|
317
|
+
|
|
318
|
+
You can still see what happens when you run a command passing the `-v/--verbose` flag or setting `log_level: debug` in YAML.
|
|
319
|
+
This is useful for troubleshooting and understanding the underlying behavior.
|
|
320
|
+
|
|
321
|
+
## Default actions
|
|
322
|
+
|
|
323
|
+
You can configure what happens when you run `plonex` with no explicit command.
|
|
324
|
+
|
|
325
|
+
By default, `plonex` shows the command help.
|
|
326
|
+
|
|
327
|
+
If you want a different behavior, set either `default_action` or
|
|
328
|
+
`default_actions` in `etc/plonex.yml`.
|
|
329
|
+
|
|
330
|
+
For example, to ensure supervisor is started and then run WSGI client is run in the foreground, you can set:
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
default_actions:
|
|
334
|
+
- supervisor start
|
|
335
|
+
- supervisor status
|
|
336
|
+
- instance debug
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Profiles
|
|
340
|
+
|
|
341
|
+
You can extend a project from one or more profiles declared in `etc/plonex.yml`.
|
|
342
|
+
|
|
343
|
+
Example:
|
|
344
|
+
|
|
345
|
+
```yaml
|
|
346
|
+
profiles:
|
|
347
|
+
- /path/to/plonex-profile
|
|
348
|
+
- https://github.com/example/plonex-profile.git
|
|
349
|
+
|
|
350
|
+
http_port: 8081
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Profile configuration is loaded before the local project configuration, so the
|
|
354
|
+
local `etc/plonex.yml` remains the highest-precedence place for site-specific
|
|
355
|
+
overrides such as ports, hostnames, and service settings.
|
|
356
|
+
|
|
357
|
+
Profiles can themselves declare `profiles`, which allows a profile to extend
|
|
358
|
+
another profile before the local project overrides both.
|
|
359
|
+
|
|
360
|
+
Relative profile paths in the project `etc/plonex.yml` are resolved from the
|
|
361
|
+
project root. Relative profile paths declared inside a profile are resolved from
|
|
362
|
+
that profile root.
|
|
363
|
+
|
|
364
|
+
One practical way to organize profiles inside a repository is:
|
|
365
|
+
|
|
366
|
+
```text
|
|
367
|
+
myproject/
|
|
368
|
+
├── etc/
|
|
369
|
+
│ └── plonex.yml
|
|
370
|
+
└── profiles/
|
|
371
|
+
├── default/
|
|
372
|
+
│ └── etc/
|
|
373
|
+
│ └── plonex.yml
|
|
374
|
+
├── production/
|
|
375
|
+
│ └── etc/
|
|
376
|
+
│ └── plonex.yml
|
|
377
|
+
└── development/
|
|
378
|
+
└── etc/
|
|
379
|
+
└── plonex.yml
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
For example, `profiles/default/etc/plonex.yml` can hold shared defaults used by
|
|
383
|
+
every environment:
|
|
384
|
+
|
|
385
|
+
```yaml
|
|
386
|
+
plone_version: 6.2.0
|
|
387
|
+
http_address: 0.0.0.0
|
|
388
|
+
zeo_address: var/zeo.sock
|
|
389
|
+
environment_vars:
|
|
390
|
+
TZ: Europe/Rome
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Then `profiles/production/etc/plonex.yml` can extend `default` and add
|
|
394
|
+
production-specific values:
|
|
395
|
+
|
|
396
|
+
```yaml
|
|
397
|
+
profiles:
|
|
398
|
+
- ../default
|
|
399
|
+
|
|
400
|
+
http_port: 8080
|
|
401
|
+
debug_mode: false
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
And `profiles/development/etc/plonex.yml` can also extend `default` but keep
|
|
405
|
+
more developer-friendly settings:
|
|
406
|
+
|
|
407
|
+
```yaml
|
|
408
|
+
profiles:
|
|
409
|
+
- ../default
|
|
410
|
+
|
|
411
|
+
http_port: 8081
|
|
412
|
+
debug_mode: true
|
|
413
|
+
log_level: debug
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Finally, the project `etc/plonex.yml` chooses which profile to inherit from and
|
|
417
|
+
keeps the final local overrides:
|
|
418
|
+
|
|
419
|
+
```yaml
|
|
420
|
+
profiles:
|
|
421
|
+
- profiles/development
|
|
422
|
+
|
|
423
|
+
http_port: 8082
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
In this example the resulting `http_port` is `8082`, because the local
|
|
427
|
+
`etc/plonex.yml` overrides `profiles/development`, which overrides
|
|
428
|
+
`profiles/default`.
|
|
429
|
+
|
|
430
|
+
## Base Constraints
|
|
431
|
+
|
|
432
|
+
`plonex` generates a merged `var/constraints.txt` for installation.
|
|
433
|
+
|
|
434
|
+
By default it starts from the Plone release constraints selected by
|
|
435
|
+
`plone_version`. The generated `etc/plonex.yml` does not include a
|
|
436
|
+
`plonex_base_constraint` entry unless you decide to add one.
|
|
437
|
+
|
|
438
|
+
Default behavior:
|
|
439
|
+
|
|
440
|
+
```yaml
|
|
441
|
+
plone_version: 6.2.0
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
This means the base constraint is effectively:
|
|
445
|
+
|
|
446
|
+
```yaml
|
|
447
|
+
https://dist.plone.org/release/{{ plone_version }}/constraints.txt
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
If you want to override that base, add
|
|
451
|
+
`plonex_base_constraint`.
|
|
452
|
+
|
|
453
|
+
Supported values are:
|
|
454
|
+
|
|
455
|
+
- remote URLs
|
|
456
|
+
- local files relative to the project root
|
|
457
|
+
- `resource://package:path` references
|
|
458
|
+
|
|
459
|
+
Examples:
|
|
460
|
+
|
|
461
|
+
```yaml
|
|
462
|
+
plonex_base_constraint: https://example.org/constraints/base.txt
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
```yaml
|
|
466
|
+
plonex_base_constraint: etc/constraints/base.txt
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
```yaml
|
|
470
|
+
plonex_base_constraint: resource://my.package:constraints/base.txt
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Use a plain URL in YAML, without Markdown link syntax. For GitHub files, copy the
|
|
474
|
+
**Raw** URL from `raw.githubusercontent.com`, rather than the `/blob/` page URL.
|
|
475
|
+
Remote constraints, including nested `-c` and `-r` references, are merged into
|
|
476
|
+
`var/constraints.txt`. Local pins override remote pins, and packages installed in
|
|
477
|
+
editable mode are excluded. HTML responses and invalid remote requirements cause
|
|
478
|
+
a warning and stop generation, preserving the previous constraints file.
|
|
479
|
+
|
|
480
|
+
Generated package names use lowercase and replace runs of dots, underscores, or
|
|
481
|
+
hyphens with a single hyphen: `zope.sendmail==7.2` becomes
|
|
482
|
+
`zope-sendmail==7.2`. This also applies to suggested and saved pins, added packages,
|
|
483
|
+
and direct `pip_requirements`. Versions, environment markers, paths, and URLs keep
|
|
484
|
+
their original spelling.
|
|
485
|
+
|
|
486
|
+
> [!NOTE]
|
|
487
|
+
> If an old `etc/constraints.d/000-plonex.txt` file still exists, `plonex` warns
|
|
488
|
+
> that it is ignored and suggests removing it. For compatibility, if neither
|
|
489
|
+
> `plone_version` nor `plonex_base_constraint` is configured, `plonex` still tries
|
|
490
|
+
> to infer `plone_version` from that legacy file.
|
|
491
|
+
|
|
492
|
+
Single action examples:
|
|
493
|
+
|
|
494
|
+
```yaml
|
|
495
|
+
default_action: project describe
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
```yaml
|
|
499
|
+
default_action: instance start
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Equivalent list form:
|
|
503
|
+
|
|
504
|
+
```yaml
|
|
505
|
+
default_action:
|
|
506
|
+
- instance start
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
If you want to run multiple commands in sequence, use `default_actions`:
|
|
510
|
+
|
|
511
|
+
```yaml
|
|
512
|
+
default_actions:
|
|
513
|
+
- supervisor start
|
|
514
|
+
- instance start
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
This is useful when you want plain `plonex` to bootstrap a common local
|
|
518
|
+
workflow, for example starting Supervisor first and then bringing up the client.
|
|
519
|
+
|
|
520
|
+
Notes:
|
|
521
|
+
|
|
522
|
+
- `default_actions` runs in order.
|
|
523
|
+
- each action can be written as a shell-like string or a list of tokens.
|
|
524
|
+
- command-line global options such as `-v` and `-q` still apply.
|
|
525
|
+
|
|
526
|
+
## Development FAQ
|
|
527
|
+
|
|
528
|
+
### How do I start a new project?
|
|
529
|
+
|
|
530
|
+
```sh
|
|
531
|
+
plonex project init myproject
|
|
532
|
+
cd myproject
|
|
533
|
+
plonex supervisor start
|
|
534
|
+
plonex supervisor status
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Supervisor starts the generated ZEO and WSGI programs in the background. For
|
|
538
|
+
interactive development, the shell workflow below gives direct debugger input.
|
|
539
|
+
|
|
540
|
+
### How do I run Plone with a debugger and still run commands?
|
|
541
|
+
|
|
542
|
+
```text
|
|
543
|
+
plonex shell
|
|
544
|
+
plonex[myproject]> db start &
|
|
545
|
+
plonex[myproject]> instance debug
|
|
546
|
+
... press Ctrl-Z to return to the prompt ...
|
|
547
|
+
plonex[myproject]> options %2
|
|
548
|
+
plonex[myproject]> db upgrade
|
|
549
|
+
plonex[myproject]> fg %2
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Ctrl-Z detaches without stopping the server. `jobs` lists the actual IDs;
|
|
553
|
+
`logs %2` reads output and `kill %2` stops that job. `fg` only reattaches jobs;
|
|
554
|
+
start new instances with `instance debug`. Exiting the shell stops its jobs.
|
|
555
|
+
Use an already-running ZEO server instead of starting a second one when your
|
|
556
|
+
project is configured with a shared database.
|
|
557
|
+
|
|
558
|
+
### How do I develop an add-on from a checkout?
|
|
559
|
+
|
|
560
|
+
Declare its repository and editable installation together:
|
|
561
|
+
|
|
562
|
+
```yaml
|
|
563
|
+
sources:
|
|
564
|
+
my.addon:
|
|
565
|
+
repo: git@github.com:example/my.addon.git
|
|
566
|
+
rev: main
|
|
567
|
+
install: true
|
|
568
|
+
extras: [test]
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
```sh
|
|
572
|
+
plonex sources clone
|
|
573
|
+
plonex dependencies install
|
|
574
|
+
plonex sources list
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Editable installs use the checkout directly. A monorepo can add `subdirectory`;
|
|
578
|
+
`path` selects a custom checkout folder. Remove corresponding manual `-e` entries
|
|
579
|
+
when migrating. Distribution names such as `my-addon` are canonicalized, while
|
|
580
|
+
Python import names such as `my.addon` retain their dots.
|
|
581
|
+
|
|
582
|
+
### Why do Python changes not appear in the application?
|
|
583
|
+
|
|
584
|
+
Check both the declaration and actual installation:
|
|
585
|
+
|
|
586
|
+
```sh
|
|
587
|
+
plonex project describe sources
|
|
588
|
+
plonex project describe dependencies
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
The source should have `install: true`, and its installed metadata should identify
|
|
592
|
+
the expected checkout as editable. A running process can still hold imported
|
|
593
|
+
Python modules; restart the instance after code changes when required. Dependency,
|
|
594
|
+
extra, or packaging changes need another `dependencies install`. An ordinary
|
|
595
|
+
`editable: false` installation contains built code rather than live source files.
|
|
596
|
+
|
|
597
|
+
### How do I update dependencies and remove obsolete packages?
|
|
598
|
+
|
|
599
|
+
```sh
|
|
600
|
+
plonex sources update
|
|
601
|
+
plonex dependencies install
|
|
602
|
+
plonex dependencies sync
|
|
603
|
+
plonex dependencies outdated
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
`install` preserves unrelated installed packages. `sync` resolves the declared
|
|
607
|
+
requirements and removes packages outside that environment. To combine checkout
|
|
608
|
+
updates with installation, use `dependencies install --update-sources`.
|
|
609
|
+
Output reports actual changes; an unchanged run prints `No package changes.`
|
|
610
|
+
|
|
611
|
+
### Where should additional requirements and pins go?
|
|
612
|
+
|
|
613
|
+
Use `pip_requirements` or `etc/requirements.d/*.txt` for requirements and
|
|
614
|
+
`etc/constraints.d/*.txt` for pins. These can also come from profiles.
|
|
615
|
+
When constraint fragments in the same directory pin the same package, the first
|
|
616
|
+
filename in alphabetical order takes precedence. Project constraints take
|
|
617
|
+
precedence over profile constraints.
|
|
618
|
+
`dependencies add 'my-addon[test]'` records a requirement and installs it.
|
|
619
|
+
Save missing pins with `dependencies install --persist-local`; the local pin file
|
|
620
|
+
stays separate from shared constraints. Use a raw text URL for
|
|
621
|
+
`plonex_base_constraint`, rather than a GitHub `/blob/` HTML page.
|
|
622
|
+
|
|
623
|
+
### Which file set this option, and why did it change?
|
|
624
|
+
|
|
625
|
+
```sh
|
|
626
|
+
plonex project describe configuration --key http_port
|
|
627
|
+
plonex project describe configuration --key http_port instance debug --port 8081
|
|
628
|
+
plonex project describe analytics instance debug
|
|
629
|
+
plonex project describe profiles
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
The configuration report includes the complete compiled YAML, resolved values,
|
|
633
|
+
winning definitions, earlier values, and Jinja references. In the HTML report,
|
|
634
|
+
select a YAML key to open its definition history and links to the source files.
|
|
635
|
+
Without a command, the YAML uses the same configuration as `project compile`;
|
|
636
|
+
adding a command shows that command's defaults, service-specific files, extra
|
|
637
|
+
files, and CLI overrides. Analytics shows override chains and configuration
|
|
638
|
+
dependencies. Sensitive fields and derived secrets are redacted in every format.
|
|
639
|
+
Use `--format json` for automation.
|
|
640
|
+
|
|
641
|
+
### How do I keep personal settings out of a shared profile?
|
|
642
|
+
|
|
643
|
+
Put machine-specific overrides in `etc/plonex.local.yml`. Mappings and lists
|
|
644
|
+
normally replace earlier values. `+sources` adds or replaces complete source
|
|
645
|
+
entries, and `+pip_requirements` appends requirements. A source entry is itself
|
|
646
|
+
replaced, so include its repository and other settings when overriding it.
|
|
647
|
+
Use `project describe configuration --key sources` to inspect the result.
|
|
648
|
+
|
|
649
|
+
### How do I open a useful project report?
|
|
650
|
+
|
|
651
|
+
```sh
|
|
652
|
+
plonex project describe --format html --browse
|
|
653
|
+
plonex project describe runtime --browse
|
|
654
|
+
plonex project describe jobs --browse
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
The complete report is `var/plonex_description/index.html`. It has responsive
|
|
658
|
+
layout, section navigation, search, file links, and definition history. Markdown
|
|
659
|
+
and JSON exports sit alongside it. Focused reports use their section name and
|
|
660
|
+
preserve the complete report. Existing file paths in the HTML report are clickable,
|
|
661
|
+
including configuration history. Open the report on the project host: browsers may
|
|
662
|
+
block local file links from a web server, and they decide whether to display or
|
|
663
|
+
download each file. Inspection does not install, compile, export the configured
|
|
664
|
+
environment, or start application services.
|
|
665
|
+
|
|
666
|
+
### Why is my project not working as expected?
|
|
667
|
+
|
|
668
|
+
```sh
|
|
669
|
+
plonex project doctor
|
|
670
|
+
plonex project doctor --format json
|
|
671
|
+
plonex supervisor start --plan
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
The doctor reports configuration, virtualenv, source installation, constraint,
|
|
675
|
+
preparation, and local service problems with suggested next steps. It does not
|
|
676
|
+
install packages or change the project. Use `--strict` to make warnings fail a CI
|
|
677
|
+
check. See the [doctor reference](docs/cli.md#project-doctor) for its scope and
|
|
678
|
+
limitations.
|
|
679
|
+
|
|
680
|
+
### How do I compare or recreate an environment?
|
|
681
|
+
|
|
682
|
+
```sh
|
|
683
|
+
plonex project snapshot create --output deployment.json
|
|
684
|
+
plonex project snapshot compare deployment.json
|
|
685
|
+
plonex project snapshot prepare deployment.json --to /path/to/new-venv
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
Snapshots capture installed versions, source revisions, and dependency inputs.
|
|
689
|
+
Preparation verifies supported inputs before creating a separate environment.
|
|
690
|
+
See [project snapshots](docs/snapshots.md) for limitations and reproducibility.
|
|
691
|
+
|
|
692
|
+
### Can I inspect an existing mxdev or Buildout project?
|
|
693
|
+
|
|
694
|
+
Run `plonex --target /path/to/project project inspect-legacy`. The report reads
|
|
695
|
+
local configuration without running recipes or modifying the project. The
|
|
696
|
+
[migration guide](docs/migration.md) covers Buildout and mxdev projects, including
|
|
697
|
+
how to keep mxdev in charge of its generated files during a transition.
|
|
698
|
+
|
|
699
|
+
### How do I run tests and stop in a failing test?
|
|
700
|
+
|
|
701
|
+
```sh
|
|
702
|
+
plonex dependencies add pytest
|
|
703
|
+
plonex test pytest my.addon -k login -x --pdb
|
|
704
|
+
plonex test zope my.addon -t Login
|
|
705
|
+
plonex test robot tests/robot/login.robot --browser firefox
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Install the add-on's testing extras and the runner it needs. Use Python import
|
|
709
|
+
names for package-based tests. Arguments after the package in `test pytest`
|
|
710
|
+
go to pytest, including `-k`, `-x`, and `--pdb`. The shell preserves terminal input
|
|
711
|
+
for interactive debugging.
|
|
712
|
+
|
|
713
|
+
### How do I run a script or inspect the ZODB?
|
|
714
|
+
|
|
715
|
+
```sh
|
|
716
|
+
plonex instance run -- scripts/maintenance.py --argument value
|
|
717
|
+
plonex instance console
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
The console provides `app`. To establish a Plone site context:
|
|
721
|
+
|
|
722
|
+
```python
|
|
723
|
+
from Testing.makerequest import makerequest
|
|
724
|
+
from zope.component.hooks import setSite
|
|
725
|
+
from zope.globalrequest import setRequest
|
|
726
|
+
|
|
727
|
+
app = makerequest(app)
|
|
728
|
+
setRequest(app.REQUEST)
|
|
729
|
+
site = app["Plone"]
|
|
730
|
+
setSite(site)
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
Use `plone.api.env.adopt_user(username="your-user")` for an explicit application
|
|
734
|
+
user context when needed. Commit intended database changes with
|
|
735
|
+
`transaction.commit()`; abort discarded changes with `transaction.abort()`.
|
|
736
|
+
See [Plone's console documentation](https://6.docs.plone.org/admin-guide/run-plone.html#run-a-debug-console).
|
|
737
|
+
|
|
738
|
+
### How do I run upgrade steps?
|
|
739
|
+
|
|
740
|
+
Run `plonex db upgrade` with the ZEO server running. Install and enable
|
|
741
|
+
`collective.ftw.upgrade` in the target project and site. Plonex starts a temporary
|
|
742
|
+
local instance with private authentication, runs the upgrade, and stops it. Output
|
|
743
|
+
is recorded in `var/log/upgrade.logs`.
|
|
744
|
+
|
|
745
|
+
To use an already running instance instead, pass
|
|
746
|
+
`--url http://127.0.0.1:8081/` and configure its upgrade authentication. Review
|
|
747
|
+
and back up the database before planned deployment upgrades.
|
|
748
|
+
|
|
749
|
+
### Why does Supervisor startup prepare dependencies and templates?
|
|
750
|
+
|
|
751
|
+
`plonex supervisor start` ensures that declared dependencies and generated runtime
|
|
752
|
+
files are current before starting Supervisor. It skips unchanged work. Requirement
|
|
753
|
+
and constraint changes trigger installation checks; changing an HTTP port only
|
|
754
|
+
regenerates affected runtime files.
|
|
755
|
+
|
|
756
|
+
```sh
|
|
757
|
+
plonex supervisor start --plan
|
|
758
|
+
plonex project describe preparation
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
The plan explains stale tasks and their prerequisites without executing them.
|
|
762
|
+
Preparation never implicitly updates Git sources, removes unused packages, runs
|
|
763
|
+
Plone upgrades, or restarts existing instances. Use `dependencies sync` for package
|
|
764
|
+
removal and explicit Supervisor commands to apply changes to running services.
|
|
765
|
+
See [incremental preparation](docs/preparation.md) for caching, failures, and
|
|
766
|
+
remote profile behavior.
|
|
767
|
+
|
|
768
|
+
### How do I apply Supervisor configuration changes?
|
|
769
|
+
|
|
770
|
+
```sh
|
|
771
|
+
plonex supervisor reread
|
|
772
|
+
plonex supervisor update
|
|
773
|
+
plonex supervisor status
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
`update` applies changed program declarations. `restart` restarts all managed
|
|
777
|
+
programs; `graceful --interval 2` restarts them sequentially. Neither should be
|
|
778
|
+
confused with editing the currently running process's configuration in memory.
|
|
779
|
+
`options %JOB` reports a shell job's startup snapshot even after YAML changes.
|
|
780
|
+
|
|
781
|
+
### How can I schedule work without a curl password or a CSRF exemption?
|
|
782
|
+
|
|
783
|
+
```yaml
|
|
784
|
+
cron_timezone: Europe/Rome
|
|
785
|
+
cron_jobs:
|
|
786
|
+
StoreSessionStats:
|
|
787
|
+
schedule: "15 2 * * *"
|
|
788
|
+
callable: my.addon.jobs:store_session_stats
|
|
789
|
+
site: /Plone
|
|
790
|
+
context: sectors
|
|
791
|
+
user: scheduler
|
|
792
|
+
timeout: 900
|
|
793
|
+
lock: zope
|
|
794
|
+
lock_timeout: 300
|
|
795
|
+
enabled: false
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
Move the business logic into the callable, installed in the project virtualenv.
|
|
799
|
+
Create the named Plone user with the roles it needs; no password belongs in this
|
|
800
|
+
job declaration. Test with `cron run StoreSessionStats`, inspect `cron logs` and
|
|
801
|
+
`cron history`, then enable the schedule and apply Supervisor configuration.
|
|
802
|
+
|
|
803
|
+
Plonex installs the job runtime and Huey into the target virtualenv
|
|
804
|
+
when jobs are configured. Supervisor launches
|
|
805
|
+
the target interpreter directly. Manual-only job declarations still keep a worker
|
|
806
|
+
for explicitly queued tasks.
|
|
807
|
+
|
|
808
|
+
A protected browser view can call the same function after POST and authenticator
|
|
809
|
+
checks. The job runs through a dedicated ZEO client and owns its transaction;
|
|
810
|
+
it does not invoke the browser view or disable CSRF. See the
|
|
811
|
+
[complete scheduled-job guide](docs/jobs.md), including a protected view example.
|
|
812
|
+
|
|
813
|
+
### How do I check scheduling times, failures, and overlap?
|
|
814
|
+
|
|
815
|
+
```sh
|
|
816
|
+
plonex cron list
|
|
817
|
+
plonex cron status
|
|
818
|
+
plonex cron queue
|
|
819
|
+
plonex cron history StoreSessionStats
|
|
820
|
+
plonex cron logs StoreSessionStats --tail 100
|
|
821
|
+
plonex project describe jobs --browse
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
Schedules use explicit IANA timezones, defaulting to UTC. Common lock names
|
|
825
|
+
serialize related jobs; manual and daemon runs share those locks. Timeouts stop
|
|
826
|
+
the job subprocess group and record the outcome. Retries default to zero; enable
|
|
827
|
+
them only for work that tolerates repeating after a failure. The queue survives
|
|
828
|
+
restarts, but missed periodic schedules are not replayed.
|
|
829
|
+
|
|
830
|
+
### How do I inspect or retry queued work?
|
|
831
|
+
|
|
832
|
+
```sh
|
|
833
|
+
plonex cron status
|
|
834
|
+
plonex cron queue
|
|
835
|
+
plonex cron inspect TASK_ID
|
|
836
|
+
plonex cron retry TASK_ID
|
|
837
|
+
plonex cron revoke TASK_ID
|
|
838
|
+
plonex project describe queue
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
Monitoring uses Huey's statistics extension in the target environment. Task IDs
|
|
842
|
+
link events to individual attempts and logs. `retry` creates a new task using the
|
|
843
|
+
current definition; `revoke` prevents a queued execution and does not kill a
|
|
844
|
+
running process. Add `--format json` for complete task IDs and structured output.
|
|
845
|
+
See the [queue guide](docs/jobs.md#queue-monitoring-and-controls).
|
|
846
|
+
|
|
847
|
+
### What changed in the command names?
|
|
848
|
+
|
|
849
|
+
There are no built-in synonyms such as both `--sync` and `sync`. Use
|
|
850
|
+
`dependencies sync`, `dependencies outdated`, `instance debug`, and
|
|
851
|
+
`project describe`. Update aliases, default command lists, deployment scripts,
|
|
852
|
+
and Supervisor `command` values from older projects. Configuration identities
|
|
853
|
+
such as `run_for: fg` and `etc/plonex-runwsgi.yml` retain their meaning.
|
|
854
|
+
The [CLI migration table](docs/cli.md#breaking-migration) lists every removed form.
|
|
855
|
+
|
|
856
|
+
## Typical workflows
|
|
857
|
+
|
|
858
|
+
### Local development
|
|
859
|
+
|
|
860
|
+
```sh
|
|
861
|
+
plonex project init .
|
|
862
|
+
plonex supervisor start
|
|
863
|
+
plonex shell
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
What happens:
|
|
867
|
+
|
|
868
|
+
- `init` creates project skeleton and base config.
|
|
869
|
+
- `init` creates `.venv` and installs the configured dependencies.
|
|
870
|
+
- `supervisor start` starts the configured ZEO and WSGI services in the background.
|
|
871
|
+
- `shell` opens a prompt for project commands. Use `supervisor status` there to
|
|
872
|
+
check managed services. `jobs` lists processes launched by the current shell;
|
|
873
|
+
Supervisor services are managed separately.
|
|
874
|
+
|
|
875
|
+
### Running maintenance tasks
|
|
876
|
+
|
|
877
|
+
```sh
|
|
878
|
+
plonex db pack --days N
|
|
879
|
+
plonex db backup
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
What happens:
|
|
883
|
+
|
|
884
|
+
- `db pack` reads `zeo_address` from merged options and calls `zeopack`.
|
|
885
|
+
- `db backup` runs `repozo` against the project Data.fs location.
|
|
886
|
+
|
|
887
|
+
### Working with supervisor
|
|
888
|
+
|
|
889
|
+
```sh
|
|
890
|
+
plonex supervisor start
|
|
891
|
+
plonex supervisor status
|
|
892
|
+
plonex supervisor restart
|
|
893
|
+
plonex supervisor graceful --interval 2.0
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
What happens:
|
|
897
|
+
|
|
898
|
+
- `plonex` generates `tmp/supervisor/etc/supervisord.conf` and service templates if needed.
|
|
899
|
+
- it runs `supervisord` and `supervisorctl` from your project virtualenv.
|
|
900
|
+
- `plonex supervisor graceful` restarts each configured service one by one in the
|
|
901
|
+
order reported by `supervisorctl status`.
|
|
902
|
+
- `--interval` controls the pause between service restarts. The default interval is `1` second.
|
|
903
|
+
|
|
904
|
+
You can also set the default interval in YAML:
|
|
905
|
+
|
|
906
|
+
```yaml
|
|
907
|
+
supervisor_graceful_interval: 10
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
Put that in `etc/plonex.yml` or another merged plonex config file.
|
|
911
|
+
The CLI flag
|
|
912
|
+
still wins over YAML when both are provided.
|
|
913
|
+
|
|
914
|
+
## Commands
|
|
915
|
+
|
|
916
|
+
### Setup and info
|
|
917
|
+
|
|
918
|
+
`shell [--target PATH]`
|
|
919
|
+
|
|
920
|
+
- Open the interactive project shell, including aliases, completion, job control,
|
|
921
|
+
logs, and startup option inspection. See [Interactive shell](#interactive-shell).
|
|
922
|
+
|
|
923
|
+
`options [--markdown] <command> [arguments ...]`
|
|
924
|
+
|
|
925
|
+
- Preview effective service arguments and options without running the service.
|
|
926
|
+
- In the interactive shell, `options [JOB]` inspects a recorded job snapshot;
|
|
927
|
+
omitting the job ID selects the most recent running job.
|
|
928
|
+
|
|
929
|
+
`project init [target]`
|
|
930
|
+
|
|
931
|
+
- Initialize project folders and base config.
|
|
932
|
+
- If `target` is omitted, `plonex` prompts for a folder and suggests the current directory as the default.
|
|
933
|
+
|
|
934
|
+
`project compile`
|
|
935
|
+
|
|
936
|
+
- Compile merged configuration into `var/plonex.yml`.
|
|
937
|
+
- If `sources` is configured, compile also generates `var/gitman.yml`.
|
|
938
|
+
- The default checkout location is `src` when `sources_location` is omitted.
|
|
939
|
+
|
|
940
|
+
Example:
|
|
941
|
+
|
|
942
|
+
```yaml
|
|
943
|
+
sources:
|
|
944
|
+
my.package:
|
|
945
|
+
repo: https://github.com/example/my.package.git
|
|
946
|
+
rev: main
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
`project describe`
|
|
950
|
+
|
|
951
|
+
- Render a project description from current configuration.
|
|
952
|
+
- Always export responsive HTML, Markdown, and JSON under `var/plonex_description/`.
|
|
953
|
+
- Select a section: `overview`, `configuration`, `analytics`, `profiles`,
|
|
954
|
+
`environment`, `sources`, `dependencies`, `services`, `runtime`, `files`, `jobs`, or `preparation`.
|
|
955
|
+
- `--format terminal|markdown|html|json` controls stdout; `--browse` opens HTML.
|
|
956
|
+
- `configuration --key OPTION [COMMAND ...]` explains definitions and overrides.
|
|
957
|
+
- Inspection does not compile configuration, install packages, or start services.
|
|
958
|
+
|
|
959
|
+
`dependencies {install|sync|outdated} [options]`
|
|
960
|
+
|
|
961
|
+
- Install from merged requirements/constraints.
|
|
962
|
+
- `sync`: compile requirements/constraints and run `uv pip sync` using the compiled requirements file as positional input.
|
|
963
|
+
- `outdated`: run `uv pip list --outdated`. Use this explicit action instead of an installation flag.
|
|
964
|
+
- `-p, --persist`: save auto-detected missing constraints into the project's `etc/constraints.d/`.
|
|
965
|
+
- `--persist-local`: save auto-detected missing constraints into a local (git-ignored) `etc/constraints.d/999-autoinstalled.local.txt`.
|
|
966
|
+
- `--persist-profile`: save auto-detected missing constraints into the first configured profile's `etc/constraints.d/`.
|
|
967
|
+
- `--update-sources`: update sources before installing dependencies (uses Gitman under the hood).
|
|
968
|
+
|
|
969
|
+
Dependency installation prints only package changes and relevant diagnostics:
|
|
970
|
+
|
|
971
|
+
```text
|
|
972
|
+
Added my-package==1.0
|
|
973
|
+
Upgraded zope-sendmail: 7.2 → 7.3
|
|
974
|
+
Removed unused-package==2.0
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
An unchanged environment prints `No package changes.` Reinstalls, downgrades,
|
|
978
|
+
and source changes are reported as well. Use `--verbose` to see full uv output.
|
|
979
|
+
The internal package inventory used for checking pins is captured silently;
|
|
980
|
+
missing-pin suggestions and resolver/build failures remain visible.
|
|
981
|
+
|
|
982
|
+
To enable source updates by default in project configuration:
|
|
983
|
+
|
|
984
|
+
```yaml
|
|
985
|
+
sources_update_before_dependencies: true
|
|
986
|
+
sources:
|
|
987
|
+
my.package:
|
|
988
|
+
repo: https://github.com/example/my.package.git
|
|
989
|
+
rev: main
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
To install a checkout in the project virtualenv, set `install: true`. Installs
|
|
993
|
+
are editable by default, so Python code changes are available without reinstalling:
|
|
994
|
+
|
|
995
|
+
```yaml
|
|
996
|
+
sources:
|
|
997
|
+
ploneintranet:
|
|
998
|
+
repo: git@github.com:quaive/ploneintranet.git
|
|
999
|
+
rev: master
|
|
1000
|
+
install: true
|
|
1001
|
+
extras: [test]
|
|
1002
|
+
pas.plugins.oidc:
|
|
1003
|
+
repo: git@github.com:collective/pas.plugins.oidc.git
|
|
1004
|
+
install: true
|
|
1005
|
+
reference.package:
|
|
1006
|
+
repo: https://github.com/example/reference.package.git
|
|
1007
|
+
install: false
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
Run `plonex sources clone` followed by `plonex dependencies install`, or use
|
|
1011
|
+
`plonex dependencies install --update-sources` to update checkouts and install in one step.
|
|
1012
|
+
`plonex dependencies sync` also supports these selections. Source declarations
|
|
1013
|
+
without `install: true` remain checkout only. `sources list` shows each source's
|
|
1014
|
+
installation selection alongside checkout health; it does not inspect the virtualenv.
|
|
1015
|
+
|
|
1016
|
+
Each selected source also accepts:
|
|
1017
|
+
|
|
1018
|
+
- `extras: [test, debug]`: optional dependency extras, with canonical package naming.
|
|
1019
|
+
- `editable: false`: build and install the local project normally; rerun dependencies
|
|
1020
|
+
after changing its code.
|
|
1021
|
+
- `path: vendor/my-checkout`: override the checkout path, relative to the project
|
|
1022
|
+
(an absolute path is also supported). Otherwise use `sources_location`, default `src`.
|
|
1023
|
+
- `subdirectory: packages/backend`: install a Python project inside a repository.
|
|
1024
|
+
This must be a relative path within the checkout.
|
|
1025
|
+
|
|
1026
|
+
Package names come from static `pyproject.toml`, `setup.cfg`, or literal `setup.py`
|
|
1027
|
+
metadata, falling back to the project directory name. Selected packages are removed
|
|
1028
|
+
from both base and local constraints, so release pins cannot override the local
|
|
1029
|
+
checkout. Missing checkouts and directories without `pyproject.toml` or `setup.py`
|
|
1030
|
+
produce an actionable error before installation. Source updates regenerate the
|
|
1031
|
+
dependency files after reading the updated metadata.
|
|
1032
|
+
uv currently cannot resolve editable checkout paths containing `#` or `?`; move
|
|
1033
|
+
the checkout or use `editable: false` in that case.
|
|
1034
|
+
|
|
1035
|
+
Put machine-specific selections in `etc/plonex.local.yml`. Configuration uses the
|
|
1036
|
+
normal mapping replacement rules: if you override `sources`, include the entries
|
|
1037
|
+
you want to keep; `+sources` adds or replaces complete source entries. Remove old
|
|
1038
|
+
`-e src/...` entries from `pip_requirements` and `etc/requirements.d/` when migrating
|
|
1039
|
+
to source declarations, including their extras. Those requirement mechanisms remain
|
|
1040
|
+
supported. Disabling a source stops requesting it; use `dependencies sync` to
|
|
1041
|
+
remove it if nothing else requires it.
|
|
1042
|
+
|
|
1043
|
+
See [development next steps](docs/development.md) for proposed environment checks,
|
|
1044
|
+
test selection, and debugging improvements.
|
|
1045
|
+
|
|
1046
|
+
`dependencies add <package> [<package> ...]`
|
|
1047
|
+
|
|
1048
|
+
- Add one or more packages and run dependency installation.
|
|
1049
|
+
|
|
1050
|
+
`sources {list|clone|update|missing|tainted|suggest} [options]`
|
|
1051
|
+
|
|
1052
|
+
- Manage configured source checkouts (uses Gitman under the hood).
|
|
1053
|
+
- `update`: run a regular sources update (executed by Gitman).
|
|
1054
|
+
- `update --force`: run a forced update (`--force`), asking for confirmation by
|
|
1055
|
+
default.
|
|
1056
|
+
- `update --force --yes`: skip confirmation.
|
|
1057
|
+
- `tainted`: list checkouts with local changes.
|
|
1058
|
+
- `list`: show configured checkouts and whether each is clean, tainted, or missing.
|
|
1059
|
+
- `missing`: show configured checkouts that are not present on disk.
|
|
1060
|
+
- `clone`: clone missing configured checkouts (using `repo` and optional `rev`).
|
|
1061
|
+
- `clone --yes`: skip confirmation prompt before cloning.
|
|
1062
|
+
- `suggest`: inspect existing unmanaged checkouts and print a ready-to-paste
|
|
1063
|
+
YAML snippet for `etc/plonex.yml` with inferred `repo` and `rev`.
|
|
1064
|
+
- `suggest --apply`: write inferred entries into `etc/plonex.yml`.
|
|
1065
|
+
- `suggest --apply-local`: write inferred entries into
|
|
1066
|
+
`etc/plonex-sources.local.yml`.
|
|
1067
|
+
- `suggest --apply-profile`: write inferred entries into
|
|
1068
|
+
the `etc/plonex.yml` of the first configured profile.
|
|
1069
|
+
|
|
1070
|
+
When unmanaged existing checkouts are detected, `sources list` and `sources tainted`
|
|
1071
|
+
also print a suggested `sources` section to add into `etc/plonex.yml`.
|
|
1072
|
+
`sources list` includes unmanaged checkouts in the table, marked `unmanaged` with
|
|
1073
|
+
their branch, repository, and checkout health. The highlighted YAML suggestion
|
|
1074
|
+
appears in a separate panel. Name filters apply to both rows and suggestions;
|
|
1075
|
+
Git inspection output stays inside the report.
|
|
1076
|
+
|
|
1077
|
+
`db upgrade`
|
|
1078
|
+
|
|
1079
|
+
- Run Plone upgrade steps.
|
|
1080
|
+
|
|
1081
|
+
### Configuration editing
|
|
1082
|
+
|
|
1083
|
+
There is a dedicated `plonex project edit` command to help you edit the configuration files for your `plonex` project.
|
|
1084
|
+
Use the arrow keys to move through the file picker, Enter to open the highlighted
|
|
1085
|
+
file, or `q` to cancel. With non-interactive input, enter one file number. Use
|
|
1086
|
+
`--all` to open each discovered file in a separate editor invocation, one after
|
|
1087
|
+
another. Editors that return immediately may leave multiple windows open.
|
|
1088
|
+
The selected editor:
|
|
1089
|
+
|
|
1090
|
+
1. with the `--editor` option in the command line
|
|
1091
|
+
1. with the `editor` option if specified in the `etc/plonex.yml` configuration file
|
|
1092
|
+
1. can be configured with the `EDITOR` environment variable
|
|
1093
|
+
1. use the `open` command as a fallback if none of the above is specified.
|
|
1094
|
+
|
|
1095
|
+
You can of course edit the configuration files manually, but `plonex project edit` helps you discover and open them quickly.
|
|
1096
|
+
|
|
1097
|
+
### Runtime
|
|
1098
|
+
|
|
1099
|
+
`db start`
|
|
1100
|
+
|
|
1101
|
+
- Start ZEO server.
|
|
1102
|
+
|
|
1103
|
+
`instance start [options] [args ...]`
|
|
1104
|
+
|
|
1105
|
+
- Options:
|
|
1106
|
+
- `-n, --name`: service name (default: `runwsgi`)
|
|
1107
|
+
- `-c, --config`: extra config file (repeatable)
|
|
1108
|
+
- `-p, --port`: HTTP port
|
|
1109
|
+
- `--host`: HTTP host
|
|
1110
|
+
|
|
1111
|
+
`instance console [options]`
|
|
1112
|
+
|
|
1113
|
+
- Options:
|
|
1114
|
+
- `-n, --name`: service name (default: `zconsole`)
|
|
1115
|
+
- `-c, --config`: extra config file (repeatable)
|
|
1116
|
+
- `-p, --port`: HTTP port
|
|
1117
|
+
- `--host`: HTTP host
|
|
1118
|
+
- Open an interactive Zope console. Use `instance run` for scripts.
|
|
1119
|
+
|
|
1120
|
+
`instance run [args ...]`
|
|
1121
|
+
|
|
1122
|
+
- Run a script through `zconsole run` with generated runtime config.
|
|
1123
|
+
|
|
1124
|
+
`instance add-user [-c FILE] <username> [password]`
|
|
1125
|
+
|
|
1126
|
+
- Create a Zope user (password can be omitted to auto-generate one).
|
|
1127
|
+
|
|
1128
|
+
`supervisor {status|start|stop|restart|graceful|reread|update}`
|
|
1129
|
+
|
|
1130
|
+
- Manage supervisord for project services.
|
|
1131
|
+
- `graceful` accepts `--interval SECONDS` and falls back to
|
|
1132
|
+
`supervisor_graceful_interval` from YAML, defaulting to `1.0`.
|
|
1133
|
+
- `reread` detects changed program declarations; `update` applies them.
|
|
1134
|
+
- `restart PROGRAM ...` restarts selected programs; omit names to restart all.
|
|
1135
|
+
|
|
1136
|
+
### Database
|
|
1137
|
+
|
|
1138
|
+
`db backup`
|
|
1139
|
+
|
|
1140
|
+
- Create a verified offline snapshot of FileStorage and blob storage.
|
|
1141
|
+
|
|
1142
|
+
`db pack [--days DAYS]`
|
|
1143
|
+
|
|
1144
|
+
- Pack ZODB revisions older than `DAYS` (default: `7`).
|
|
1145
|
+
- Uses merged `zeo_address` from your config files.
|
|
1146
|
+
|
|
1147
|
+
`db restore --to NEW_DIRECTORY [--from SNAPSHOT_DIRECTORY]`
|
|
1148
|
+
|
|
1149
|
+
- Recover into a new directory without replacing the live database. See
|
|
1150
|
+
[database backup and recovery](docs/recovery.md).
|
|
1151
|
+
|
|
1152
|
+
### Tests
|
|
1153
|
+
|
|
1154
|
+
`test pytest <package-or-path> [pytest arguments ...]`
|
|
1155
|
+
|
|
1156
|
+
- Runs `.venv/bin/python -m pytest --pyargs PACKAGE` in the target project, with
|
|
1157
|
+
its configured environment and pytest settings. Install pytest in that
|
|
1158
|
+
project's virtualenv first.
|
|
1159
|
+
- Accepts importable Python package names, test directories, files, and node IDs.
|
|
1160
|
+
- Arguments after the package are passed to pytest, including `-k`, `-m`, `-x`,
|
|
1161
|
+
`-q`, `-v`, and plugin flags. An optional `--` after the package is accepted.
|
|
1162
|
+
- Put plonex logging flags before `pytest`; for example,
|
|
1163
|
+
`plonex -v test pytest my.package -q` enables plonex diagnostics and quiet pytest
|
|
1164
|
+
output. Test failures preserve pytest's exit status.
|
|
1165
|
+
|
|
1166
|
+
```sh
|
|
1167
|
+
plonex test pytest my.package -k login -x
|
|
1168
|
+
plonex test pytest src/my.package/tests -q
|
|
1169
|
+
plonex test pytest tests/test_login.py::test_login -v
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
`test zope <package> [-t TEST]`
|
|
1173
|
+
|
|
1174
|
+
- Run `zope-testrunner` for a package.
|
|
1175
|
+
|
|
1176
|
+
`test robot-server [--layer LAYER]`
|
|
1177
|
+
|
|
1178
|
+
- Start robot test server.
|
|
1179
|
+
|
|
1180
|
+
`test robot <paths...> [--browser BROWSER] [-t TEST]`
|
|
1181
|
+
|
|
1182
|
+
- Run Robot Framework tests.
|
|
1183
|
+
|
|
1184
|
+
## Configuration and option precedence
|
|
1185
|
+
|
|
1186
|
+
Options are merged in this order (higher wins):
|
|
1187
|
+
|
|
1188
|
+
1. CLI options
|
|
1189
|
+
1. Files passed with `-c/--config`
|
|
1190
|
+
1. `etc/plonex-<service>.*.yml`
|
|
1191
|
+
1. `etc/plonex-<service>.yml`
|
|
1192
|
+
1. `etc/plonex.*.yml` (alphabetical precedence)
|
|
1193
|
+
1. `etc/plonex.yml`
|
|
1194
|
+
1. Profiles declared by `etc/plonex.yml` and nested profile `plonex.yml` files
|
|
1195
|
+
1. Service defaults
|
|
1196
|
+
|
|
1197
|
+
Why this matters:
|
|
1198
|
+
|
|
1199
|
+
- you can keep sane defaults in `etc/plonex.yml`,
|
|
1200
|
+
- inherit shared defaults from one or more profiles,
|
|
1201
|
+
- add machine- or developer-specific overrides in `etc/plonex.local.yml`,
|
|
1202
|
+
- and still force one-off values from the command line when needed.
|
|
1203
|
+
|
|
1204
|
+
This is especially useful for paths like `zeo_address`, ports, or feature flags
|
|
1205
|
+
that can vary by environment.
|
|
1206
|
+
|
|
1207
|
+
Useful settings include:
|
|
1208
|
+
|
|
1209
|
+
- `log_level`: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
|
1210
|
+
- `environment_vars`: environment variables exported before service execution
|
|
1211
|
+
- `zeo_address`: socket/host used by runtime services and `db pack`
|
|
1212
|
+
- `blobstorage`: blob storage path
|
|
1213
|
+
- `http_port`, `http_address`
|
|
1214
|
+
|
|
1215
|
+
Example:
|
|
1216
|
+
|
|
1217
|
+
```yaml
|
|
1218
|
+
zeo_address: /srv/components/zeo/var/zeo.socket
|
|
1219
|
+
blobstorage: /srv/components/zeo/var/blobstorage
|
|
1220
|
+
environment_vars:
|
|
1221
|
+
TZ: Europe/Rome
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
Service-specific overrides are useful when one command needs different settings.
|
|
1225
|
+
For example:
|
|
1226
|
+
|
|
1227
|
+
- `etc/plonex.yml`: shared defaults.
|
|
1228
|
+
- `etc/plonex.local.yml`: local machine overrides (socket paths, local ports).
|
|
1229
|
+
- `etc/plonex-runwsgi.yml`: runwsgi-only adjustments.
|
|
1230
|
+
|
|
1231
|
+
Because these files are merged with precedence, you can keep common settings in
|
|
1232
|
+
one place and make only small targeted overrides where needed.
|
|
1233
|
+
|
|
1234
|
+
### Project environment variables
|
|
1235
|
+
|
|
1236
|
+
Plonex supplies these variables to Zope instances, console sessions, and scripts:
|
|
1237
|
+
|
|
1238
|
+
- `PLONEX_TARGET`: absolute project root.
|
|
1239
|
+
- `PLONEX_INSTANCE_NAME`: runtime service name, selected with `--name` where
|
|
1240
|
+
supported (for example, `instance1`). Defaults are `runwsgi`, `fg`, and
|
|
1241
|
+
`zconsole` for start, debug, and console or run, respectively.
|
|
1242
|
+
- `PLONEX_INSTANCE_HOME`: absolute path of the generated instance runtime directory.
|
|
1243
|
+
- `PLONEX_COMMAND`: `instance start`, `instance debug`, `instance console`, or
|
|
1244
|
+
`instance run`. Internal Zope script jobs use `instance run`.
|
|
1245
|
+
- `PLONEX_VERSION`: version of Plonex launching the process.
|
|
1246
|
+
|
|
1247
|
+
These values take precedence over values inherited from the shell or defined
|
|
1248
|
+
in configuration.
|
|
1249
|
+
|
|
1250
|
+
Before running a command, plonex reads the optional `.env` and `.env.local` files
|
|
1251
|
+
in the project root (the directory containing `etc/plonex.yml`). Both supply
|
|
1252
|
+
variables to plonex and the services it starts, including Supervisor and its
|
|
1253
|
+
child processes. `.env.local` overrides `.env`, so it can hold machine-specific
|
|
1254
|
+
values. Other names, such as `.env.production`, are not loaded automatically.
|
|
1255
|
+
|
|
1256
|
+
Each file contains one `NAME=value` assignment per line. Empty lines, comments,
|
|
1257
|
+
optional `export`, and shell-style single or double quotes are supported. Quote
|
|
1258
|
+
values containing spaces or `#`. Values are literal: variable expansion, command
|
|
1259
|
+
substitution, and multiline values are not supported. Either file may be absent.
|
|
1260
|
+
|
|
1261
|
+
When the same variable is defined in multiple places, the highest applicable
|
|
1262
|
+
setting wins:
|
|
1263
|
+
|
|
1264
|
+
1. A job's `environment` settings, for that job. A managed process may also
|
|
1265
|
+
define its own environment settings.
|
|
1266
|
+
1. The service's resolved `environment_vars` in YAML or configuration overrides.
|
|
1267
|
+
YAML files and `-c/--config` follow the configuration precedence above.
|
|
1268
|
+
1. Variables already exported in the shell that starts plonex (including an
|
|
1269
|
+
explicitly exported empty value).
|
|
1270
|
+
1. The project root `.env.local`.
|
|
1271
|
+
1. The project root `.env`.
|
|
1272
|
+
|
|
1273
|
+
For example, start with these files in the project root:
|
|
1274
|
+
|
|
1275
|
+
`.env`:
|
|
1276
|
+
|
|
1277
|
+
```dotenv
|
|
1278
|
+
COLOR=blue
|
|
1279
|
+
TZ=Europe/Rome
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
`.env.local`:
|
|
1283
|
+
|
|
1284
|
+
```dotenv
|
|
1285
|
+
COLOR=green
|
|
1286
|
+
```
|
|
1287
|
+
|
|
1288
|
+
With no other definition of `COLOR`, a service receives `COLOR=green` and
|
|
1289
|
+
`TZ=Europe/Rome`. Remove `COLOR` from `.env.local` and the service receives
|
|
1290
|
+
`COLOR=blue`. To override both files for one command, run:
|
|
1291
|
+
|
|
1292
|
+
```shell
|
|
1293
|
+
COLOR=red plonex instance start
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
The service now receives `COLOR=red`. To override it for a particular service,
|
|
1297
|
+
add the following to `etc/plonex-runwsgi.yml`:
|
|
1298
|
+
|
|
1299
|
+
```yaml
|
|
1300
|
+
environment_vars:
|
|
1301
|
+
COLOR: purple
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
That service receives `COLOR=purple`, even when `COLOR=red` is exported in the
|
|
1305
|
+
shell. Other services use their own resolved configuration. To override a YAML
|
|
1306
|
+
setting for one invocation, create `etc/one-off.yml`:
|
|
1307
|
+
|
|
1308
|
+
```yaml
|
|
1309
|
+
environment_vars:
|
|
1310
|
+
COLOR: yellow
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
Then run `plonex instance start --config etc/one-off.yml`; that invocation
|
|
1314
|
+
receives `COLOR=yellow`.
|
|
1315
|
+
|
|
1316
|
+
A scheduled job can override the service value for its own process. For example,
|
|
1317
|
+
in the applicable cron configuration:
|
|
1318
|
+
|
|
1319
|
+
```yaml
|
|
1320
|
+
cron_jobs:
|
|
1321
|
+
example:
|
|
1322
|
+
schedule: "*/15 * * * *"
|
|
1323
|
+
command: ["/usr/bin/env"]
|
|
1324
|
+
environment:
|
|
1325
|
+
COLOR: orange
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
This job receives `COLOR=orange`. Other jobs retain their own resolved values.
|
|
1329
|
+
|
|
1330
|
+
The environment files supply process environment variables; they do not
|
|
1331
|
+
substitute values into YAML options. YAML `environment_vars` is an option mapping:
|
|
1332
|
+
a higher-priority definition normally replaces the mapping, while `+environment_vars` can extend it in profile and additional project
|
|
1333
|
+
configuration files that support `+` merges.
|
|
1334
|
+
Plonex does not automatically load separate service-specific `.env` files.
|
|
1335
|
+
Services may implement their own environment handling.
|
|
1336
|
+
|
|
1337
|
+
Keep files containing secrets out of version control and give them appropriate
|
|
1338
|
+
permissions; plonex does not create or configure the project's ignore rules.
|
|
1339
|
+
Restart running processes to pick up changes. The interactive shell reloads the
|
|
1340
|
+
files for each command.
|
|
1341
|
+
|
|
1342
|
+
## Dependency-driven services
|
|
1343
|
+
|
|
1344
|
+
`plonex` supports declarative helper services in `etc/plonex.yml`.
|
|
1345
|
+
These services are not intended to be run directly as a top-level command.
|
|
1346
|
+
Instead, they run automatically as dependencies of runtime commands.
|
|
1347
|
+
|
|
1348
|
+
This is useful when a command needs generated files before execution, for
|
|
1349
|
+
example Supervisor program snippets or other rendered templates.
|
|
1350
|
+
|
|
1351
|
+
Example:
|
|
1352
|
+
|
|
1353
|
+
```yaml
|
|
1354
|
+
services:
|
|
1355
|
+
- template:
|
|
1356
|
+
run_for: supervisor
|
|
1357
|
+
source_path: resource://plonex.services.supervisor.templates:program.conf.j2
|
|
1358
|
+
target_path: tmp/supervisor/etc/supervisor/runwsgi.conf
|
|
1359
|
+
options:
|
|
1360
|
+
program: runwsgi
|
|
1361
|
+
command: plonex instance start
|
|
1362
|
+
process_name: runwsgi
|
|
1363
|
+
directory: "{{ target }}"
|
|
1364
|
+
priority: 2
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
In this example:
|
|
1368
|
+
|
|
1369
|
+
- the template is rendered only when running a command mapped to `supervisor`,
|
|
1370
|
+
- the rendered file is prepared before `supervisord`/`supervisorctl` is called,
|
|
1371
|
+
- and the dependency is fully controlled from YAML.
|
|
1372
|
+
|
|
1373
|
+
`run_for` accepts either a string or a list of command names:
|
|
1374
|
+
|
|
1375
|
+
```yaml
|
|
1376
|
+
services:
|
|
1377
|
+
- template:
|
|
1378
|
+
run_for: [supervisor, runwsgi]
|
|
1379
|
+
source: etc/templates/runtime.conf.j2
|
|
1380
|
+
target: tmp/runtime.conf
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
Notes:
|
|
1384
|
+
|
|
1385
|
+
- service entries must be a list of single-key mappings,
|
|
1386
|
+
- unknown service names raise a configuration error,
|
|
1387
|
+
- relative `source`/`target` paths are resolved from the project target folder,
|
|
1388
|
+
- `resource://...` template sources are supported.
|
|
1389
|
+
|
|
1390
|
+
Recommended pattern:
|
|
1391
|
+
|
|
1392
|
+
- keep long-lived defaults in `etc/plonex.yml`,
|
|
1393
|
+
- keep machine-specific path overrides in `etc/plonex.local.yml`,
|
|
1394
|
+
- add `run_for` only where generation must be scoped to specific commands.
|
|
1395
|
+
|
|
1396
|
+
More examples:
|
|
1397
|
+
|
|
1398
|
+
- Add extra ZCML includes for runtime services:
|
|
1399
|
+
|
|
1400
|
+
```yaml
|
|
1401
|
+
zcml_additional:
|
|
1402
|
+
- etc/zcml/010-my-package-meta.zcml
|
|
1403
|
+
- etc/zcml/020-my-package-configure.zcml
|
|
1404
|
+
- etc/zcml/030-my-package-overrides.zcml
|
|
1405
|
+
```
|
|
1406
|
+
|
|
1407
|
+
These files are rendered or copied into `tmp/runwsgi/etc/package-includes/`
|
|
1408
|
+
before `plonex instance start ...` runs. File names matter: `plonex` expects the
|
|
1409
|
+
usual `-meta.zcml`, `-configure.zcml`, or `-overrides.zcml` suffixes.
|
|
1410
|
+
|
|
1411
|
+
- Add extra `zope.conf` snippets for runtime services:
|
|
1412
|
+
|
|
1413
|
+
```yaml
|
|
1414
|
+
zope_conf_additional:
|
|
1415
|
+
- etc/zopeconf/cache.j2
|
|
1416
|
+
- etc/zopeconf/instancesettings.conf
|
|
1417
|
+
```
|
|
1418
|
+
|
|
1419
|
+
For example, `etc/zopeconf/cache.j2` could contain:
|
|
1420
|
+
|
|
1421
|
+
```text
|
|
1422
|
+
<product-config my.package>
|
|
1423
|
+
some-setting value
|
|
1424
|
+
</product-config>
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
Each listed file is appended to the generated runtime `zope.conf` file.
|
|
1428
|
+
Jinja templates can use the current service context.
|
|
1429
|
+
|
|
1430
|
+
- Generate a Supervisor program for an auxiliary service such as a websocket
|
|
1431
|
+
worker, Celery worker, or custom script:
|
|
1432
|
+
|
|
1433
|
+
```yaml
|
|
1434
|
+
services:
|
|
1435
|
+
- template:
|
|
1436
|
+
run_for: supervisor
|
|
1437
|
+
source_path: resource://plonex.services.supervisor.templates:program.conf.j2
|
|
1438
|
+
target_path: tmp/supervisor/etc/supervisor/worker.conf
|
|
1439
|
+
options:
|
|
1440
|
+
program: worker
|
|
1441
|
+
command: .venv/bin/python -m mypackage.worker
|
|
1442
|
+
process_name: worker
|
|
1443
|
+
directory: "{{ target }}"
|
|
1444
|
+
priority: 20
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
That way `plonex supervisor start` manages not only `zeoserver` and
|
|
1448
|
+
`runwsgi`, but also your additional long-running process.
|
|
1449
|
+
|
|
1450
|
+
- Combine service dependencies and runtime extras in the same project:
|
|
1451
|
+
|
|
1452
|
+
```yaml
|
|
1453
|
+
zcml_additional:
|
|
1454
|
+
- etc/zcml/020-my-package-configure.zcml
|
|
1455
|
+
|
|
1456
|
+
zope_conf_additional:
|
|
1457
|
+
- etc/zopeconf/cache.j2
|
|
1458
|
+
|
|
1459
|
+
services:
|
|
1460
|
+
- template:
|
|
1461
|
+
run_for: supervisor
|
|
1462
|
+
source: etc/templates/worker.conf.j2
|
|
1463
|
+
target: tmp/supervisor/etc/supervisor/worker.conf
|
|
1464
|
+
```
|
|
1465
|
+
|
|
1466
|
+
This keeps all project-specific runtime wiring in `etc/plonex.yml` while still
|
|
1467
|
+
letting the generated files live under `tmp/`.
|
|
1468
|
+
|
|
1469
|
+
## Under the hood
|
|
1470
|
+
|
|
1471
|
+
Services remain dataclasses based on `BaseService`. Commands resolve the project,
|
|
1472
|
+
merge configuration, enter the service (including helper services), then run the
|
|
1473
|
+
appropriate executable from the project virtualenv.
|
|
1474
|
+
|
|
1475
|
+
| Command | Main service | Execution |
|
|
1476
|
+
| ---------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
1477
|
+
| `instance debug`, `instance start` | `RunWSGI` | `.venv/bin/runwsgi tmp/<name>/etc/wsgi.ini` |
|
|
1478
|
+
| `instance console`, `instance run` | `ZConsole` | `.venv/bin/zconsole ACTION tmp/<name>/etc/zope.conf ...` |
|
|
1479
|
+
| `db start` | `ZeoServer` | `.venv/bin/runzeo -C tmp/zeoserver/etc/zeo.conf` |
|
|
1480
|
+
| `supervisor start` | `Supervisor` | `.venv/bin/supervisord -c tmp/supervisor/etc/supervisord.conf` |
|
|
1481
|
+
| `supervisor status` | `Supervisor` | `.venv/bin/supervisorctl -c tmp/supervisor/etc/supervisord.conf status` |
|
|
1482
|
+
| `dependencies install` | `InstallService` | `uv pip install -r var/requirements.txt -c var/constraints.txt` |
|
|
1483
|
+
| `dependencies sync` | `InstallService` | `uv pip compile ... --output-file var/compiled-requirements.txt`, then `uv pip sync var/compiled-requirements.txt` |
|
|
1484
|
+
| `dependencies outdated` | `InstallService` | `uv pip list --outdated` |
|
|
1485
|
+
| `test pytest PACKAGE` | `PytestService` | `.venv/bin/python -m pytest --pyargs PACKAGE ...` |
|
|
1486
|
+
| `test zope PACKAGE` | `ZopeTest` | `.venv/bin/zope-testrunner --all --quiet -pvc --package PACKAGE --auto-path ...` |
|
|
1487
|
+
| `db pack` | `ZeoServer` | `.venv/bin/zeopack -u <zeo_address> -d <days>` |
|
|
1488
|
+
| `options COMMAND` | Inspection | Construct the same service and read its resolved options |
|
|
1489
|
+
|
|
1490
|
+
Paths shown above use default folder and service names. Dependency inspection
|
|
1491
|
+
uses `uv pip freeze` with the target project's Python, so printed package names
|
|
1492
|
+
are canonical. Runtime templates and configured helper services can add other
|
|
1493
|
+
preparation steps.
|
|
1494
|
+
|
|
1495
|
+
The shared service registry and invocation binding are also used by inspection.
|
|
1496
|
+
The shell owns terminal-backed jobs; services continue to run in isolated CLI
|
|
1497
|
+
processes. Tables and inspection reports share a Markdown-capable presenter.
|
|
1498
|
+
See [Project decisions](docs/decisions.md) for ownership boundaries, snapshot
|
|
1499
|
+
semantics, and how to add commands while preserving these patterns.
|
|
1500
|
+
|
|
1501
|
+
## Troubleshooting
|
|
1502
|
+
|
|
1503
|
+
### "Could not find etc/plonex.yml"
|
|
1504
|
+
|
|
1505
|
+
`plonex` looks for `etc/plonex.yml` by walking up from the target directory.
|
|
1506
|
+
Use one of these approaches:
|
|
1507
|
+
|
|
1508
|
+
- run commands from inside your project tree,
|
|
1509
|
+
- pass `--target /path/to/project`,
|
|
1510
|
+
- or initialize a project first with `plonex project init`.
|
|
1511
|
+
|
|
1512
|
+
### Command uses unexpected values
|
|
1513
|
+
|
|
1514
|
+
Use `plonex options COMMAND` with the same flags as the command you are
|
|
1515
|
+
troubleshooting. For a running or completed shell job, `options %1` shows the
|
|
1516
|
+
options it actually started with. Use `jobs` to find the job ID.
|
|
1517
|
+
|
|
1518
|
+
`plonex project compile` also writes merged configuration to `var/plonex.yml`, but that
|
|
1519
|
+
file is not a substitute for inspecting a particular service and its CLI flags.
|
|
1520
|
+
|
|
1521
|
+
Typical causes:
|
|
1522
|
+
|
|
1523
|
+
- a higher-priority config file overrides your value,
|
|
1524
|
+
- a command-line option is overriding YAML,
|
|
1525
|
+
- or a service-specific file exists and takes precedence for that service.
|
|
1526
|
+
|
|
1527
|
+
### `db pack` cannot connect to ZEO
|
|
1528
|
+
|
|
1529
|
+
Check `zeo_address` in your merged config and ensure the socket/host exists.
|
|
1530
|
+
If needed, set it in `etc/plonex.local.yml` for machine-specific environments.
|
|
1531
|
+
|
|
1532
|
+
### Missing binaries in `.venv/bin`
|
|
1533
|
+
|
|
1534
|
+
If commands fail because binaries are missing, run:
|
|
1535
|
+
|
|
1536
|
+
```sh
|
|
1537
|
+
plonex dependencies install
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1540
|
+
This recreates or updates environment-installed tooling used by runtime commands.
|
|
1541
|
+
|
|
1542
|
+
## Current limitations
|
|
1543
|
+
|
|
1544
|
+
- Database snapshots require stopped FileStorage writers and a coordinated blob
|
|
1545
|
+
store; legacy repozo backups require their original restore procedure.
|
|
1546
|
+
- Interactive job control requires a Unix terminal. Piped commands run without
|
|
1547
|
+
terminal job control.
|
|
1548
|
+
- Jobs and snapshots belong to one shell session. Job logs and snapshots remain
|
|
1549
|
+
on disk, but a new shell does not adopt old processes or job IDs.
|
|
1550
|
+
- Option previews construct services and may create directories; they do not run
|
|
1551
|
+
services. Startup snapshots are not live views into a process's Python state.
|
|
1552
|
+
|
|
1553
|
+
## AI Assistance
|
|
1554
|
+
|
|
1555
|
+
Parts of this project were developed with the assistance of AI-based tools.
|
|
1556
|
+
|
|
1557
|
+
All generated content was reviewed, tested, and modified by human maintainers
|
|
1558
|
+
before inclusion in the repository.
|