ndev-stack 0.3.11__tar.gz → 0.3.12__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.11 → ndev_stack-0.3.12}/PKG-INFO +1 -1
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/__init__.py +1 -1
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/vhost.py +18 -5
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/nginx_helper.py +91 -7
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/tui.py +16 -2
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/PKG-INFO +1 -1
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/pyproject.toml +1 -1
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/tests/test_opensuse_compat.py +21 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/README.md +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/__main__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/cli.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/config.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/constants.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/distro.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/github.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/logger.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/manifest.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/base.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/mailpit/manifest.json +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/mailpit/module.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/mongodb/manifest.json +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/mongodb/module.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/postgres/manifest.json +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/postgres/module.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/redis/manifest.json +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/builtin/redis/module.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/modules/manager.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/common/utils.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/chroot/manager.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/chroot/packages.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/chroot/shell.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/cli.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/available.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/clean.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/ctl.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/current.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/db.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/doctor.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/grok.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/install.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/list.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/logs.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/mailpit.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/modules.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/mongodb.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/postgres.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/reload.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/restart.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/setup.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/start.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/status.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/stop.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/uninstall.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/update.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/upgrade.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/commands/use.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/builder.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/downloader.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/extensions.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/installer.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/resolver.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/php/templates.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/fpm.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/mailpit.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/pma.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/process.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/services.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/sockets.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/linux/runtime/upgrade.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/main.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/tui.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/bin/shim.exe +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/cli.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/commands/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/__init__.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/db.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/elevate.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/ext.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/fcgi.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/grok.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/logs.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/mailpit.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/mkcert.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/paths.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/php.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/pma.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/redis_core.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/services.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/setup.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/shim.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/upgrade.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/core/vhost.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/templates/vhost.conf.tmpl +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/templates/vhost_ssl.conf.tmpl +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev/win/tui.py +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/SOURCES.txt +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/dependency_links.txt +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/entry_points.txt +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/requires.txt +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/ndev_stack.egg-info/top_level.txt +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/setup.cfg +0 -0
- {ndev_stack-0.3.11 → ndev_stack-0.3.12}/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.12
|
|
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
|
|
@@ -319,6 +319,8 @@ def vhost_cmd(
|
|
|
319
319
|
get_nginx_vhost_dirs,
|
|
320
320
|
generate_vhost_config,
|
|
321
321
|
ensure_nginx_sites_enabled_included,
|
|
322
|
+
install_nginx_ssl_cert,
|
|
323
|
+
ensure_docroot_accessible,
|
|
322
324
|
add_to_hosts_privileged,
|
|
323
325
|
reload_nginx,
|
|
324
326
|
)
|
|
@@ -338,14 +340,25 @@ def vhost_cmd(
|
|
|
338
340
|
if enabled_dir:
|
|
339
341
|
ensure_nginx_sites_enabled_included()
|
|
340
342
|
|
|
343
|
+
# Install SSL certificates into /etc/nginx/ssl for systemd / SELinux compatibility
|
|
344
|
+
final_cert_path = cert_path
|
|
345
|
+
final_key_path = key_path
|
|
346
|
+
if ssl and cert_path and key_path:
|
|
347
|
+
try:
|
|
348
|
+
final_cert_path, final_key_path = install_nginx_ssl_cert(domain, cert_path, key_path)
|
|
349
|
+
except Exception as e:
|
|
350
|
+
logger.warning(f"Could not install SSL certificate to /etc/nginx/ssl: {e}")
|
|
351
|
+
|
|
352
|
+
ensure_docroot_accessible(root_path)
|
|
353
|
+
|
|
341
354
|
conf_file = vhost_dir / f"{domain}.conf"
|
|
342
355
|
config_template = generate_vhost_config(
|
|
343
356
|
domain=domain,
|
|
344
|
-
root=
|
|
357
|
+
root=str(root_path),
|
|
345
358
|
selected_sock=selected_sock,
|
|
346
359
|
ssl=bool(ssl),
|
|
347
|
-
cert_path=
|
|
348
|
-
key_path=
|
|
360
|
+
cert_path=final_cert_path,
|
|
361
|
+
key_path=final_key_path,
|
|
349
362
|
)
|
|
350
363
|
|
|
351
364
|
enabled_link = None
|
|
@@ -382,8 +395,8 @@ def vhost_cmd(
|
|
|
382
395
|
if enabled_link:
|
|
383
396
|
console.print(f"Symlink : {enabled_link}")
|
|
384
397
|
if ssl:
|
|
385
|
-
console.print(f"SSL Cert : {
|
|
386
|
-
console.print(f"SSL Key : {
|
|
398
|
+
console.print(f"SSL Cert : {final_cert_path}")
|
|
399
|
+
console.print(f"SSL Key : {final_key_path}")
|
|
387
400
|
console.print(f"\nOpen: https://{domain}")
|
|
388
401
|
else:
|
|
389
402
|
console.print(f"\nOpen: http://{domain}")
|
|
@@ -426,13 +426,24 @@ server {{
|
|
|
426
426
|
|
|
427
427
|
def reload_nginx(password: Optional[str] = None) -> bool:
|
|
428
428
|
"""
|
|
429
|
-
Reload Nginx configuration
|
|
429
|
+
Reload Nginx configuration if active, or start Nginx if stopped.
|
|
430
430
|
"""
|
|
431
|
+
if os.geteuid() != 0 and password:
|
|
432
|
+
validate_sudo_password(password)
|
|
433
|
+
|
|
431
434
|
cmd = None
|
|
432
435
|
if shutil.which("systemctl"):
|
|
433
|
-
|
|
436
|
+
res = subprocess.run(["systemctl", "is-active", "--quiet", "nginx"])
|
|
437
|
+
if res.returncode == 0:
|
|
438
|
+
cmd = ["systemctl", "reload", "nginx"]
|
|
439
|
+
else:
|
|
440
|
+
cmd = ["systemctl", "start", "nginx"]
|
|
434
441
|
elif shutil.which("service"):
|
|
435
|
-
|
|
442
|
+
res = subprocess.run(["service", "nginx", "status"], capture_output=True)
|
|
443
|
+
if res.returncode == 0:
|
|
444
|
+
cmd = ["service", "nginx", "reload"]
|
|
445
|
+
else:
|
|
446
|
+
cmd = ["service", "nginx", "start"]
|
|
436
447
|
else:
|
|
437
448
|
nginx_bin = which_binary("nginx") or shutil.which("nginx")
|
|
438
449
|
if nginx_bin:
|
|
@@ -442,18 +453,88 @@ def reload_nginx(password: Optional[str] = None) -> bool:
|
|
|
442
453
|
return False
|
|
443
454
|
|
|
444
455
|
if os.geteuid() != 0:
|
|
445
|
-
if password:
|
|
446
|
-
validate_sudo_password(password)
|
|
447
456
|
cmd = ["sudo", "-n"] + cmd
|
|
448
457
|
|
|
449
458
|
try:
|
|
450
459
|
res = subprocess.run(cmd, capture_output=True, timeout=10)
|
|
451
460
|
return res.returncode == 0
|
|
452
461
|
except Exception as e:
|
|
453
|
-
logger.warning(f"Could not reload Nginx: {e}")
|
|
462
|
+
logger.warning(f"Could not reload/start Nginx: {e}")
|
|
454
463
|
return False
|
|
455
464
|
|
|
456
465
|
|
|
466
|
+
def install_nginx_ssl_cert(
|
|
467
|
+
domain: str,
|
|
468
|
+
src_cert: Path | str,
|
|
469
|
+
src_key: Path | str,
|
|
470
|
+
password: Optional[str] = None
|
|
471
|
+
) -> Tuple[Path, Path]:
|
|
472
|
+
"""
|
|
473
|
+
Install SSL certificate and key into /etc/nginx/ssl/{domain}.* with proper permissions and SELinux label.
|
|
474
|
+
Fixes 'BIO_new_file() failed (SSL: error:8000000d:system library:BIO_new_file:Permission denied)'
|
|
475
|
+
caused by systemd ProtectHome and SELinux restricting access to ~/.ndev/certs.
|
|
476
|
+
Returns (installed_cert_path, installed_key_path).
|
|
477
|
+
"""
|
|
478
|
+
ssl_dir = Path("/etc/nginx/ssl")
|
|
479
|
+
dest_cert = ssl_dir / f"{domain}.crt"
|
|
480
|
+
dest_key = ssl_dir / f"{domain}.key"
|
|
481
|
+
|
|
482
|
+
cert_content = Path(src_cert).read_text(encoding="utf-8")
|
|
483
|
+
key_content = Path(src_key).read_text(encoding="utf-8")
|
|
484
|
+
|
|
485
|
+
write_privileged_file(dest_cert, cert_content, password=password)
|
|
486
|
+
write_privileged_file(dest_key, key_content, password=password)
|
|
487
|
+
|
|
488
|
+
if os.geteuid() == 0:
|
|
489
|
+
try:
|
|
490
|
+
os.chmod(str(dest_cert), 0o644)
|
|
491
|
+
os.chmod(str(dest_key), 0o644)
|
|
492
|
+
except Exception:
|
|
493
|
+
pass
|
|
494
|
+
else:
|
|
495
|
+
try:
|
|
496
|
+
os.chmod(str(dest_cert), 0o644)
|
|
497
|
+
os.chmod(str(dest_key), 0o644)
|
|
498
|
+
except (PermissionError, OSError):
|
|
499
|
+
subprocess.run(["sudo", "-n", "chmod", "644", str(dest_cert), str(dest_key)], check=False)
|
|
500
|
+
|
|
501
|
+
if shutil.which("restorecon"):
|
|
502
|
+
cmd = ["restorecon", "-Rv", str(ssl_dir)]
|
|
503
|
+
if os.geteuid() != 0:
|
|
504
|
+
cmd = ["sudo", "-n"] + cmd
|
|
505
|
+
try:
|
|
506
|
+
subprocess.run(cmd, capture_output=True)
|
|
507
|
+
except Exception:
|
|
508
|
+
pass
|
|
509
|
+
|
|
510
|
+
return dest_cert, dest_key
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def ensure_docroot_accessible(root_path: Path) -> None:
|
|
514
|
+
"""
|
|
515
|
+
Ensure the parent directories up to root_path have execute permission (+x)
|
|
516
|
+
so the nginx worker process (e.g. user nginx) can traverse into document root.
|
|
517
|
+
"""
|
|
518
|
+
home = Path.home()
|
|
519
|
+
sudo_user = os.environ.get("SUDO_USER")
|
|
520
|
+
if sudo_user:
|
|
521
|
+
try:
|
|
522
|
+
import pwd
|
|
523
|
+
home = Path(pwd.getpwnam(sudo_user).pw_dir)
|
|
524
|
+
except Exception:
|
|
525
|
+
pass
|
|
526
|
+
|
|
527
|
+
try:
|
|
528
|
+
resolved_root = root_path.resolve()
|
|
529
|
+
resolved_home = home.resolve()
|
|
530
|
+
if resolved_root == resolved_home or resolved_root.is_relative_to(resolved_home):
|
|
531
|
+
st = home.stat()
|
|
532
|
+
if not (st.st_mode & 0o001):
|
|
533
|
+
os.chmod(str(home), st.st_mode | 0o001)
|
|
534
|
+
except Exception:
|
|
535
|
+
pass
|
|
536
|
+
|
|
537
|
+
|
|
457
538
|
def list_vhosts() -> List[Dict[str, Any]]:
|
|
458
539
|
"""List all configured virtual hosts across all searched Nginx config directories."""
|
|
459
540
|
vhosts = []
|
|
@@ -513,8 +594,11 @@ def remove_vhost(domain: str, password: Optional[str] = None) -> bool:
|
|
|
513
594
|
except Exception as e:
|
|
514
595
|
logger.warning(f"Could not remove {conf_file}: {e}")
|
|
515
596
|
|
|
516
|
-
# Remove optional certificates
|
|
597
|
+
# Remove system and optional certificates
|
|
517
598
|
for cert_ext in [".crt", ".key"]:
|
|
599
|
+
sys_cert = Path(f"/etc/nginx/ssl/{clean_domain}{cert_ext}")
|
|
600
|
+
unlink_privileged(sys_cert, password=password)
|
|
601
|
+
|
|
518
602
|
cfile = NDEV_DIR / "certs" / f"{clean_domain}{cert_ext}"
|
|
519
603
|
if cfile.exists():
|
|
520
604
|
try:
|
|
@@ -1203,6 +1203,8 @@ class NdevDashboard(App):
|
|
|
1203
1203
|
get_nginx_vhost_dirs,
|
|
1204
1204
|
generate_vhost_config,
|
|
1205
1205
|
ensure_nginx_sites_enabled_included,
|
|
1206
|
+
install_nginx_ssl_cert,
|
|
1207
|
+
ensure_docroot_accessible,
|
|
1206
1208
|
write_privileged_file,
|
|
1207
1209
|
symlink_privileged,
|
|
1208
1210
|
add_to_hosts_privileged,
|
|
@@ -1220,6 +1222,18 @@ class NdevDashboard(App):
|
|
|
1220
1222
|
if ssl:
|
|
1221
1223
|
cert_path, key_path = generate_local_cert(domain, cert_dir)
|
|
1222
1224
|
|
|
1225
|
+
final_cert_path = cert_path
|
|
1226
|
+
final_key_path = key_path
|
|
1227
|
+
if ssl and cert_path and key_path:
|
|
1228
|
+
try:
|
|
1229
|
+
final_cert_path, final_key_path = install_nginx_ssl_cert(
|
|
1230
|
+
domain, cert_path, key_path, password=password
|
|
1231
|
+
)
|
|
1232
|
+
except Exception as e:
|
|
1233
|
+
logger.warning(f"Could not install SSL certificate into /etc/nginx/ssl: {e}")
|
|
1234
|
+
|
|
1235
|
+
ensure_docroot_accessible(Path(root))
|
|
1236
|
+
|
|
1223
1237
|
mm = php_ver.replace(".", "")[:2] if "." in php_ver else php_ver
|
|
1224
1238
|
selected_sock = NDEV_DIR / "run" / f"php{mm}.sock"
|
|
1225
1239
|
|
|
@@ -1228,8 +1242,8 @@ class NdevDashboard(App):
|
|
|
1228
1242
|
root=root,
|
|
1229
1243
|
selected_sock=selected_sock,
|
|
1230
1244
|
ssl=bool(ssl),
|
|
1231
|
-
cert_path=
|
|
1232
|
-
key_path=
|
|
1245
|
+
cert_path=final_cert_path,
|
|
1246
|
+
key_path=final_key_path,
|
|
1233
1247
|
)
|
|
1234
1248
|
write_privileged_file(conf_file, tpl, password=password)
|
|
1235
1249
|
if enabled_dir and enabled_dir != vhost_dir:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ndev-stack
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.12
|
|
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.12"
|
|
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"
|
|
@@ -255,6 +255,27 @@ class TestNginxHelper(unittest.TestCase):
|
|
|
255
255
|
mock_run.return_value = unittest.mock.MagicMock(returncode=1)
|
|
256
256
|
self.assertTrue(nginx_helper.check_sudo_needs_password())
|
|
257
257
|
|
|
258
|
+
def test_install_nginx_ssl_cert(self):
|
|
259
|
+
src_cert = self.test_dir / "src.crt"
|
|
260
|
+
src_key = self.test_dir / "src.key"
|
|
261
|
+
src_cert.write_text("CERT_CONTENT")
|
|
262
|
+
src_key.write_text("KEY_CONTENT")
|
|
263
|
+
|
|
264
|
+
fake_ssl_dir = self.test_dir / "nginx_ssl"
|
|
265
|
+
with patch("ndev.linux.runtime.nginx_helper.Path") as mock_path:
|
|
266
|
+
def fake_p(p):
|
|
267
|
+
if str(p) == "/etc/nginx/ssl":
|
|
268
|
+
return fake_ssl_dir
|
|
269
|
+
return Path(p)
|
|
270
|
+
mock_path.side_effect = fake_p
|
|
271
|
+
|
|
272
|
+
with patch("os.geteuid", return_value=0):
|
|
273
|
+
dest_cert, dest_key = nginx_helper.install_nginx_ssl_cert("sample.local", src_cert, src_key)
|
|
274
|
+
self.assertTrue(dest_cert.exists())
|
|
275
|
+
self.assertTrue(dest_key.exists())
|
|
276
|
+
self.assertEqual(dest_cert.read_text(), "CERT_CONTENT")
|
|
277
|
+
self.assertEqual(dest_key.read_text(), "KEY_CONTENT")
|
|
278
|
+
|
|
258
279
|
def test_fastcgi_snippet_opensuse(self):
|
|
259
280
|
with patch.object(Path, "exists", autospec=True) as mock_exists:
|
|
260
281
|
def side_effect_exists(p):
|
|
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
|