Compare commits
6 Commits
3b2d644a1b
...
140a712abf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
140a712abf | ||
|
|
dfca0844f0 | ||
|
|
eb172a367f | ||
|
|
a84fe3f740 | ||
|
|
4c93fa132f | ||
|
|
73d9587e1d |
@@ -4,8 +4,14 @@ echo "command: mount_volume <volume>"
|
|||||||
echo "alias: set_prod"
|
echo "alias: set_prod"
|
||||||
|
|
||||||
export hosts_file="/app/hosts.dev"
|
export hosts_file="/app/hosts.dev"
|
||||||
|
export host_vars_dir="/app/host_vars/"
|
||||||
|
|
||||||
|
export PS1="\[\e[32m\]\h:\w\$\[\e[0m\] "
|
||||||
|
df -h .
|
||||||
|
|
||||||
set_prod() {
|
set_prod() {
|
||||||
export HOSTS_FILE="/app/hosts.all"
|
export hosts_file="/app/hosts.all"
|
||||||
echo "HOSTS_FILE set to: $HOSTS_FILE"
|
export host_vars_dir="/app/host_vars/vault/"
|
||||||
|
echo "LIVE MODE ENABLED !!! "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ RUN ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N "" && \
|
|||||||
chmod 600 /root/.ssh/id_rsa && \
|
chmod 600 /root/.ssh/id_rsa && \
|
||||||
chmod 600 /root/.ssh/config
|
chmod 600 /root/.ssh/config
|
||||||
|
|
||||||
COPY ass /usr/bin/
|
COPY rex /usr/bin/
|
||||||
COPY template /usr/bin/
|
COPY template /usr/bin/
|
||||||
COPY dpush /usr/bin/
|
COPY dpush /usr/bin/
|
||||||
COPY create_volume /usr/bin/
|
COPY create_volume /usr/bin/
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ Host dev
|
|||||||
|
|
||||||
|
|
||||||
Host saopaulo
|
Host saopaulo
|
||||||
Hostname 192.168.9.11
|
Hostname saopaulo
|
||||||
User ansible
|
User ansible
|
||||||
IdentityFile /mnt/encrypted_volume/.ssh/saopaulo
|
IdentityFile /mnt/encrypted_volume/.ssh/saopaulo
|
||||||
|
|
||||||
Host mumbai
|
Host mumbai
|
||||||
Hostname 192.168.9.17
|
Hostname mumbai
|
||||||
User ansible
|
User ansible
|
||||||
IdentityFile /mnt/encrypted_volume/.ssh/mumbai
|
IdentityFile /mnt/encrypted_volume/.ssh/mumbai
|
||||||
|
|
||||||
Host london
|
Host london
|
||||||
Hostname 192.168.9.15
|
Hostname london
|
||||||
User ansible
|
User ansible
|
||||||
IdentityFile /mnt/encrypted_volume/.ssh/london
|
IdentityFile /mnt/encrypted_volume/.ssh/london
|
||||||
|
|
||||||
Host boston
|
Host boston
|
||||||
Hostname 192.168.9.16
|
Hostname boston
|
||||||
User ansible
|
User ansible
|
||||||
IdentityFile /mnt/encrypted_volume/.ssh/boston
|
IdentityFile /mnt/encrypted_volume/.ssh/boston
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ fi
|
|||||||
FILE="/data/$1"
|
FILE="/data/$1"
|
||||||
MAPPER_NAME="encrypted_volume"
|
MAPPER_NAME="encrypted_volume"
|
||||||
MOUNT_POINT="/mnt/${MAPPER_NAME}"
|
MOUNT_POINT="/mnt/${MAPPER_NAME}"
|
||||||
dd if=/dev/zero of="$FILE" bs=1M count=100
|
dd if=/dev/zero of="$FILE" bs=1M count=10
|
||||||
|
|
||||||
|
|
||||||
echo "Setting up LUKS on $FILE..."
|
echo "Setting up LUKS on $FILE..."
|
||||||
cryptsetup luksFormat "$FILE"
|
cryptsetup luksFormat "$FILE"
|
||||||
|
|||||||
9
alpine/hosts
Normal file
9
alpine/hosts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
127.0.0.1 dev
|
||||||
|
::1 dev
|
||||||
|
|
||||||
|
192.168.111.209 dev n8n
|
||||||
|
|
||||||
|
192.168.9.11 saopaulo
|
||||||
|
192.168.9.17 mumbai
|
||||||
|
192.168.9.15 london
|
||||||
|
192.168.9.16 boston
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ "$#" -ne 3 ]; then
|
if [ "$#" -ne 3 ]; then
|
||||||
echo "Usage: $0 <localfile> <remotefile> <host_vars_dir>"
|
echo "Usage: $0 <localfile> <remotefile>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
localfile="$1"
|
localfile="$1"
|
||||||
remotefile="$2"
|
remotefile="$2"
|
||||||
host_vars_dir="$3"
|
remotetmp="/var/tmp/4server"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while read -r host; do
|
while read -r host; do
|
||||||
echo "Processing host: $host"
|
echo "Processing host: $host"
|
||||||
@@ -32,7 +34,8 @@ while read -r host; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo "Copying to $host:$remotefile"
|
echo "Copying to $host:$remotefile"
|
||||||
echo "$content" | ssh "$host" "cat > $remotefile"
|
echo "$content" | ssh "$host" "cat > $remotetmp"
|
||||||
|
rex doas mv $remotetmp $remotefile
|
||||||
|
|
||||||
done < "$hosts_file"
|
done < "$hosts_file"
|
||||||
|
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends, Response
|
|
||||||
from fastapi.security.api_key import APIKeyHeader
|
|
||||||
from fastapi.responses import RedirectResponse
|
|
||||||
from pydantic import BaseModel
|
|
||||||
import psutil
|
|
||||||
import sqlite3
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import uvicorn
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
# Constants
|
|
||||||
DB_PATH = "/OD8N/data/contracts/contracts.db"
|
|
||||||
BIN_PATH = "/OD8N/sbin"
|
|
||||||
API_KEY = os.getenv("API_KEY", "your-secret-api-key")
|
|
||||||
|
|
||||||
# FastAPI app
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
# Security
|
|
||||||
api_key_header = APIKeyHeader(name="X-API-Key")
|
|
||||||
|
|
||||||
|
|
||||||
def verify_api_key(key: str = Depends(api_key_header)):
|
|
||||||
if key != API_KEY:
|
|
||||||
raise HTTPException(status_code=403, detail="Unauthorized")
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------- Database ----------------------
|
|
||||||
def init_db():
|
|
||||||
"""Initialize the database with containers table."""
|
|
||||||
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
|
|
||||||
conn = sqlite3.connect(DB_PATH)
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS containers (
|
|
||||||
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
UUID CHAR(36),
|
|
||||||
location CHAR(100),
|
|
||||||
email CHAR(100),
|
|
||||||
expires DATE,
|
|
||||||
tags TEXT,
|
|
||||||
env TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------- Models ----------------------
|
|
||||||
class ContainerModel(BaseModel):
|
|
||||||
UUID: str
|
|
||||||
location: str
|
|
||||||
email: str
|
|
||||||
expires: str
|
|
||||||
tags: Optional[str] = None
|
|
||||||
env: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class StartContainerRequest(BaseModel):
|
|
||||||
uuid: str
|
|
||||||
email: str
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------- Routes ----------------------
|
|
||||||
@app.get("/", include_in_schema=False)
|
|
||||||
def redirect_to_odoo():
|
|
||||||
return RedirectResponse(url="https://OD8N.com")
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/startContainer", dependencies=[Depends(verify_api_key)])
|
|
||||||
def start_container(request: StartContainerRequest):
|
|
||||||
try:
|
|
||||||
result = subprocess.run(
|
|
||||||
[os.path.join(BIN_PATH, "startContainer"), request.uuid, request.email],
|
|
||||||
capture_output=True,
|
|
||||||
text=True,
|
|
||||||
check=True
|
|
||||||
)
|
|
||||||
return {"status": "success", "output": result.stdout}
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"Error in /startContainer: {e.stderr}", file=sys.stderr)
|
|
||||||
raise HTTPException(status_code=500, detail=f"Command failed: {e.stderr}")
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/system", dependencies=[Depends(verify_api_key)])
|
|
||||||
def get_system_info():
|
|
||||||
try:
|
|
||||||
with open("/etc/alpine-release") as f:
|
|
||||||
version = f.read().strip()
|
|
||||||
return {"alpine_version": version}
|
|
||||||
except FileNotFoundError:
|
|
||||||
raise HTTPException(status_code=404, detail="File not found. Press play on tape")
|
|
||||||
except Exception as e:
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/resources", dependencies=[Depends(verify_api_key)])
|
|
||||||
def get_resources():
|
|
||||||
mem = psutil.virtual_memory()
|
|
||||||
disk = psutil.disk_usage("/")
|
|
||||||
return {
|
|
||||||
"memory": {"total": mem.total, "available": mem.available, "used": mem.used},
|
|
||||||
"disk": {"total": disk.total, "used": disk.used, "free": disk.free},
|
|
||||||
"cpu_count": psutil.cpu_count(logical=True),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/containers", dependencies=[Depends(verify_api_key)])
|
|
||||||
def get_containers():
|
|
||||||
result = subprocess.run(['/OD8N/sbin/getContainers'], capture_output=True, text=True)
|
|
||||||
if result.returncode != 0:
|
|
||||||
return Response(content='{"error": "Script failed"}', media_type="application/json", status_code=500)
|
|
||||||
return Response(content=result.stdout, media_type="application/json")
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/container", dependencies=[Depends(verify_api_key)])
|
|
||||||
def upsert_container(container: ContainerModel):
|
|
||||||
try:
|
|
||||||
conn = sqlite3.connect(DB_PATH)
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute("SELECT 1 FROM containers WHERE UUID = ?", (container.UUID,))
|
|
||||||
exists = cursor.fetchone()
|
|
||||||
|
|
||||||
if exists:
|
|
||||||
cursor.execute("""
|
|
||||||
UPDATE containers SET
|
|
||||||
location = ?, email = ?, expires = ?, tags = ?, env = ?
|
|
||||||
WHERE UUID = ?
|
|
||||||
""", (
|
|
||||||
container.location, container.email, container.expires,
|
|
||||||
container.tags, container.env, container.UUID
|
|
||||||
))
|
|
||||||
operation = "update"
|
|
||||||
else:
|
|
||||||
cursor.execute("""
|
|
||||||
INSERT INTO containers (UUID, location, email, expires, tags, env)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
""", (
|
|
||||||
container.UUID, container.location, container.email,
|
|
||||||
container.expires, container.tags, container.env
|
|
||||||
))
|
|
||||||
operation = "insert"
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
return {"status": "success", "operation": operation}
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in /container: {e}", file=sys.stderr)
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------- Entry Point ----------------------
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print("Version 0.1")
|
|
||||||
init_db()
|
|
||||||
uvicorn.run(app, host="10.5.0.1", port=8888)
|
|
||||||
|
|
||||||
15
app/etc/.bashrc
Normal file
15
app/etc/.bashrc
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# ~/.bashrc
|
||||||
|
|
||||||
|
echo "command: mount_volume <volume>"
|
||||||
|
echo "alias: set_prod"
|
||||||
|
|
||||||
|
export hosts_file="/app/hosts.dev"
|
||||||
|
|
||||||
|
export PS1="\[\e[32m\]\h:\w\$\[\e[0m\] "
|
||||||
|
df -h .
|
||||||
|
|
||||||
|
set_prod() {
|
||||||
|
export HOSTS_FILE="/app/hosts.all"
|
||||||
|
echo "HOSTS_FILE set to: $HOSTS_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
30
app/etc/certs/dev.crt
Normal file
30
app/etc/certs/dev.crt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
||||||
52
app/etc/certs/dev.key
Normal file
52
app/etc/certs/dev.key
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
YV/U3ImFkT12e6nwfgrMRfQCZrRsp9g=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
21
app/etc/init.d/4server-api.init.j2
Normal file
21
app/etc/init.d/4server-api.init.j2
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="4server-api"
|
||||||
|
description="4server API Service"
|
||||||
|
|
||||||
|
command="/4server/sbin/api"
|
||||||
|
command_args=""
|
||||||
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
command_background="yes"
|
||||||
|
|
||||||
|
|
||||||
|
output_log="/4server/data/api.log"
|
||||||
|
error_log="/4server/data/api.log"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
use logger dns
|
||||||
|
after firewall
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1 +1,4 @@
|
|||||||
API_KEY=4h6lDzAOVksuCqmhEB3
|
API_KEY=4h6lDzAOVksuCqmhEB3
|
||||||
|
hostname="dev"
|
||||||
|
nebula_key="123"
|
||||||
|
nebula_cert="456"
|
||||||
|
|||||||
39
app/onboarding
Executable file
39
app/onboarding
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
template templates/hosthostname /etc/hostname
|
||||||
|
# ass swap file ????
|
||||||
|
# ------ create user 4server
|
||||||
|
|
||||||
|
|
||||||
|
# ------ disable root user and login
|
||||||
|
|
||||||
|
|
||||||
|
# ----- install nabula
|
||||||
|
echo "prsync nebula bin"
|
||||||
|
prsync -h "$hosts_file" -avz ./templates/nebula/nebula /4server/nebula
|
||||||
|
rex doas mv /4server/nebula /usr/bin/
|
||||||
|
|
||||||
|
rex doas mkdir -p /etc/nebula
|
||||||
|
rex doas chmod 700 /etc/nebula
|
||||||
|
|
||||||
|
template templates/nebula/nebula.yml /etc/nebula/config.yml
|
||||||
|
template templates/nebula/host.key /etc/nebula/host.key
|
||||||
|
template templates/nebula/host.crt /etc/nebula/host.crt
|
||||||
|
|
||||||
|
rex doas chmod 700 /etc/nebula
|
||||||
|
|
||||||
|
template templates/init.d/nebula /etc/init.d/nebula
|
||||||
|
rex doas chmod 0755 /etc/init.d/nebula
|
||||||
|
rex doas chown root:root /etc/init.d/nebula
|
||||||
|
rex doas rc-update add nebula default
|
||||||
|
rex doas rc-service nebula restart
|
||||||
|
|
||||||
|
template templates/init.d/ping_service /etc/init.d/ping_service
|
||||||
|
rex doas chmod 0755 /etc/init.d/ping_service
|
||||||
|
rex doas chown root:root /etc/init.d/ping_service
|
||||||
|
rex doas rc-update add ping_service default
|
||||||
|
rex doas rc-service ping_service restart
|
||||||
|
|
||||||
|
|
||||||
|
#! ----------- install ufe
|
||||||
|
- ssh, 8080 only on nebula
|
||||||
|
- only 80, 443 to the world
|
||||||
@@ -1,4 +1,2 @@
|
|||||||
#!/bin/ass
|
#!/bin/bash
|
||||||
|
rex doas restart
|
||||||
doas apk update
|
|
||||||
doas apk upgrade
|
|
||||||
|
|||||||
163
app/sbin/api
Executable file
163
app/sbin/api
Executable file
@@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from fastapi import FastAPI, HTTPException, Depends, Response
|
||||||
|
from fastapi.security.api_key import APIKeyHeader
|
||||||
|
from fastapi.responses import RedirectResponse
|
||||||
|
from pydantic import BaseModel
|
||||||
|
import psutil
|
||||||
|
import sqlite3
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import uvicorn
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
DB_PATH = "/4server/data/contracts.db"
|
||||||
|
BIN_PATH = "/4server/sbin"
|
||||||
|
API_KEY = os.getenv("API_KEY", "your-secret-api-key")
|
||||||
|
VERSION = "API: 0.0.5"
|
||||||
|
|
||||||
|
# FastAPI app
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# Security
|
||||||
|
api_key_header = APIKeyHeader(name="X-API-Key")
|
||||||
|
|
||||||
|
|
||||||
|
def verify_api_key(key: str = Depends(api_key_header)):
|
||||||
|
if key != API_KEY:
|
||||||
|
raise HTTPException(status_code=403, detail="Unauthorized")
|
||||||
|
|
||||||
|
# ---------------------- Database ----------------------
|
||||||
|
def init_db():
|
||||||
|
"""Initialize the database with containers table."""
|
||||||
|
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS containers (
|
||||||
|
ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
UUID CHAR(50),
|
||||||
|
email CHAR(100),
|
||||||
|
expires DATE,
|
||||||
|
tags TEXT,
|
||||||
|
env TEXT,
|
||||||
|
affiliate char(30),
|
||||||
|
image char(50),
|
||||||
|
history text,
|
||||||
|
comment text,
|
||||||
|
domains text,
|
||||||
|
status char (20).
|
||||||
|
created DATE,
|
||||||
|
bump DATE
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- Models ----------------------
|
||||||
|
class ContainerModel(BaseModel):
|
||||||
|
UUID: str
|
||||||
|
email: str
|
||||||
|
expires: str
|
||||||
|
tags: Optional[str] = None
|
||||||
|
env: Optional[str] = None
|
||||||
|
affiliate: Optional[str] = None
|
||||||
|
image: Optional[str} = None
|
||||||
|
history: Optional[str] = None
|
||||||
|
comment: Optional[str] = None
|
||||||
|
domains:Optional[str] = None
|
||||||
|
status: str
|
||||||
|
created: str
|
||||||
|
|
||||||
|
|
||||||
|
class StartContainerRequest(BaseModel):
|
||||||
|
uuid: str
|
||||||
|
email: str
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- CONTAINER Routes ----------------------
|
||||||
|
@app.get("/", include_in_schema=False)
|
||||||
|
def redirect_to_odoo():
|
||||||
|
return RedirectResponse(url="https://ODOO4PROJECTS.com")
|
||||||
|
|
||||||
|
@app.post("/container/update", dependencies=[Depends(verify_api_key)])
|
||||||
|
def update_container(request: UpdateContainerRequest):
|
||||||
|
--> Insert the new container into the database. Create, if container does not exist
|
||||||
|
|
||||||
|
@app.post("/container/start", dependencies=[Depends(verify_api_key)])
|
||||||
|
def start_container(request: StartContainerRequest):
|
||||||
|
--> refactor, so that only the container is is given in the request. the shell script BIN_PATH/startContainer is called withtge containerid as parameter
|
||||||
|
|
||||||
|
@app.post("/container/stop", dependencies=[Depends(verify_api_key)])
|
||||||
|
def stop_container(request: StopContainerRequest):
|
||||||
|
--> refactor, so that only the container is is given in the request. the shell script BIN_PATH/stopContainer is called withtge containerid as parameter
|
||||||
|
|
||||||
|
@app.post("/container/nuke", dependencies=[Depends(verify_api_key)])
|
||||||
|
def nuke_container(request: StopContainerRequest):
|
||||||
|
--> refactor, so that only the container is is given in the request.
|
||||||
|
when the status of the database is "nuke" then
|
||||||
|
the shell script BIN_PATH/nukeContainer is called withtge containerid as parameter
|
||||||
|
|
||||||
|
@app.post("/container/info", dependencies=[Depends(verify_api_key)])
|
||||||
|
def info_container(request: InfoContainerRequest):
|
||||||
|
--> refactor: When no container id is given, query all containers from the database. when a containeris is given, just select that one. Return the result
|
||||||
|
|
||||||
|
--> create an endpoint that changes the container image to the latest version of that image /container/bump besides updating the container image, also update the SQL for this container and put the current date into "bump"
|
||||||
|
|
||||||
|
--> add /container/quota return the disk and ram usage of this container. I think you can obtain this from docker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------ SYSTEM Routes
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/system/containers", dependencies=[Depends(verify_api_key)])
|
||||||
|
def get_containers():
|
||||||
|
result = subprocess.run([BIN_PATH+'/getContainers'], capture_output=True, text=True)
|
||||||
|
if result.returncode != 0:
|
||||||
|
return Response(content='{"error": "Script failed"}', media_type="application/json", status_code=500)
|
||||||
|
return Response(content=result.stdout, media_type="application/json")
|
||||||
|
|
||||||
|
--> create an endpoint that lkists all docker images available on the system /system/images
|
||||||
|
|
||||||
|
@app.get("/system/info", dependencies=[Depends(verify_api_key)])
|
||||||
|
def get_system_info():
|
||||||
|
return all INFOas JSON
|
||||||
|
in this function add last_update and return the content of /4server/data/update
|
||||||
|
if this file does not exist return NONE
|
||||||
|
also add the latest bump date of all images in the database
|
||||||
|
return the VERSION as well.
|
||||||
|
try:
|
||||||
|
with open("/etc/alpine-release") as f:
|
||||||
|
version = f.read().strip()
|
||||||
|
return {"alpine_version": version}
|
||||||
|
except FileNotFoundError:
|
||||||
|
raise HTTPException(status_code=404, detail="File not found. Press play on tape")
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/system/resources", dependencies=[Depends(verify_api_key)])
|
||||||
|
def get_resources():
|
||||||
|
|
||||||
|
--> consolidate this API into /system/info
|
||||||
|
|
||||||
|
mem = psutil.virtual_memory()
|
||||||
|
disk = psutil.disk_usage("/")
|
||||||
|
return {
|
||||||
|
"memory": {"total": mem.total, "available": mem.available, "used": mem.used},
|
||||||
|
"disk": {"total": disk.total, "used": disk.used, "free": disk.free},
|
||||||
|
"cpu_count": psutil.cpu_count(logical=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
--> create an endpoint that docker pulls all containers /system/pull
|
||||||
|
|
||||||
|
# ---------------------- Entry Point ----------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(VERSION)
|
||||||
|
init_db()
|
||||||
|
uvicorn.run(app, host="10.5.0.1", port=8888)
|
||||||
|
|
||||||
BIN
app/sbin/nebula
Executable file
BIN
app/sbin/nebula
Executable file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
exec > /OD8N/data/startContainer.log 2>&1
|
exec > /4server/data/startContainer.log 2>&1
|
||||||
|
|
||||||
echo "$(date '+%Y-%m-%d %H:%M') - startContainer $1"
|
echo "$(date '+%Y-%m-%d %H:%M') - startContainer $1"
|
||||||
|
|
||||||
@@ -9,11 +9,11 @@ CONTAINER_NAME="$1"
|
|||||||
# Get the hostname of the machine
|
# Get the hostname of the machine
|
||||||
HOSTNAME=$(hostname)
|
HOSTNAME=$(hostname)
|
||||||
|
|
||||||
mkdir -p /OD8N/data/${CONTAINER_NAME}/n8n
|
mkdir -p /4server/data/${CONTAINER_NAME}/n8n
|
||||||
mkdir -p /OD8N/data/${CONTAINER_NAME}/data
|
mkdir -p /4server/data/${CONTAINER_NAME}/data
|
||||||
|
|
||||||
sudo chmod 777 /OD8N/data/${CONTAINER_NAME}/n8n
|
sudo chmod 777 /4server/data/${CONTAINER_NAME}/n8n
|
||||||
sudo chmod 777 /OD8N/data/${CONTAINER_NAME}/data
|
sudo chmod 777 /4server/data/${CONTAINER_NAME}/data
|
||||||
|
|
||||||
|
|
||||||
# Stop the container if it exists
|
# Stop the container if it exists
|
||||||
@@ -37,8 +37,8 @@ docker run -d \
|
|||||||
-e NODE_ENV=production \
|
-e NODE_ENV=production \
|
||||||
-e WEBHOOK_URL="https://${CONTAINER_NAME}.od8n.com/" \
|
-e WEBHOOK_URL="https://${CONTAINER_NAME}.od8n.com/" \
|
||||||
-e GENERIC_TIMEZONE="UTC-3" \
|
-e GENERIC_TIMEZONE="UTC-3" \
|
||||||
-v "/OD8N/data/${CONTAINER_NAME}/n8n:/home/node/.n8n" \
|
-v "/4server/data/${CONTAINER_NAME}/n8n:/home/node/.n8n" \
|
||||||
-v "/OD8N/data/${CONTAINER_NAME}/data:/data" \
|
-v "/4server/data/${CONTAINER_NAME}/data:/data" \
|
||||||
--label "traefik.enable=true" \
|
--label "traefik.enable=true" \
|
||||||
--label "traefik.http.routers.${CONTAINER_NAME}.rule=Host(\`${CONTAINER_NAME}.od8n.com\`)" \
|
--label "traefik.http.routers.${CONTAINER_NAME}.rule=Host(\`${CONTAINER_NAME}.od8n.com\`)" \
|
||||||
--label "traefik.http.routers.${CONTAINER_NAME}.entrypoints=web,websecure" \
|
--label "traefik.http.routers.${CONTAINER_NAME}.entrypoints=web,websecure" \
|
||||||
@@ -49,4 +49,4 @@ docker run -d \
|
|||||||
n8nio/n8n:latest
|
n8nio/n8n:latest
|
||||||
|
|
||||||
|
|
||||||
echo "Done $1"
|
echo "Started $1"
|
||||||
14
app/sbin/startContainer
Normal file
14
app/sbin/startContainer
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
this script gets a container UUID
|
||||||
|
|
||||||
|
Wtrite a bash script, that gets all info out off the Sqlite3 Database usind the UUID and stores the values in environment variables
|
||||||
|
|
||||||
|
setr the BIN_BATH to /4srver/sbin/
|
||||||
|
|
||||||
|
the uuid looks like xxx-xxx-xxxx-xxxx-xxxx-....
|
||||||
|
|
||||||
|
get the second number
|
||||||
|
|
||||||
|
When the number is 001 call the script BIN_PATH/start/n8n
|
||||||
|
When the number is 002 call the sctipr BIN_ÜATH/start/ODOO18
|
||||||
|
WHen the number is 003 call the script BIN_PATH/start/ODOO19
|
||||||
|
|
||||||
41
app/templates/docker-compose.yml
Normal file
41
app/templates/docker-compose.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
beedb:
|
||||||
|
image: postgres:16
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=postgres
|
||||||
|
- POSTGRES_PASSWORD=deradmin
|
||||||
|
- POSTGRES_USER=deradmin1
|
||||||
|
volumes:
|
||||||
|
- /4server/data/postgres:/var/lib/postgresql/data/
|
||||||
|
- /4server/data/pg_backup/:/BACKUP/
|
||||||
|
networks:
|
||||||
|
4projects:
|
||||||
|
ipv4_address: 10.5.0.200
|
||||||
|
|
||||||
|
traefik:
|
||||||
|
image: docker.io/library/traefik:3.1
|
||||||
|
container_name: traefik
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 443:443
|
||||||
|
- 8080:8080
|
||||||
|
volumes:
|
||||||
|
- /run/docker.sock:/run/docker.sock:ro
|
||||||
|
- /4server/data/traefik/config/traefik/etc:/etc/traefik
|
||||||
|
- /4server/data/traefik/certs:/certs
|
||||||
|
- /4server/data/traefik/traefik-logs:/var/log/traefik
|
||||||
|
networks:
|
||||||
|
- 4projects
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
networks:
|
||||||
|
4projects:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 10.5.0.0/16
|
||||||
|
gateway: 10.5.0.1
|
||||||
|
ip_range: 10.5.0.0/26
|
||||||
|
|
||||||
1
app/templates/hostname
Normal file
1
app/templates/hostname
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{{hostname}}
|
||||||
2
app/templates/hosts
Normal file
2
app/templates/hosts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
127.0.0.1 {{hostname}} localhost
|
||||||
|
10.5.0.200 beedb
|
||||||
20
app/templates/init.d/4server-api
Executable file
20
app/templates/init.d/4server-api
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="4server-api"
|
||||||
|
description="4server API Service"
|
||||||
|
|
||||||
|
command="/4server/sbin/api"
|
||||||
|
command_args=""
|
||||||
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
command_background="yes"
|
||||||
|
|
||||||
|
output_log="/4server/data/api.log"
|
||||||
|
error_log="/4server/data/api.log"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
use logger dns
|
||||||
|
after firewall
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
12
app/templates/init.d/nebula
Executable file
12
app/templates/init.d/nebula
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
command="/usr/bin/nebula"
|
||||||
|
command_args="-config /etc/nebula/config.yml"
|
||||||
|
command_background="yes"
|
||||||
|
pidfile="/run/nebula.pid"
|
||||||
|
name="nebula"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need localmount
|
||||||
|
after networking
|
||||||
|
}
|
||||||
|
|
||||||
17
app/templates/init.d/ping_check
Executable file
17
app/templates/init.d/ping_check
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
description="Ping 192.168.9.1 every minute"
|
||||||
|
|
||||||
|
pidfile="/run/ping_check.pid"
|
||||||
|
|
||||||
|
start() {
|
||||||
|
ebegin "Starting ping_check service"
|
||||||
|
start-stop-daemon --start --background --make-pidfile --pidfile $pidfile --exec /bin/sh -- -c "while true; do ping -c 1 192.168.9.1; sleep 60; done"
|
||||||
|
eend $?
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
ebegin "Stopping ping_check service"
|
||||||
|
start-stop-daemon --stop --pidfile $pidfile
|
||||||
|
eend $?
|
||||||
|
}
|
||||||
|
|
||||||
69
app/templates/nebula/config.yml
Normal file
69
app/templates/nebula/config.yml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
pki:
|
||||||
|
ca: /etc/nebula/ca.crt
|
||||||
|
cert: /etc/nebula/host.crt
|
||||||
|
key: /etc/nebula/host.key
|
||||||
|
static_host_map:
|
||||||
|
"192.168.9.1": ["167.71.79.60:4242"]
|
||||||
|
lighthouse:
|
||||||
|
am_lighthouse: false
|
||||||
|
interval: 60
|
||||||
|
hosts:
|
||||||
|
listen:
|
||||||
|
host: 0.0.0.0
|
||||||
|
port: 4242
|
||||||
|
punchy:
|
||||||
|
punch: true
|
||||||
|
|
||||||
|
relay:
|
||||||
|
am_relay: false
|
||||||
|
use_relays: true
|
||||||
|
|
||||||
|
tun:
|
||||||
|
disabled: false
|
||||||
|
dev: nebula1
|
||||||
|
drop_local_broadcast: false
|
||||||
|
drop_multicast: false
|
||||||
|
tx_queue: 500
|
||||||
|
mtu: 1300
|
||||||
|
routes:
|
||||||
|
#- mtu: 8800
|
||||||
|
# route: 10.0.0.0/16
|
||||||
|
|
||||||
|
unsafe_routes:
|
||||||
|
logging:
|
||||||
|
level: info
|
||||||
|
format: text
|
||||||
|
firewall:
|
||||||
|
outbound_action: drop
|
||||||
|
inbound_action: drop
|
||||||
|
|
||||||
|
conntrack:
|
||||||
|
tcp_timeout: 12m
|
||||||
|
udp_timeout: 3m
|
||||||
|
default_timeout: 10m
|
||||||
|
|
||||||
|
outbound:
|
||||||
|
- port: any
|
||||||
|
proto: any
|
||||||
|
host: any
|
||||||
|
|
||||||
|
inbound:
|
||||||
|
- port: any #ping
|
||||||
|
proto: icmp
|
||||||
|
host: any
|
||||||
|
|
||||||
|
- port: 22 #GIT
|
||||||
|
proto: tcp
|
||||||
|
groups:
|
||||||
|
- admin
|
||||||
|
- ansible
|
||||||
|
|
||||||
|
- port: 8080
|
||||||
|
proto: tcp
|
||||||
|
groups:
|
||||||
|
-admin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/sbin/openrc-run
|
|
||||||
|
|
||||||
name="od8n-api"
|
|
||||||
description="OD8N API Service"
|
|
||||||
|
|
||||||
command="/OD8N/sbin/api"
|
|
||||||
command_args=""
|
|
||||||
pidfile="/run/${RC_SVCNAME}.pid"
|
|
||||||
command_background="yes"
|
|
||||||
|
|
||||||
if [ -f /etc/od8n ]; then
|
|
||||||
. /etc/od8n
|
|
||||||
export $(cut -d= -f1 /etc/od8n)
|
|
||||||
fi
|
|
||||||
|
|
||||||
output_log="/OD8N/data/api.log"
|
|
||||||
error_log="/OD8N/data/api.log"
|
|
||||||
|
|
||||||
depend() {
|
|
||||||
need net
|
|
||||||
use logger dns
|
|
||||||
after firewall
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
3
app/templates/repositories
Normal file
3
app/templates/repositories
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
https://dl-cdn.alpinelinux.org/alpine/v3.22/main
|
||||||
|
https://dl-cdn.alpinelinux.org/alpine/v3.22/community
|
||||||
|
|
||||||
102
app/templates/traefik.yaml
Normal file
102
app/templates/traefik.yaml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
global:
|
||||||
|
checkNewVersion: false
|
||||||
|
sendAnonymousUsage: false
|
||||||
|
|
||||||
|
accesslog:
|
||||||
|
filePath: /var/log/traefik/access.log
|
||||||
|
|
||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
disableDashboardAd: true
|
||||||
|
insecure: true
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: :80
|
||||||
|
# -- (Optional) Redirect all HTTP to HTTPS
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: websecure
|
||||||
|
scheme: https
|
||||||
|
websecure:
|
||||||
|
# http:
|
||||||
|
# middlewares:
|
||||||
|
# - crowdsec-bouncer@file
|
||||||
|
address: :443
|
||||||
|
transport:
|
||||||
|
respondingTimeouts:
|
||||||
|
readTimeout: 0
|
||||||
|
writeTimeout: 0
|
||||||
|
idleTimeout: 42
|
||||||
|
# -- (Optional) Add custom Entrypoint
|
||||||
|
# custom:
|
||||||
|
# address: :8080
|
||||||
|
|
||||||
|
# -- Configure your CertificateResolver here...
|
||||||
|
certificatesResolvers:
|
||||||
|
# staging:
|
||||||
|
# acme:
|
||||||
|
# email: your-email@example.com
|
||||||
|
# storage: /etc/traefik/certs/acme.json
|
||||||
|
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
# httpChallenge:
|
||||||
|
# entryPoint: web
|
||||||
|
|
||||||
|
production:
|
||||||
|
acme:
|
||||||
|
email: oliver@odoo4projects.com
|
||||||
|
storage: /certs/acme.json
|
||||||
|
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: web
|
||||||
|
|
||||||
|
# -- (Optional) Disable TLS Cert verification check
|
||||||
|
# serversTransport:
|
||||||
|
# insecureSkipVerify: true
|
||||||
|
|
||||||
|
# -- (Optional) Overwrite Default Certificates
|
||||||
|
# tls:
|
||||||
|
# stores:
|
||||||
|
# default:
|
||||||
|
# defaultCertificate:
|
||||||
|
# certFile: /etc/traefik/certs/cert.pem
|
||||||
|
# keyFile: /etc/traefik/certs/cert-key.pem
|
||||||
|
# -- (Optional) Disable TLS version 1.0 and 1.1
|
||||||
|
# options:
|
||||||
|
# default:
|
||||||
|
# minVersion: VersionTLS12
|
||||||
|
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
# -- (Optional) Enable this, if you want to expose all containers automatically
|
||||||
|
exposedByDefault: true
|
||||||
|
file:
|
||||||
|
directory: /etc/traefik
|
||||||
|
watch: true
|
||||||
|
|
||||||
|
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
crowdsec-bouncer:
|
||||||
|
forwardauth:
|
||||||
|
address: http://bouncer-traefik:8080/api/v1/forwardAuth
|
||||||
|
trustForwardHeader: true
|
||||||
|
|
||||||
|
|
||||||
|
routers:
|
||||||
|
saopaulo-router:
|
||||||
|
rule: "Host(`dev.local`)"
|
||||||
|
service: saopaulo-service
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: production
|
||||||
|
|
||||||
|
services:
|
||||||
|
saopaulo-service:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: "http://10.5.0.1:8888"
|
||||||
|
|
||||||
|
|
||||||
8
app/test/create_container
Normal file
8
app/test/create_container
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
write a curl request that creatrs a container with
|
||||||
|
a uuid starting with 000-001-....
|
||||||
|
email o.arnold@projektbox.de
|
||||||
|
domain n8n.local
|
||||||
|
and the rest with sane info
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5
app/test/start_container
Normal file
5
app/test/start_container
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
start the container
|
||||||
|
|
||||||
|
000-001-
|
||||||
|
|
||||||
|
add a random uuid
|
||||||
3
app/todo.txt
Normal file
3
app/todo.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
create user
|
||||||
|
set bash as default user
|
||||||
|
|
||||||
53
app/update
53
app/update
@@ -1,25 +1,46 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
ass doas mkdir -p /OD8N
|
### SYSTEM SETUP
|
||||||
ass doas chmod 777 /OD8N
|
rex doas mkdir -p /4server
|
||||||
ass mkdir -p /OD8N/data
|
rex doas chmod 777 /4server
|
||||||
|
rex mkdir -p /4server/data
|
||||||
|
template templates/hosts /etc/hosts
|
||||||
|
|
||||||
|
|
||||||
ass doas apk update
|
### PACKAGES
|
||||||
ass doas apk upgrade
|
template templates/repositories /etc/apk/repositories
|
||||||
ass doas apk add jq rsync mc vim
|
rex doas apk update && upgrade
|
||||||
|
rex doas apk add jq rsync mc vim docker docker-compose htop linux-lts sqlite bash postgresql-16-client
|
||||||
|
|
||||||
prsync -h "$hosts_file" -avz ./bin/OD8N/sbin/ /OD8N/sbin/
|
### own bins
|
||||||
|
prsync -h "$hosts_file" -avz ./sbin/ /4server/sbin/
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
#INSTALL API KEYS
|
#INSTALL API KEYS
|
||||||
template templates/od8n /OD8N/od8n ./host_vars
|
template templates/4server /etc/4server
|
||||||
ass doas mv /OD8N/od8n /etc/od8n
|
|
||||||
|
|
||||||
#INSTALL API SERVICE
|
#INSTALL API SERVICE
|
||||||
template templates/od8n-api /OD8N/od8n-api ./host_vars/
|
template templates/init.d/4server-api /etc/init.d/4server-api:
|
||||||
ass doas mv /OD8N/od8n-api /etc/init.d/od8n-api
|
rex doas chmod 0755 /etc/init.d/4server-api
|
||||||
ass doas chmod 0755 /etc/init.d/od8n-api
|
rex doas chown root:root /etc/init.d/4server-api
|
||||||
ass doas chown root:root /etc/init.d/od8n-api
|
rex doas rc-update add 4server-api default
|
||||||
ass doas rc-update add od8n-api default
|
rex doas rc-service 4server-api restart
|
||||||
ass doas rc-service od8n-api restart
|
|
||||||
ass doas rc-update add od8n-api default
|
|
||||||
|
### Infrastructure
|
||||||
|
##### Docker
|
||||||
|
rex doas rc-service docker start
|
||||||
|
rex doas rc-update add docker boot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rex mkdir -p /4server/data/treafik/config/
|
||||||
|
template templates/traefik.yaml /4server/data/traefik/config/traefik.yaml
|
||||||
|
|
||||||
|
rex mkdir -p /4server/data/traefik/etc/certs
|
||||||
|
prsync -h "$hosts_file" -avz ./etc/certs/* /4server/data/traefik/etc/certs/
|
||||||
|
|
||||||
|
template templates/docker-compose.yml /4server/docker-compose.yml
|
||||||
|
rex doas docker-compose -f /4server/docker-compose.yml up -d
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ services:
|
|||||||
context: ./alpine
|
context: ./alpine
|
||||||
volumes:
|
volumes:
|
||||||
- ./app:/app
|
- ./app:/app
|
||||||
- ./od8n:/app/od8n
|
|
||||||
tty: true
|
tty: true
|
||||||
privileged: true
|
privileged: true
|
||||||
|
|
||||||
|
|||||||
12
start_vm
12
start_vm
@@ -1,6 +1,14 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
|
|
||||||
cp alpine.qcow2 tmp/alpine.qcow2
|
#cp alpine.qcow2 tmp/alpine.qcow2
|
||||||
|
|
||||||
|
sudo qemu-system-x86_64 \
|
||||||
|
-m 1024M \
|
||||||
|
-hda tmp/alpine.qcow2 \
|
||||||
|
-boot d \
|
||||||
|
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::80-:80,hostfwd=tcp::443-:443,hostfwd=tcp::8080-:8080 \
|
||||||
|
-device e1000,netdev=net0 \
|
||||||
|
-enable-kvm \
|
||||||
|
-cpu host
|
||||||
|
|
||||||
qemu-system-x86_64 -m 1024M -hda tmp/alpine.qcow2 -boot d -netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0 -enable-kvm -cpu host
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user