ndev-stack 0.3.13__tar.gz → 0.3.14__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.
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/PKG-INFO +1 -1
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/__init__.py +1 -1
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/setup.py +70 -22
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/nginx_helper.py +75 -2
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/PKG-INFO +1 -1
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/pyproject.toml +1 -1
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/README.md +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/__main__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/cli.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/config.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/constants.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/distro.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/github.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/logger.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/manifest.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/base.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/mailpit/manifest.json +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/mailpit/module.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/mongodb/manifest.json +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/mongodb/module.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/postgres/manifest.json +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/postgres/module.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/redis/manifest.json +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/builtin/redis/module.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/modules/manager.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/common/utils.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/chroot/manager.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/chroot/packages.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/chroot/shell.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/cli.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/available.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/clean.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/ctl.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/current.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/db.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/doctor.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/grok.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/install.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/list.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/logs.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/mailpit.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/modules.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/mongodb.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/postgres.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/reload.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/restart.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/start.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/status.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/stop.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/uninstall.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/update.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/upgrade.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/use.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/commands/vhost.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/builder.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/downloader.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/extensions.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/installer.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/resolver.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/php/templates.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/fpm.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/mailpit.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/pma.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/process.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/services.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/sockets.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/runtime/upgrade.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/linux/tui.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/main.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/tui.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/bin/shim.exe +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/cli.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/commands/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/__init__.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/db.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/elevate.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/ext.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/fcgi.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/grok.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/logs.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/mailpit.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/mkcert.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/paths.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/php.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/pma.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/redis_core.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/services.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/setup.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/shim.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/upgrade.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/core/vhost.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/templates/vhost.conf.tmpl +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/templates/vhost_ssl.conf.tmpl +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev/win/tui.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/SOURCES.txt +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/dependency_links.txt +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/entry_points.txt +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/requires.txt +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/ndev_stack.egg-info/top_level.txt +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/setup.cfg +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/tests/test_opensuse_compat.py +0 -0
- {ndev_stack-0.3.13 → ndev_stack-0.3.14}/tests/test_shim.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ndev-stack
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Cross-platform developer stack manager for PHP, FastCGI/PHP-FPM, MariaDB, Redis, PostgreSQL, MongoDB, Nginx, SSL, and Mailpit on Linux and Windows
|
|
5
5
|
Author-email: Ankit Karan <ankit.karan99@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/ankitkaran99/ndev
|
|
@@ -51,9 +51,9 @@ def setup_cmd():
|
|
|
51
51
|
console.print("[bold yellow]Refreshing openSUSE repositories (sudo zypper refresh)...[/bold yellow]")
|
|
52
52
|
subprocess.run(["sudo", "zypper", "--non-interactive", "refresh"], check=True)
|
|
53
53
|
|
|
54
|
-
# 2. Install MariaDB, Nginx, curl, and
|
|
55
|
-
console.print("\n[bold yellow]Installing MariaDB, Nginx, curl, and
|
|
56
|
-
packages = ["mariadb", "mariadb-client", "nginx", "curl", "bubblewrap"]
|
|
54
|
+
# 2. Install MariaDB, Nginx, curl, Bubblewrap, and SELinux tools
|
|
55
|
+
console.print("\n[bold yellow]Installing MariaDB, Nginx, curl, Bubblewrap, and system tools (sudo zypper install)...[/bold yellow]")
|
|
56
|
+
packages = ["mariadb", "mariadb-client", "nginx", "curl", "bubblewrap", "policycoreutils-python-utils"]
|
|
57
57
|
subprocess.run(["sudo", "zypper", "--non-interactive", "install", "-y"] + packages, check=True)
|
|
58
58
|
|
|
59
59
|
# Optional mkcert package
|
|
@@ -65,27 +65,16 @@ def setup_cmd():
|
|
|
65
65
|
except Exception:
|
|
66
66
|
pass
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
subprocess.run(["sudo", "systemctl", "enable", "--now", "mariadb"], check=False, capture_output=True)
|
|
70
|
-
subprocess.run(["sudo", "systemctl", "enable", "--now", "nginx"], check=False, capture_output=True)
|
|
71
|
-
except Exception:
|
|
72
|
-
pass
|
|
73
|
-
|
|
74
|
-
try:
|
|
75
|
-
from ndev.linux.runtime.nginx_helper import ensure_selinux_httpd_permissions
|
|
76
|
-
ensure_selinux_httpd_permissions()
|
|
77
|
-
except Exception:
|
|
78
|
-
pass
|
|
79
|
-
|
|
80
|
-
console.print("[bold green]MariaDB, Nginx, and Bubblewrap installed and configured successfully![/bold green]\n")
|
|
68
|
+
console.print("[bold green]System packages installed successfully![/bold green]\n")
|
|
81
69
|
else:
|
|
82
70
|
# 1. Update Package Lists
|
|
83
71
|
console.print("[bold yellow]Updating package lists (sudo apt-get update)...[/bold yellow]")
|
|
84
72
|
subprocess.run(["sudo", "apt-get", "update"], check=True)
|
|
85
73
|
|
|
86
74
|
# 2. Install MariaDB and Nginx
|
|
87
|
-
console.print("\n[bold yellow]Installing MariaDB and
|
|
88
|
-
|
|
75
|
+
console.print("\n[bold yellow]Installing MariaDB, Nginx, curl, Bubblewrap, and system tools (sudo apt-get install)...[/bold yellow]")
|
|
76
|
+
packages = ["mariadb-server", "nginx", "curl", "bubblewrap", "policycoreutils-python-utils"]
|
|
77
|
+
subprocess.run(["sudo", "apt-get", "install", "-y"] + packages, check=True)
|
|
89
78
|
|
|
90
79
|
# Optional mkcert package
|
|
91
80
|
try:
|
|
@@ -96,9 +85,63 @@ def setup_cmd():
|
|
|
96
85
|
except Exception:
|
|
97
86
|
pass
|
|
98
87
|
|
|
99
|
-
console.print("[bold green]
|
|
100
|
-
|
|
101
|
-
# 3.
|
|
88
|
+
console.print("[bold green]System packages installed successfully![/bold green]\n")
|
|
89
|
+
|
|
90
|
+
# 3. Auto-configure Stack Services, Permissions, SSL, and SELinux
|
|
91
|
+
console.print("[bold yellow]Auto-configuring stack services, directories, SSL, and SELinux...[/bold yellow]")
|
|
92
|
+
from ndev.linux.runtime.nginx_helper import (
|
|
93
|
+
ensure_selinux_httpd_permissions,
|
|
94
|
+
ensure_nginx_ssl_dir,
|
|
95
|
+
ensure_nginx_sites_enabled_included,
|
|
96
|
+
ensure_development_directories,
|
|
97
|
+
reload_nginx,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Enable & start system services
|
|
101
|
+
try:
|
|
102
|
+
subprocess.run(["sudo", "systemctl", "enable", "--now", "mariadb"], check=False, capture_output=True)
|
|
103
|
+
subprocess.run(["sudo", "systemctl", "enable", "--now", "nginx"], check=False, capture_output=True)
|
|
104
|
+
console.print(" [bold green]✓[/bold green] Enabled and started MariaDB and Nginx system services.")
|
|
105
|
+
except Exception:
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
# SELinux Permissions
|
|
109
|
+
try:
|
|
110
|
+
ok = ensure_selinux_httpd_permissions()
|
|
111
|
+
if ok:
|
|
112
|
+
console.print(" [bold green]✓[/bold green] Configured SELinux permissions for Nginx (httpd_t set to permissive).")
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.warning(f"SELinux configuration notice: {e}")
|
|
115
|
+
|
|
116
|
+
# Nginx SSL Directory (/etc/nginx/ssl)
|
|
117
|
+
try:
|
|
118
|
+
ensure_nginx_ssl_dir()
|
|
119
|
+
console.print(" [bold green]✓[/bold green] Configured Nginx SSL certificate directory (/etc/nginx/ssl).")
|
|
120
|
+
except Exception as e:
|
|
121
|
+
logger.warning(f"SSL directory configuration notice: {e}")
|
|
122
|
+
|
|
123
|
+
# Nginx Sites-Enabled / Vhosts Bridge
|
|
124
|
+
try:
|
|
125
|
+
ensure_nginx_sites_enabled_included()
|
|
126
|
+
console.print(" [bold green]✓[/bold green] Configured Nginx sites-available/sites-enabled directory bridge.")
|
|
127
|
+
except Exception as e:
|
|
128
|
+
logger.warning(f"Nginx bridge configuration notice: {e}")
|
|
129
|
+
|
|
130
|
+
# Web development root permissions and docroot traversal
|
|
131
|
+
try:
|
|
132
|
+
ensure_development_directories()
|
|
133
|
+
console.print(" [bold green]✓[/bold green] Configured web development root permissions (~/Sites).")
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.warning(f"Docroot permission notice: {e}")
|
|
136
|
+
|
|
137
|
+
# Reload Nginx
|
|
138
|
+
try:
|
|
139
|
+
reload_nginx()
|
|
140
|
+
console.print(" [bold green]✓[/bold green] Nginx web server configuration reloaded.")
|
|
141
|
+
except Exception:
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
# 4. Install Composer
|
|
102
145
|
local_bin = get_user_local_bin_dir()
|
|
103
146
|
composer_bin = local_bin / "composer"
|
|
104
147
|
if composer_bin.exists():
|
|
@@ -150,7 +193,12 @@ def setup_cmd():
|
|
|
150
193
|
chown_to_sudo_user(ndev_link)
|
|
151
194
|
console.print(f"[bold green]Created symlink {ndev_link} -> {ndev_venv_path}[/bold green]")
|
|
152
195
|
|
|
153
|
-
console.print("\n[bold green]System setup completed successfully![/bold green]")
|
|
196
|
+
console.print("\n[bold green]System setup completed successfully![/bold green]\n")
|
|
197
|
+
try:
|
|
198
|
+
from ndev.linux.commands.doctor import doctor_cmd
|
|
199
|
+
doctor_cmd()
|
|
200
|
+
except Exception:
|
|
201
|
+
pass
|
|
154
202
|
|
|
155
203
|
except subprocess.CalledProcessError as e:
|
|
156
204
|
logger.error(f"Command execution failed: {e}")
|
|
@@ -74,14 +74,26 @@ def run_privileged_command(
|
|
|
74
74
|
capture_output: bool = True
|
|
75
75
|
) -> subprocess.CompletedProcess:
|
|
76
76
|
"""
|
|
77
|
-
Run a command with elevated privileges using sudo
|
|
77
|
+
Run a command with elevated privileges using sudo if non-root.
|
|
78
78
|
Validates sudo password first if provided to refresh the sudo credential timestamp.
|
|
79
|
+
If no password provided:
|
|
80
|
+
- Uses sudo -n if not in an interactive terminal or if sudo timestamp is active.
|
|
81
|
+
- Falls back to interactive sudo if in an interactive terminal.
|
|
79
82
|
"""
|
|
80
83
|
full_cmd = list(cmd)
|
|
81
84
|
if os.geteuid() != 0:
|
|
82
85
|
if password:
|
|
83
86
|
validate_sudo_password(password)
|
|
84
|
-
|
|
87
|
+
full_cmd = ["sudo", "-n"] + full_cmd
|
|
88
|
+
else:
|
|
89
|
+
if not check_sudo_needs_password():
|
|
90
|
+
full_cmd = ["sudo", "-n"] + full_cmd
|
|
91
|
+
elif sys.stdin.isatty():
|
|
92
|
+
full_cmd = ["sudo"] + full_cmd
|
|
93
|
+
capture_output = False
|
|
94
|
+
else:
|
|
95
|
+
full_cmd = ["sudo", "-n"] + full_cmd
|
|
96
|
+
|
|
85
97
|
return subprocess.run(
|
|
86
98
|
full_cmd,
|
|
87
99
|
check=check,
|
|
@@ -156,6 +168,67 @@ def ensure_selinux_httpd_permissions(password: Optional[str] = None) -> bool:
|
|
|
156
168
|
return success or is_selinux_httpd_permissive()
|
|
157
169
|
|
|
158
170
|
|
|
171
|
+
def ensure_nginx_ssl_dir(password: Optional[str] = None) -> Path:
|
|
172
|
+
"""
|
|
173
|
+
Ensure /etc/nginx/ssl directory exists with 0755 permissions and proper SELinux context.
|
|
174
|
+
"""
|
|
175
|
+
ssl_dir = Path("/etc/nginx/ssl")
|
|
176
|
+
if os.geteuid() == 0:
|
|
177
|
+
ssl_dir.mkdir(parents=True, exist_ok=True)
|
|
178
|
+
try:
|
|
179
|
+
os.chmod(str(ssl_dir), 0o755)
|
|
180
|
+
except Exception:
|
|
181
|
+
pass
|
|
182
|
+
else:
|
|
183
|
+
run_privileged_command(["mkdir", "-p", str(ssl_dir)], password=password, check=False)
|
|
184
|
+
run_privileged_command(["chmod", "755", str(ssl_dir)], password=password, check=False)
|
|
185
|
+
|
|
186
|
+
if shutil.which("restorecon"):
|
|
187
|
+
run_privileged_command(["restorecon", "-Rv", str(ssl_dir)], password=password, check=False)
|
|
188
|
+
|
|
189
|
+
return ssl_dir
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def ensure_development_directories(password: Optional[str] = None) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Ensure the user home directory has +x traversal permissions,
|
|
195
|
+
~/Sites directory exists with 0755 permissions, and any configured vhost docroots are accessible.
|
|
196
|
+
"""
|
|
197
|
+
home = Path.home()
|
|
198
|
+
sudo_user = os.environ.get("SUDO_USER")
|
|
199
|
+
if sudo_user:
|
|
200
|
+
try:
|
|
201
|
+
import pwd
|
|
202
|
+
home = Path(pwd.getpwnam(sudo_user).pw_dir)
|
|
203
|
+
except Exception:
|
|
204
|
+
pass
|
|
205
|
+
|
|
206
|
+
# Ensure home has traversal (+x)
|
|
207
|
+
try:
|
|
208
|
+
st = home.stat()
|
|
209
|
+
if not (st.st_mode & 0o001):
|
|
210
|
+
os.chmod(str(home), st.st_mode | 0o001)
|
|
211
|
+
except Exception:
|
|
212
|
+
pass
|
|
213
|
+
|
|
214
|
+
# Ensure ~/Sites exists
|
|
215
|
+
sites_dir = home / "Sites"
|
|
216
|
+
try:
|
|
217
|
+
sites_dir.mkdir(parents=True, exist_ok=True)
|
|
218
|
+
os.chmod(str(sites_dir), 0o755)
|
|
219
|
+
except Exception:
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
# Ensure all configured vhost docroots are accessible
|
|
223
|
+
try:
|
|
224
|
+
for vhost in list_vhosts():
|
|
225
|
+
docroot = vhost.get("root")
|
|
226
|
+
if docroot and Path(docroot).exists():
|
|
227
|
+
ensure_docroot_accessible(Path(docroot))
|
|
228
|
+
except Exception:
|
|
229
|
+
pass
|
|
230
|
+
|
|
231
|
+
|
|
159
232
|
def write_privileged_file(target: Path, content: str, password: Optional[str] = None) -> None:
|
|
160
233
|
"""
|
|
161
234
|
Write content to a file, using sudo tee if current process lacks permissions.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ndev-stack
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Cross-platform developer stack manager for PHP, FastCGI/PHP-FPM, MariaDB, Redis, PostgreSQL, MongoDB, Nginx, SSL, and Mailpit on Linux and Windows
|
|
5
5
|
Author-email: Ankit Karan <ankit.karan99@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/ankitkaran99/ndev
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ndev-stack"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.14"
|
|
8
8
|
description = "Cross-platform developer stack manager for PHP, FastCGI/PHP-FPM, MariaDB, Redis, PostgreSQL, MongoDB, Nginx, SSL, and Mailpit on Linux and Windows"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|