mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 22:04:56 +00:00
Rewrote both Docker init container scripts in Python using requests. Switched init containers from alpine:3.21 to python:3.12-alpine. Zero shell scripts remain in deployment/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
125 lines
4.4 KiB
Python
125 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""One-shot Nexus initialisation — runs inside the nexus-init container.
|
|
|
|
Creates Docker + npm repositories. Conan2 is handled by Artifactory CE.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
import requests
|
|
|
|
NEXUS_URL = os.environ.get("NEXUS_URL", "http://nexus:8081")
|
|
NEW_PASS = os.environ.get("NEXUS_ADMIN_NEW_PASS", "nexus")
|
|
DOCKER_PORT = int(os.environ.get("DOCKER_REPO_PORT", "5000"))
|
|
PASS_FILE = "/nexus-data/admin.password"
|
|
API = f"{NEXUS_URL}/service/rest/v1"
|
|
|
|
|
|
def log(msg: str) -> None:
|
|
print(f"[nexus-init] {msg}", flush=True)
|
|
|
|
|
|
def create_repo(repo_type: str, label: str, body: dict, auth: tuple) -> bool:
|
|
r = requests.post(f"{API}/repositories/{repo_type}", json=body, auth=auth)
|
|
if r.status_code == 201:
|
|
log(f"{label} repo created")
|
|
return True
|
|
if r.status_code == 400:
|
|
log(f"{label} repo already exists, skipping")
|
|
return True
|
|
log(f"ERROR: {label} repo creation returned HTTP {r.status_code}")
|
|
return False
|
|
|
|
|
|
def main() -> int:
|
|
auth = ("admin", NEW_PASS)
|
|
|
|
# Resolve admin password (idempotent across multiple runs)
|
|
r = requests.get(f"{API}/status", auth=auth)
|
|
if r.status_code == 200:
|
|
log(f"Already initialised with password '{NEW_PASS}'")
|
|
elif os.path.exists(PASS_FILE):
|
|
with open(PASS_FILE) as f:
|
|
init_pass = f.read().strip()
|
|
log("First run: changing admin password...")
|
|
r = requests.put(f"{API}/security/users/admin/change-password",
|
|
auth=("admin", init_pass),
|
|
headers={"Content-Type": "text/plain"}, data=NEW_PASS)
|
|
if r.status_code == 204:
|
|
log(f"Admin password set to '{NEW_PASS}'")
|
|
else:
|
|
log(f"ERROR: password change returned HTTP {r.status_code}")
|
|
return 1
|
|
else:
|
|
log("ERROR: cannot authenticate — is NEXUS_ADMIN_NEW_PASS correct?")
|
|
return 1
|
|
|
|
# Enable anonymous pull access
|
|
requests.put(f"{API}/security/anonymous", json={
|
|
"enabled": True, "userId": "anonymous", "realmName": "NexusAuthorizingRealm",
|
|
}, auth=auth)
|
|
log("Anonymous access enabled")
|
|
|
|
# Enable Docker + npm Bearer Token realms
|
|
requests.put(f"{API}/security/realms/active", auth=auth,
|
|
json=["NexusAuthenticatingRealm", "DockerToken", "NpmToken"])
|
|
log("Docker + npm Bearer Token realms enabled")
|
|
|
|
# Docker hosted repository
|
|
if not create_repo("docker/hosted", "Docker 'local'", {
|
|
"name": "local", "online": True,
|
|
"storage": {"blobStoreName": "default", "strictContentTypeValidation": True,
|
|
"writePolicy": "allow"},
|
|
"docker": {"v1Enabled": False, "forceBasicAuth": False, "httpPort": DOCKER_PORT},
|
|
}, auth):
|
|
return 1
|
|
|
|
# npm hosted
|
|
if not create_repo("npm/hosted", "npm-hosted", {
|
|
"name": "npm-hosted", "online": True,
|
|
"storage": {"blobStoreName": "default", "strictContentTypeValidation": True,
|
|
"writePolicy": "allow_once"},
|
|
}, auth):
|
|
return 1
|
|
|
|
# npm proxy (caches npmjs.org)
|
|
if not create_repo("npm/proxy", "npm-proxy", {
|
|
"name": "npm-proxy", "online": True,
|
|
"storage": {"blobStoreName": "default", "strictContentTypeValidation": True},
|
|
"proxy": {"remoteUrl": "https://registry.npmjs.org",
|
|
"contentMaxAge": 1440, "metadataMaxAge": 1440},
|
|
"httpClient": {"blocked": False, "autoBlock": True},
|
|
"negativeCache": {"enabled": True, "timeToLive": 1440},
|
|
}, auth):
|
|
return 1
|
|
|
|
# npm group (hosted wins, proxy fallback)
|
|
if not create_repo("npm/group", "npm-group", {
|
|
"name": "npm-group", "online": True,
|
|
"storage": {"blobStoreName": "default", "strictContentTypeValidation": True},
|
|
"group": {"memberNames": ["npm-hosted", "npm-proxy"]},
|
|
}, auth):
|
|
return 1
|
|
|
|
log("")
|
|
log("=" * 46)
|
|
log(" Nexus ready!")
|
|
log(f" Registry : localhost:{DOCKER_PORT}")
|
|
log(f" Web UI : http://localhost:8091")
|
|
log(f" Login : admin / {NEW_PASS}")
|
|
log("")
|
|
log(f" npm group URL: {NEXUS_URL}/repository/npm-group/")
|
|
log(f" npm hosted URL: {NEXUS_URL}/repository/npm-hosted/")
|
|
log("")
|
|
log(" Next steps:")
|
|
log(" python3 deployment.py nexus push (Docker images)")
|
|
log(" Conan2 is on Artifactory CE (port 8092)")
|
|
log(" python3 deployment.py npm publish-patches (Patched npm packages)")
|
|
log("=" * 46)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|