py-simple-service-manager 0.1.0__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.
- py_simple_service_manager-0.1.0/LICENSE +21 -0
- py_simple_service_manager-0.1.0/PKG-INFO +186 -0
- py_simple_service_manager-0.1.0/README.md +162 -0
- py_simple_service_manager-0.1.0/pyproject.toml +41 -0
- py_simple_service_manager-0.1.0/setup.cfg +4 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/__init__.py +6 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/__main__.py +4 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/admin.py +21 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/bootstrap.py +39 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/cli.py +301 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/gui.py +364 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/manager.py +199 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/models.py +151 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/paths.py +142 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/platforms/__init__.py +21 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/platforms/base.py +35 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/platforms/linux.py +93 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/platforms/macos.py +79 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/platforms/windows.py +131 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/process.py +85 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/runner.py +207 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager/store.py +79 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/PKG-INFO +186 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/SOURCES.txt +33 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/dependency_links.txt +1 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/entry_points.txt +4 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/requires.txt +3 -0
- py_simple_service_manager-0.1.0/src/py_simple_service_manager.egg-info/top_level.txt +1 -0
- py_simple_service_manager-0.1.0/tests/test_bootstrap.py +27 -0
- py_simple_service_manager-0.1.0/tests/test_cli.py +27 -0
- py_simple_service_manager-0.1.0/tests/test_manager.py +65 -0
- py_simple_service_manager-0.1.0/tests/test_models.py +31 -0
- py_simple_service_manager-0.1.0/tests/test_runner.py +102 -0
- py_simple_service_manager-0.1.0/tests/test_store.py +34 -0
- py_simple_service_manager-0.1.0/tests/test_windows_backend.py +44 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GGN_2015
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py-simple-service-manager
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Cross-platform command-as-service manager for Windows, Linux systemd, and macOS launchd.
|
|
5
|
+
Author: GGN_2015
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: MacOS
|
|
11
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: System :: Boot
|
|
16
|
+
Classifier: Topic :: System :: Systems Administration
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: admin
|
|
22
|
+
Requires-Dist: py-admin-launch>=0.1.3; extra == "admin"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# py-simple-service-manager
|
|
26
|
+
|
|
27
|
+
`py-simple-service-manager` lets you manage a one-line command as a service on
|
|
28
|
+
Linux, Windows, and macOS.
|
|
29
|
+
|
|
30
|
+
The same Python runner handles command execution, retry attempts, status files,
|
|
31
|
+
and stdout/stderr logs. Platform backends only register and control the runner:
|
|
32
|
+
|
|
33
|
+
- Linux: `systemd` units controlled by `systemctl`
|
|
34
|
+
- Windows: Task Scheduler tasks controlled by `schtasks` and PowerShell
|
|
35
|
+
- macOS: `launchd` agents/daemons controlled by `launchctl`
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
python -m pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Optional administrator relaunch support:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python -m pip install -e ".[admin]"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `admin` extra uses
|
|
50
|
+
[`py-admin-launch`](https://pypi.org/project/py-admin-launch/) for Windows UAC,
|
|
51
|
+
Linux `pkexec`/`sudo`, and macOS `osascript`/`sudo`.
|
|
52
|
+
|
|
53
|
+
## Startup modes
|
|
54
|
+
|
|
55
|
+
- `manual`: do not start at boot.
|
|
56
|
+
- `auto`: start once at boot after network components are available.
|
|
57
|
+
- `auto-retry`: start at boot and retry after `K` seconds up to `N` times when
|
|
58
|
+
the command exits with a non-zero code.
|
|
59
|
+
|
|
60
|
+
The retry count is handled by this package's runner, so it works consistently
|
|
61
|
+
across all supported platforms.
|
|
62
|
+
|
|
63
|
+
`pssm logs` and the GUI log tabs read the current log files, not only completed
|
|
64
|
+
runs. The runner flushes stdout/stderr to disk as bytes arrive, and Python
|
|
65
|
+
commands are launched with unbuffered output automatically.
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
Register a manual service:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pssm add api -- python -m http.server 9000
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Register a boot service:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pssm --scope system --elevate add api --mode auto -- python -m http.server 9000
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Register a boot service with retry:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pssm --scope system --elevate add worker --mode auto-retry --retry-delay 10 --retry-limit 5 -- python worker.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Change startup mode later:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pssm mode worker manual
|
|
91
|
+
pssm --scope system --elevate mode worker auto-retry --retry-delay 10 --retry-limit 5
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Inspect and control services:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pssm list
|
|
98
|
+
pssm status worker
|
|
99
|
+
pssm logs worker
|
|
100
|
+
pssm logs worker --stream stderr --lines 100
|
|
101
|
+
pssm start worker
|
|
102
|
+
pssm stop worker --force
|
|
103
|
+
pssm remove worker
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Edit the same fields exposed by the GUI:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pssm edit worker --command "python worker.py --queue default" --cwd /path/to/app
|
|
110
|
+
pssm edit worker --mode auto-retry --retry-delay 10 --retry-limit 5
|
|
111
|
+
pssm edit worker --clear-cwd
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Open the GUI:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pssm gui
|
|
118
|
+
pssm-gui
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The GUI supports listing services, creating services, editing command/startup
|
|
122
|
+
mode/retry settings/working directory, deleting services, starting and stopping
|
|
123
|
+
services, and viewing stdout/stderr. Anything the GUI can change is also
|
|
124
|
+
available through the CLI.
|
|
125
|
+
|
|
126
|
+
Show storage paths and platform details:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pssm doctor
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`--scope` can be `user`, `system`, or `auto`. `auto` uses `system` when the
|
|
133
|
+
current process is already elevated, otherwise `user`.
|
|
134
|
+
|
|
135
|
+
## Platform notes
|
|
136
|
+
|
|
137
|
+
### Linux
|
|
138
|
+
|
|
139
|
+
Linux requires `systemd` and `systemctl`.
|
|
140
|
+
|
|
141
|
+
- User scope writes units to `~/.config/systemd/user`.
|
|
142
|
+
- System scope writes units to `/etc/systemd/system`.
|
|
143
|
+
- Boot startup uses `network-online.target` with `Wants=` and `After=`.
|
|
144
|
+
|
|
145
|
+
For user units that should survive logout, enable lingering outside this tool:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
loginctl enable-linger "$USER"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Windows
|
|
152
|
+
|
|
153
|
+
Windows uses Task Scheduler.
|
|
154
|
+
|
|
155
|
+
- Manual services can be registered in user scope.
|
|
156
|
+
- Boot startup requires system scope and elevation:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pssm --scope system --elevate add name --mode auto -- your-command
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
System-scope tasks run as `SYSTEM` with highest available privileges. Make sure
|
|
163
|
+
the command and Python environment are available to that account.
|
|
164
|
+
|
|
165
|
+
### macOS
|
|
166
|
+
|
|
167
|
+
macOS uses `launchd`.
|
|
168
|
+
|
|
169
|
+
- User scope writes LaunchAgents to `~/Library/LaunchAgents`.
|
|
170
|
+
- System scope writes LaunchDaemons to `/Library/LaunchDaemons`.
|
|
171
|
+
- Boot startup maps to `RunAtLoad=true`.
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
Run tests from source:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
PYTHONPATH=src python -m unittest discover -s tests -v
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
On Windows PowerShell:
|
|
182
|
+
|
|
183
|
+
```powershell
|
|
184
|
+
$env:PYTHONPATH = "src"
|
|
185
|
+
python -m unittest discover -s tests -v
|
|
186
|
+
```
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# py-simple-service-manager
|
|
2
|
+
|
|
3
|
+
`py-simple-service-manager` lets you manage a one-line command as a service on
|
|
4
|
+
Linux, Windows, and macOS.
|
|
5
|
+
|
|
6
|
+
The same Python runner handles command execution, retry attempts, status files,
|
|
7
|
+
and stdout/stderr logs. Platform backends only register and control the runner:
|
|
8
|
+
|
|
9
|
+
- Linux: `systemd` units controlled by `systemctl`
|
|
10
|
+
- Windows: Task Scheduler tasks controlled by `schtasks` and PowerShell
|
|
11
|
+
- macOS: `launchd` agents/daemons controlled by `launchctl`
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
python -m pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Optional administrator relaunch support:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install -e ".[admin]"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The `admin` extra uses
|
|
26
|
+
[`py-admin-launch`](https://pypi.org/project/py-admin-launch/) for Windows UAC,
|
|
27
|
+
Linux `pkexec`/`sudo`, and macOS `osascript`/`sudo`.
|
|
28
|
+
|
|
29
|
+
## Startup modes
|
|
30
|
+
|
|
31
|
+
- `manual`: do not start at boot.
|
|
32
|
+
- `auto`: start once at boot after network components are available.
|
|
33
|
+
- `auto-retry`: start at boot and retry after `K` seconds up to `N` times when
|
|
34
|
+
the command exits with a non-zero code.
|
|
35
|
+
|
|
36
|
+
The retry count is handled by this package's runner, so it works consistently
|
|
37
|
+
across all supported platforms.
|
|
38
|
+
|
|
39
|
+
`pssm logs` and the GUI log tabs read the current log files, not only completed
|
|
40
|
+
runs. The runner flushes stdout/stderr to disk as bytes arrive, and Python
|
|
41
|
+
commands are launched with unbuffered output automatically.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
Register a manual service:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pssm add api -- python -m http.server 9000
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Register a boot service:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pssm --scope system --elevate add api --mode auto -- python -m http.server 9000
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Register a boot service with retry:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pssm --scope system --elevate add worker --mode auto-retry --retry-delay 10 --retry-limit 5 -- python worker.py
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Change startup mode later:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pssm mode worker manual
|
|
67
|
+
pssm --scope system --elevate mode worker auto-retry --retry-delay 10 --retry-limit 5
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Inspect and control services:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pssm list
|
|
74
|
+
pssm status worker
|
|
75
|
+
pssm logs worker
|
|
76
|
+
pssm logs worker --stream stderr --lines 100
|
|
77
|
+
pssm start worker
|
|
78
|
+
pssm stop worker --force
|
|
79
|
+
pssm remove worker
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Edit the same fields exposed by the GUI:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pssm edit worker --command "python worker.py --queue default" --cwd /path/to/app
|
|
86
|
+
pssm edit worker --mode auto-retry --retry-delay 10 --retry-limit 5
|
|
87
|
+
pssm edit worker --clear-cwd
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Open the GUI:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pssm gui
|
|
94
|
+
pssm-gui
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The GUI supports listing services, creating services, editing command/startup
|
|
98
|
+
mode/retry settings/working directory, deleting services, starting and stopping
|
|
99
|
+
services, and viewing stdout/stderr. Anything the GUI can change is also
|
|
100
|
+
available through the CLI.
|
|
101
|
+
|
|
102
|
+
Show storage paths and platform details:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pssm doctor
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`--scope` can be `user`, `system`, or `auto`. `auto` uses `system` when the
|
|
109
|
+
current process is already elevated, otherwise `user`.
|
|
110
|
+
|
|
111
|
+
## Platform notes
|
|
112
|
+
|
|
113
|
+
### Linux
|
|
114
|
+
|
|
115
|
+
Linux requires `systemd` and `systemctl`.
|
|
116
|
+
|
|
117
|
+
- User scope writes units to `~/.config/systemd/user`.
|
|
118
|
+
- System scope writes units to `/etc/systemd/system`.
|
|
119
|
+
- Boot startup uses `network-online.target` with `Wants=` and `After=`.
|
|
120
|
+
|
|
121
|
+
For user units that should survive logout, enable lingering outside this tool:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
loginctl enable-linger "$USER"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Windows
|
|
128
|
+
|
|
129
|
+
Windows uses Task Scheduler.
|
|
130
|
+
|
|
131
|
+
- Manual services can be registered in user scope.
|
|
132
|
+
- Boot startup requires system scope and elevation:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pssm --scope system --elevate add name --mode auto -- your-command
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
System-scope tasks run as `SYSTEM` with highest available privileges. Make sure
|
|
139
|
+
the command and Python environment are available to that account.
|
|
140
|
+
|
|
141
|
+
### macOS
|
|
142
|
+
|
|
143
|
+
macOS uses `launchd`.
|
|
144
|
+
|
|
145
|
+
- User scope writes LaunchAgents to `~/Library/LaunchAgents`.
|
|
146
|
+
- System scope writes LaunchDaemons to `/Library/LaunchDaemons`.
|
|
147
|
+
- Boot startup maps to `RunAtLoad=true`.
|
|
148
|
+
|
|
149
|
+
## Development
|
|
150
|
+
|
|
151
|
+
Run tests from source:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
PYTHONPATH=src python -m unittest discover -s tests -v
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
On Windows PowerShell:
|
|
158
|
+
|
|
159
|
+
```powershell
|
|
160
|
+
$env:PYTHONPATH = "src"
|
|
161
|
+
python -m unittest discover -s tests -v
|
|
162
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "py-simple-service-manager"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Cross-platform command-as-service manager for Windows, Linux systemd, and macOS launchd."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "GGN_2015" }]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: MacOS",
|
|
19
|
+
"Operating System :: Microsoft :: Windows",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Topic :: System :: Boot",
|
|
24
|
+
"Topic :: System :: Systems Administration",
|
|
25
|
+
"Topic :: Utilities",
|
|
26
|
+
]
|
|
27
|
+
dependencies = []
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
admin = ["py-admin-launch>=0.1.3"]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
pssm = "py_simple_service_manager.cli:main"
|
|
34
|
+
py-simple-service-manager = "py_simple_service_manager.cli:main"
|
|
35
|
+
pssm-gui = "py_simple_service_manager.gui:main"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Sequence
|
|
6
|
+
|
|
7
|
+
from .paths import is_admin
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def relaunch_with_admin(argv: Sequence[str]) -> int:
|
|
11
|
+
if is_admin():
|
|
12
|
+
return -1
|
|
13
|
+
try:
|
|
14
|
+
from py_admin_launch import launch
|
|
15
|
+
except ImportError as exc:
|
|
16
|
+
raise RuntimeError(
|
|
17
|
+
"admin relaunch requires py-admin-launch; install with "
|
|
18
|
+
"'pip install py-simple-service-manager[admin]'"
|
|
19
|
+
) from exc
|
|
20
|
+
result = launch([sys.executable, "-m", "py_simple_service_manager", *argv], cwd=os.getcwd(), wait=True)
|
|
21
|
+
return int(result.returncode or 0)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .paths import AppLayout
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def bootstrap_path(layout: AppLayout, name: str) -> Path:
|
|
9
|
+
return layout.generated_dir / f"{name}-runner.py"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def write_runner_bootstrap(layout: AppLayout, name: str) -> Path:
|
|
13
|
+
path = bootstrap_path(layout, name)
|
|
14
|
+
package_parent = Path(__file__).resolve().parent.parent
|
|
15
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
path.write_text(
|
|
17
|
+
"\n".join(
|
|
18
|
+
[
|
|
19
|
+
"from __future__ import annotations",
|
|
20
|
+
"",
|
|
21
|
+
"import sys",
|
|
22
|
+
"",
|
|
23
|
+
f"sys.path.insert(0, {ascii(str(package_parent))})",
|
|
24
|
+
"from py_simple_service_manager.runner import main",
|
|
25
|
+
"",
|
|
26
|
+
"if __name__ == '__main__':",
|
|
27
|
+
" raise SystemExit(main())",
|
|
28
|
+
"",
|
|
29
|
+
]
|
|
30
|
+
),
|
|
31
|
+
encoding="utf-8",
|
|
32
|
+
)
|
|
33
|
+
return path
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def delete_runner_bootstrap(layout: AppLayout, name: str) -> None:
|
|
37
|
+
path = bootstrap_path(layout, name)
|
|
38
|
+
if path.exists():
|
|
39
|
+
path.unlink()
|