initial commit
This commit is contained in:
commit
3473119419
40
.containerignore
Normal file
40
.containerignore
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Ignore git metadata
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Ignore container/build files themselves
|
||||||
|
Containerfile
|
||||||
|
Dockerfile
|
||||||
|
.containerignore
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Compose (no longer used)
|
||||||
|
podman-compose.yml
|
||||||
|
docker-compose.yml
|
||||||
|
|
||||||
|
# Scripts and docs
|
||||||
|
pod-start.ps1
|
||||||
|
pod-stop.ps1
|
||||||
|
PODMAN-SETUP.md
|
||||||
|
README.md
|
||||||
|
|
||||||
|
# IDE / OS artifacts
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
Thumbs.db
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Node modules will be installed fresh in the container
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Python caches
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Generated at runtime
|
||||||
|
certs/
|
||||||
|
*.log
|
||||||
59
Containerfile
Normal file
59
Containerfile
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
###############################################################################
|
||||||
|
# o11v4 Containerfile — Podman Pods
|
||||||
|
#
|
||||||
|
# Single image used by BOTH containers in the pod:
|
||||||
|
# - licserver (runs server.js via PM2)
|
||||||
|
# - app (runs o11v4 binary watchdog)
|
||||||
|
#
|
||||||
|
# Build: podman build -t o11v4 .
|
||||||
|
# Run: .\pod-start.ps1 (see PODMAN-SETUP.md)
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
FROM docker.io/library/node:20-slim
|
||||||
|
|
||||||
|
# ── System packages ─────────────────────────────────────────────────────────
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
python3 python3-pip python3-venv \
|
||||||
|
ffmpeg \
|
||||||
|
openssl \
|
||||||
|
procps \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# ── Python venv + dependencies (used by example.py) ─────────────────────────
|
||||||
|
RUN python3 -m venv /opt/venv
|
||||||
|
ENV PATH="/opt/venv/bin:$PATH"
|
||||||
|
RUN pip install --no-cache-dir requests PyJWT
|
||||||
|
|
||||||
|
# ── PM2 (Node process manager) ──────────────────────────────────────────────
|
||||||
|
RUN npm install -g pm2
|
||||||
|
|
||||||
|
# ── Application directory ───────────────────────────────────────────────────
|
||||||
|
RUN mkdir -p /home/o11/hls /home/o11/dl /home/o11/certs /home/o11/www
|
||||||
|
|
||||||
|
WORKDIR /home/o11
|
||||||
|
|
||||||
|
# ── Copy project files ──────────────────────────────────────────────────────
|
||||||
|
COPY server.js o11.cfg lic.cr run.sh ./
|
||||||
|
|
||||||
|
# If you have a www/ directory with static assets, uncomment:
|
||||||
|
# COPY www/ ./www/
|
||||||
|
|
||||||
|
# ── Install Express locally ─────────────────────────────────────────────────
|
||||||
|
RUN npm init -y > /dev/null 2>&1 && npm install express
|
||||||
|
|
||||||
|
# ── Copy binary + entrypoints ───────────────────────────────────────────────
|
||||||
|
COPY o11v4 ./o11v4
|
||||||
|
COPY entrypoint-licserver.sh /entrypoint-licserver.sh
|
||||||
|
COPY entrypoint-app.sh /entrypoint-app.sh
|
||||||
|
|
||||||
|
RUN chmod +x /home/o11/o11v4 \
|
||||||
|
/entrypoint-licserver.sh \
|
||||||
|
/entrypoint-app.sh
|
||||||
|
|
||||||
|
# ── Expose ports ────────────────────────────────────────────────────────────
|
||||||
|
# 80 - License server HTTP
|
||||||
|
# 443 - License server HTTPS
|
||||||
|
# 5454 - License server HTTP alt
|
||||||
|
# 8484 - o11v4 main application
|
||||||
|
EXPOSE 80 443 5454 8484
|
||||||
255
PODMAN-SETUP.md
Normal file
255
PODMAN-SETUP.md
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
# o11v4 — Podman Setup
|
||||||
|
|
||||||
|
Two containers in one pod. Podman handles everything.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Install Podman
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
Download and install from https://podman.io/
|
||||||
|
|
||||||
|
Close and reopen your terminal, then verify:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
podman --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Initialize the machine (once):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
podman machine init
|
||||||
|
podman machine start
|
||||||
|
```
|
||||||
|
|
||||||
|
If PowerShell blocks scripts, run this first:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
Install via Homebrew:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install podman
|
||||||
|
```
|
||||||
|
|
||||||
|
Initialize the machine (once):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman machine init
|
||||||
|
podman machine start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
Install from your package manager:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Debian / Ubuntu
|
||||||
|
sudo apt install -y podman
|
||||||
|
|
||||||
|
# Fedora
|
||||||
|
sudo dnf install -y podman
|
||||||
|
|
||||||
|
# Arch
|
||||||
|
sudo pacman -S podman
|
||||||
|
```
|
||||||
|
|
||||||
|
No machine init needed — Podman runs natively on Linux.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Build & Run
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\pod-start.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS / Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x pod-start.sh pod-stop.sh
|
||||||
|
./pod-start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://localhost:8484` — login: `admin` / `admin`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. What the Script Does
|
||||||
|
|
||||||
|
The start script performs these steps:
|
||||||
|
|
||||||
|
1. Builds the container image from the Containerfile
|
||||||
|
2. Creates a pod with shared networking and `/etc/hosts` entries
|
||||||
|
3. Starts the license server container
|
||||||
|
4. Starts the o11v4 app container
|
||||||
|
|
||||||
|
You can run the commands manually if you prefer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Build the image
|
||||||
|
podman build -t o11v4 .
|
||||||
|
|
||||||
|
# 2. Create the pod
|
||||||
|
podman pod create --name o11v4-pod \
|
||||||
|
--add-host "lic.cryptolive.one:127.0.0.1" \
|
||||||
|
--add-host "lic.bitmaster.cc:127.0.0.1" \
|
||||||
|
-p 8484:8484 -p 8080:80 -p 8443:443 -p 5454:5454
|
||||||
|
|
||||||
|
# 3. Run the license server container
|
||||||
|
podman run -d --pod o11v4-pod --name licserver \
|
||||||
|
-e SERVER_IP=127.0.0.1 o11v4 /entrypoint-licserver.sh
|
||||||
|
|
||||||
|
# 4. Run the app container
|
||||||
|
podman run -d --pod o11v4-pod --name o11v4-app \
|
||||||
|
-e SERVER_IP=127.0.0.1 \
|
||||||
|
--tmpfs /home/o11/hls:size=2g,mode=1777 \
|
||||||
|
--tmpfs /home/o11/dl:size=2g,mode=1777 \
|
||||||
|
o11v4 /entrypoint-app.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Managing the Pod
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
|--------|---------|
|
||||||
|
| Start | `.\pod-start.ps1` |
|
||||||
|
| Stop | `.\pod-stop.ps1` |
|
||||||
|
| Full rebuild | `.\pod-stop.ps1 -RemoveImage` then `.\pod-start.ps1` |
|
||||||
|
|
||||||
|
### macOS / Linux
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
|--------|---------|
|
||||||
|
| Start | `./pod-start.sh` |
|
||||||
|
| Stop | `./pod-stop.sh` |
|
||||||
|
| Full rebuild | `./pod-stop.sh --remove-image` then `./pod-start.sh` |
|
||||||
|
|
||||||
|
### Common Commands (all platforms)
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
|--------|---------|
|
||||||
|
| Pod status | `podman pod ps` |
|
||||||
|
| All containers | `podman ps --pod` |
|
||||||
|
| Restart pod | `podman pod restart o11v4-pod` |
|
||||||
|
| App logs | `podman logs -f o11v4-app` |
|
||||||
|
| Licserver logs | `podman logs -f licserver` |
|
||||||
|
| Shell into app | `podman exec -it o11v4-app bash` |
|
||||||
|
| Shell into licserver | `podman exec -it licserver bash` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Configuration
|
||||||
|
|
||||||
|
### o11.cfg (optional, edit before building)
|
||||||
|
|
||||||
|
You can change the admin password by generating a SHA-256 hash and putting it in the `Password` field in `o11.cfg`.
|
||||||
|
|
||||||
|
**Windows (PowerShell):**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$p = "yourpassword"
|
||||||
|
[BitConverter]::ToString(
|
||||||
|
[Security.Cryptography.SHA256]::Create().ComputeHash(
|
||||||
|
[Text.Encoding]::UTF8.GetBytes($p)
|
||||||
|
)
|
||||||
|
).Replace("-","").ToLower()
|
||||||
|
```
|
||||||
|
|
||||||
|
**macOS / Linux:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo -n "yourpassword" | sha256sum | awk '{print $1}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### tmpfs sizes
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\pod-start.ps1 -HlsSize 4g -DlSize 4g
|
||||||
|
```
|
||||||
|
|
||||||
|
**macOS / Linux:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./pod-start.sh --hls-size 4g --dl-size 4g
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Troubleshooting
|
||||||
|
|
||||||
|
**"Cannot connect to Podman" (Windows / macOS):**
|
||||||
|
```bash
|
||||||
|
podman machine start
|
||||||
|
```
|
||||||
|
|
||||||
|
**o11v4 crashes:**
|
||||||
|
```bash
|
||||||
|
podman logs -f o11v4-app
|
||||||
|
```
|
||||||
|
|
||||||
|
**Can't reach localhost:8484:**
|
||||||
|
```bash
|
||||||
|
podman pod ps # pod running?
|
||||||
|
podman port o11v4-pod # ports mapped?
|
||||||
|
```
|
||||||
|
|
||||||
|
**License server issues:**
|
||||||
|
```bash
|
||||||
|
podman exec licserver pm2 logs licserver --lines 50
|
||||||
|
podman exec o11v4-app cat /etc/hosts
|
||||||
|
```
|
||||||
|
|
||||||
|
**Full reset (Windows):**
|
||||||
|
```powershell
|
||||||
|
.\pod-stop.ps1 -RemoveImage
|
||||||
|
.\pod-start.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
**Full reset (macOS / Linux):**
|
||||||
|
```bash
|
||||||
|
./pod-stop.sh --remove-image
|
||||||
|
./pod-start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. How It Works
|
||||||
|
|
||||||
|
```
|
||||||
|
o11v4-pod (shared network namespace)
|
||||||
|
┌──────────────────────────────────────────────────┐
|
||||||
|
│ │
|
||||||
|
│ licserver container o11v4-app container │
|
||||||
|
│ ┌──────────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ server.js │ │ o11v4 binary │ │
|
||||||
|
│ │ PM2 │◄────────│ watchdog loop │ │
|
||||||
|
│ │ :80 :443 │ license │ :8484 main app │ │
|
||||||
|
│ │ :5454 │ check │ FFmpeg │ │
|
||||||
|
│ │ lic.cr │ via │ tmpfs: hls/, dl/ │ │
|
||||||
|
│ └──────────────┘ localhost└──────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ /etc/hosts: │
|
||||||
|
│ 127.0.0.1 lic.cryptolive.one │
|
||||||
|
│ 127.0.0.1 lic.bitmaster.cc │
|
||||||
|
└──────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
└── localhost:8484 → your browser
|
||||||
|
```
|
||||||
|
|
||||||
|
Both containers share `localhost`. The pod's `--add-host` entries
|
||||||
|
redirect licensing domains to `127.0.0.1`, so o11v4's license check
|
||||||
|
hits the licserver container. The licserver serves `lic.cr` and the
|
||||||
|
check passes.
|
||||||
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# o11v4-podman
|
||||||
|
|
||||||
|
Run o11v4 in a containerized environment using Podman.
|
||||||
|
|
||||||
|
This project packages o11v4 inside a Podman pod, letting you run it on devices that aren't really supported, such as **Windows** and **macOS**, while keeping everything isolated and secure. The container handles all Linux dependencies, so you don't need to set up a Linux environment yourself using something like WSL.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
See [PODMAN-SETUP.md](PODMAN-SETUP.md) for full instructions on how to install Podman and run o11v4 on your system.
|
||||||
24
entrypoint-app.sh
Normal file
24
entrypoint-app.sh
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WORK="/home/o11"
|
||||||
|
cd "$WORK"
|
||||||
|
|
||||||
|
echo "[app] Waiting for license server to be ready..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "[app] Starting o11v4 watchdog..."
|
||||||
|
while true; do
|
||||||
|
if ! pgrep -x "o11v4" > /dev/null 2>&1; then
|
||||||
|
echo "[app] Starting o11v4 on port 8484..."
|
||||||
|
"$WORK/o11v4" \
|
||||||
|
-p 8484 \
|
||||||
|
-noramfs \
|
||||||
|
-f /usr/bin/ffmpeg \
|
||||||
|
-path "$WORK/" \
|
||||||
|
-noautostart \
|
||||||
|
-plstreamname "%s [%p]" &
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
sleep 20
|
||||||
|
done
|
||||||
26
entrypoint-licserver.sh
Normal file
26
entrypoint-licserver.sh
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WORK="/home/o11"
|
||||||
|
cd "$WORK"
|
||||||
|
|
||||||
|
IP="${SERVER_IP:-127.0.0.1}"
|
||||||
|
echo "[licserver] Using IP address: $IP"
|
||||||
|
|
||||||
|
# ── Patch server.js with the correct IP ─────────────────────────────────────
|
||||||
|
sed -i "s|const ipAddress = '';|const ipAddress = '${IP}';|" "$WORK/server.js"
|
||||||
|
|
||||||
|
# ── Generate self-signed TLS certs (if missing) ─────────────────────────────
|
||||||
|
if [ ! -f "$WORK/certs/key.pem" ] || [ ! -f "$WORK/certs/cert.pem" ]; then
|
||||||
|
echo "[licserver] Generating self-signed TLS certificates..."
|
||||||
|
openssl req -x509 -newkey rsa:2048 \
|
||||||
|
-keyout "$WORK/certs/key.pem" \
|
||||||
|
-out "$WORK/certs/cert.pem" \
|
||||||
|
-days 365 -nodes \
|
||||||
|
-subj "/CN=localhost" 2>/dev/null
|
||||||
|
echo "[licserver] Certificates generated."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Start the license server (foreground — keeps container alive) ────────────
|
||||||
|
echo "[licserver] Starting license server on ports 80, 443, 5454..."
|
||||||
|
exec pm2-runtime start "$WORK/server.js" --name licserver
|
||||||
183
example.py
Normal file
183
example.py
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
import jwt
|
||||||
|
import logging
|
||||||
|
from logging.handlers import RotatingFileHandler # Import RotatingFileHandler
|
||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
# Utility function for parameter parsing
|
||||||
|
def parse_params(params: list[str], name: str, default: str = "") -> str:
|
||||||
|
return next((p.split('=')[1] for p in params if p.startswith(f"{name}=")), default)
|
||||||
|
|
||||||
|
# Fetch parameters from sys.argv
|
||||||
|
user = parse_params(sys.argv, 'user')
|
||||||
|
password = parse_params(sys.argv, 'password')
|
||||||
|
id = parse_params(sys.argv, 'id')
|
||||||
|
action = parse_params(sys.argv, 'action')
|
||||||
|
pssh = parse_params(sys.argv, 'pssh')
|
||||||
|
|
||||||
|
# Dynamically set the log filename based on the 'id' parameter
|
||||||
|
|
||||||
|
log_filename = f"{id}.log" if id else f"default.log"
|
||||||
|
# Setup logging to a dynamically named file
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG, # Capture all log messages
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||||
|
handlers=[
|
||||||
|
RotatingFileHandler(log_filename, maxBytes=5*1024*1024, backupCount=3),
|
||||||
|
logging.StreamHandler()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Constants for URLs
|
||||||
|
CHANNELS_API_URL = 'https://cbd46b77.cdn.cms.movetv.com/cms/publish3/domain/summary/ums/1.json'
|
||||||
|
PLAYBACK_API_URL = 'https://cbd46b77.cdn.cms.movetv.com/playermetadata/sling/v1/api/channels/{id}/schedule/now/playback_info.qvt'
|
||||||
|
|
||||||
|
# API headers
|
||||||
|
api_headers = {"ccdodlad-api-key": "bluechip_studio_696223755_api_and_extension_unlimited"}
|
||||||
|
|
||||||
|
# CDM process
|
||||||
|
def do_cdm(pssh: str, id: str) -> Optional[Dict[str, Any]]:
|
||||||
|
try:
|
||||||
|
# Use f-string for URL formatting
|
||||||
|
sling_key_api = f"id={id}&pssh={pssh}"
|
||||||
|
|
||||||
|
# Make the request
|
||||||
|
response = requests.get(sling_key_api)
|
||||||
|
response.raise_for_status() # Raise an error for bad HTTP status codes
|
||||||
|
|
||||||
|
try:
|
||||||
|
key_data = response.json() # Attempt to parse JSON
|
||||||
|
except ValueError:
|
||||||
|
logging.error(f"Invalid JSON response: {response.content}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Check if 'status' is present in the response and handle 'false' status
|
||||||
|
if key_data.get('status') == 'false':
|
||||||
|
logging.error("Failed to Grab Key: Status is false")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Return the 'keys' field from the response if present
|
||||||
|
keys = key_data.get('keys', None)
|
||||||
|
if keys is None or not keys: # Check if keys is None or an empty list
|
||||||
|
logging.error("Keys are empty or not present")
|
||||||
|
return None
|
||||||
|
|
||||||
|
list = "\n".join(keys)
|
||||||
|
|
||||||
|
print(list)
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
logging.error(f"RequestException: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Unexpected error in do_cdm: {e}")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Function to process channels and fetch playback manifest
|
||||||
|
def process_channel(id: str) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
response = requests.get(PLAYBACK_API_URL.format(id=id))
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
dash_manifest_url = data.get('playback_info', {}).get('dash_manifest_url')
|
||||||
|
|
||||||
|
if dash_manifest_url:
|
||||||
|
return dash_manifest_url
|
||||||
|
else:
|
||||||
|
logging.error("dash_manifest_url not found in the response")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
logging.error(f"API request error: {e}")
|
||||||
|
except KeyError as e:
|
||||||
|
logging.error(f"KeyError: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Unexpected error: {e}")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Function to handle the channels action
|
||||||
|
def handle_channels() -> None:
|
||||||
|
output = {"Channels": []}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(CHANNELS_API_URL).json()
|
||||||
|
channels = response.get('channels', [])
|
||||||
|
|
||||||
|
for channel_data in channels:
|
||||||
|
channelid = str(channel_data['channel_guid'])
|
||||||
|
|
||||||
|
channel_info = {
|
||||||
|
"Name": channel_data['metadata']['channel_name'],
|
||||||
|
"Mode": "live",
|
||||||
|
"SessionManifest": True,
|
||||||
|
"ManifestScript": f'id={channelid}',
|
||||||
|
"CdmType": "widevine",
|
||||||
|
"UseCdm": True,
|
||||||
|
"Cdm": f'id={channelid}',
|
||||||
|
"Video": "best",
|
||||||
|
"OnDemand": True,
|
||||||
|
"SpeedUp": True,
|
||||||
|
"CdmMode": "external"
|
||||||
|
}
|
||||||
|
|
||||||
|
output['Channels'].append(channel_info)
|
||||||
|
|
||||||
|
print(json.dumps(output, indent=2))
|
||||||
|
|
||||||
|
except (KeyError, ValueError, requests.RequestException) as e:
|
||||||
|
logging.error(f"Error while handling channels: {e}")
|
||||||
|
|
||||||
|
# Function to handle the manifest action
|
||||||
|
def handle_manifest(id: str) -> None:
|
||||||
|
try:
|
||||||
|
manifest_url = process_channel(id)
|
||||||
|
output = {
|
||||||
|
"ManifestUrl": manifest_url,
|
||||||
|
"Headers": {
|
||||||
|
"Manifest": {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
|
||||||
|
},
|
||||||
|
"Media": {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Heartbeat": {
|
||||||
|
"Url": '',
|
||||||
|
"Params": '',
|
||||||
|
"PeriodMs": 5 * 60 * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(json.dumps(output, indent=4))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error while handling manifest: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def fix_base64(encoded_str):
|
||||||
|
# Add necessary padding if needed
|
||||||
|
missing_padding = len(encoded_str) % 4
|
||||||
|
if missing_padding:
|
||||||
|
encoded_str += '=' * (4 - missing_padding) # Add '=' padding
|
||||||
|
|
||||||
|
return encoded_str
|
||||||
|
|
||||||
|
# Main control flow
|
||||||
|
logging.error("Running with action : " + action)
|
||||||
|
if action == "cdm":
|
||||||
|
logging.error("Requesting keys")
|
||||||
|
do_cdm(pssh, id)
|
||||||
|
|
||||||
|
elif action == "channels":
|
||||||
|
logging.error("Reloading channels")
|
||||||
|
handle_channels()
|
||||||
|
|
||||||
|
elif action == "manifest":
|
||||||
|
logging.error("Requesting manifest")
|
||||||
|
handle_manifest(id)
|
||||||
15
o11.cfg
Normal file
15
o11.cfg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"EpgUrl": "",
|
||||||
|
"Server": "",
|
||||||
|
"Users": [
|
||||||
|
{
|
||||||
|
"Username": "admin",
|
||||||
|
"Password": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",
|
||||||
|
"Network": "",
|
||||||
|
"IsAdmin": true,
|
||||||
|
"HasWebAccess": true,
|
||||||
|
"ProviderIds": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Servers": null
|
||||||
|
}
|
||||||
96
pod-start.ps1
Normal file
96
pod-start.ps1
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
###############################################################################
|
||||||
|
# pod-start.ps1 — Build image, create pod, start containers
|
||||||
|
#
|
||||||
|
# Usage: .\pod-start.ps1
|
||||||
|
# .\pod-start.ps1 -ServerIP 192.168.1.50
|
||||||
|
# .\pod-start.ps1 -HlsSize 4g -DlSize 4g
|
||||||
|
#
|
||||||
|
# Requires: Podman installed, Podman Machine running
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$ServerIP = "127.0.0.1",
|
||||||
|
[string]$HlsSize = "2g",
|
||||||
|
[string]$DlSize = "2g",
|
||||||
|
[string]$ImageName = "o11v4",
|
||||||
|
[string]$PodName = "o11v4-pod"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " o11v4 Podman Pod Setup" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# ── Clean up any existing pod ────────────────────────────────────────────────
|
||||||
|
podman pod exists $PodName 2>$null
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "Removing existing pod '$PodName'..." -ForegroundColor Yellow
|
||||||
|
podman pod stop $PodName 2>$null
|
||||||
|
podman pod rm -f $PodName 2>$null
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Build the image ─────────────────────────────────────────────────────────
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "[1/4] Building image '$ImageName'..." -ForegroundColor Green
|
||||||
|
podman build -t $ImageName .
|
||||||
|
Write-Host " Image built successfully." -ForegroundColor Green
|
||||||
|
|
||||||
|
# ── Create the pod ──────────────────────────────────────────────────────────
|
||||||
|
# All containers in the pod share a network namespace (localhost).
|
||||||
|
# --add-host redirects licensing domains to the license server.
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "[2/4] Creating pod '$PodName'..." -ForegroundColor Green
|
||||||
|
podman pod create `
|
||||||
|
--name $PodName `
|
||||||
|
--add-host "lic.cryptolive.one:$ServerIP" `
|
||||||
|
--add-host "lic.bitmaster.cc:$ServerIP" `
|
||||||
|
-p 8484:8484 `
|
||||||
|
-p 8080:80 `
|
||||||
|
-p 8443:443 `
|
||||||
|
-p 5454:5454
|
||||||
|
Write-Host " Pod created." -ForegroundColor Green
|
||||||
|
|
||||||
|
# ── Start the license server container ──────────────────────────────────────
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "[3/4] Starting license server container..." -ForegroundColor Green
|
||||||
|
podman run -d `
|
||||||
|
--pod $PodName `
|
||||||
|
--name licserver `
|
||||||
|
-e "SERVER_IP=$ServerIP" `
|
||||||
|
$ImageName `
|
||||||
|
/entrypoint-licserver.sh
|
||||||
|
Write-Host " License server started." -ForegroundColor Green
|
||||||
|
|
||||||
|
# ── Start the o11v4 app container ───────────────────────────────────────────
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "[4/4] Starting o11v4 app container..." -ForegroundColor Green
|
||||||
|
podman run -d `
|
||||||
|
--pod $PodName `
|
||||||
|
--name o11v4-app `
|
||||||
|
-e "SERVER_IP=$ServerIP" `
|
||||||
|
--tmpfs "/home/o11/hls:size=$HlsSize,mode=1777" `
|
||||||
|
--tmpfs "/home/o11/dl:size=$DlSize,mode=1777" `
|
||||||
|
$ImageName `
|
||||||
|
/entrypoint-app.sh
|
||||||
|
Write-Host " o11v4 app started." -ForegroundColor Green
|
||||||
|
|
||||||
|
# ── Done ────────────────────────────────────────────────────────────────────
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " All running!" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " App: http://localhost:8484" -ForegroundColor White
|
||||||
|
Write-Host " Login: admin / admin" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " Useful commands:" -ForegroundColor Gray
|
||||||
|
Write-Host " podman pod ps # pod status" -ForegroundColor Gray
|
||||||
|
Write-Host " podman ps --pod # all containers" -ForegroundColor Gray
|
||||||
|
Write-Host " podman logs -f licserver # license server logs" -ForegroundColor Gray
|
||||||
|
Write-Host " podman logs -f o11v4-app # app logs" -ForegroundColor Gray
|
||||||
|
Write-Host " podman exec -it o11v4-app bash # shell into app" -ForegroundColor Gray
|
||||||
|
Write-Host " .\pod-stop.ps1 # stop everything" -ForegroundColor Gray
|
||||||
|
Write-Host ""
|
||||||
103
pod-start.sh
Normal file
103
pod-start.sh
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
###############################################################################
|
||||||
|
# pod-start.sh — Build image, create pod, start containers
|
||||||
|
#
|
||||||
|
# Usage: ./pod-start.sh
|
||||||
|
# ./pod-start.sh --server-ip 192.168.1.50
|
||||||
|
# ./pod-start.sh --hls-size 4g --dl-size 4g
|
||||||
|
#
|
||||||
|
# Requires: Podman installed and running
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SERVER_IP="127.0.0.1"
|
||||||
|
HLS_SIZE="2g"
|
||||||
|
DL_SIZE="2g"
|
||||||
|
IMAGE_NAME="o11v4"
|
||||||
|
POD_NAME="o11v4-pod"
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--server-ip) SERVER_IP="$2"; shift 2 ;;
|
||||||
|
--hls-size) HLS_SIZE="$2"; shift 2 ;;
|
||||||
|
--dl-size) DL_SIZE="$2"; shift 2 ;;
|
||||||
|
--image) IMAGE_NAME="$2"; shift 2 ;;
|
||||||
|
--pod) POD_NAME="$2"; shift 2 ;;
|
||||||
|
*) echo "Unknown option: $1"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo " o11v4 Podman Pod Setup"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ── Clean up any existing pod ────────────────────────────────────────────────
|
||||||
|
if podman pod exists "$POD_NAME" 2>/dev/null; then
|
||||||
|
echo "Removing existing pod '$POD_NAME'..."
|
||||||
|
podman pod stop "$POD_NAME" 2>/dev/null || true
|
||||||
|
podman pod rm -f "$POD_NAME" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Build the image ─────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "[1/4] Building image '$IMAGE_NAME'..."
|
||||||
|
podman build -t "$IMAGE_NAME" .
|
||||||
|
echo " Image built successfully."
|
||||||
|
|
||||||
|
# ── Create the pod ──────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "[2/4] Creating pod '$POD_NAME'..."
|
||||||
|
podman pod create \
|
||||||
|
--name "$POD_NAME" \
|
||||||
|
--add-host "lic.cryptolive.one:$SERVER_IP" \
|
||||||
|
--add-host "lic.bitmaster.cc:$SERVER_IP" \
|
||||||
|
-p 8484:8484 \
|
||||||
|
-p 8080:80 \
|
||||||
|
-p 8443:443 \
|
||||||
|
-p 5454:5454
|
||||||
|
echo " Pod created."
|
||||||
|
|
||||||
|
# ── Start the license server container ──────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "[3/4] Starting license server container..."
|
||||||
|
podman run -d \
|
||||||
|
--pod "$POD_NAME" \
|
||||||
|
--name licserver \
|
||||||
|
-e "SERVER_IP=$SERVER_IP" \
|
||||||
|
"$IMAGE_NAME" \
|
||||||
|
/entrypoint-licserver.sh
|
||||||
|
echo " License server started."
|
||||||
|
|
||||||
|
# ── Start the o11v4 app container ───────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "[4/4] Starting o11v4 app container..."
|
||||||
|
podman run -d \
|
||||||
|
--pod "$POD_NAME" \
|
||||||
|
--name o11v4-app \
|
||||||
|
-e "SERVER_IP=$SERVER_IP" \
|
||||||
|
--tmpfs "/home/o11/hls:size=$HLS_SIZE,mode=1777" \
|
||||||
|
--tmpfs "/home/o11/dl:size=$DL_SIZE,mode=1777" \
|
||||||
|
"$IMAGE_NAME" \
|
||||||
|
/entrypoint-app.sh
|
||||||
|
echo " o11v4 app started."
|
||||||
|
|
||||||
|
# ── Done ────────────────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo " All running!"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
echo " App: http://localhost:8484"
|
||||||
|
echo " Login: admin / admin"
|
||||||
|
echo ""
|
||||||
|
echo " Useful commands:"
|
||||||
|
echo " podman pod ps # pod status"
|
||||||
|
echo " podman ps --pod # all containers"
|
||||||
|
echo " podman logs -f licserver # license server logs"
|
||||||
|
echo " podman logs -f o11v4-app # app logs"
|
||||||
|
echo " podman exec -it o11v4-app bash # shell into app"
|
||||||
|
echo " ./pod-stop.sh # stop everything"
|
||||||
|
echo ""
|
||||||
37
pod-stop.ps1
Normal file
37
pod-stop.ps1
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
###############################################################################
|
||||||
|
# pod-stop.ps1 — Stop and remove the o11v4 pod and all its containers
|
||||||
|
#
|
||||||
|
# Usage: .\pod-stop.ps1
|
||||||
|
# .\pod-stop.ps1 -PodName my-pod
|
||||||
|
# .\pod-stop.ps1 -RemoveImage # also delete the built image
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$PodName = "o11v4-pod",
|
||||||
|
[string]$ImageName = "o11v4",
|
||||||
|
[switch]$RemoveImage
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "SilentlyContinue"
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Stopping pod '$PodName'..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
# ── Stop and remove the pod (takes all containers with it) ──────────────────
|
||||||
|
podman pod stop $PodName 2>$null
|
||||||
|
podman pod rm -f $PodName 2>$null
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0 -or $true) {
|
||||||
|
Write-Host "Pod stopped and removed." -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Optionally remove the image ─────────────────────────────────────────────
|
||||||
|
if ($RemoveImage) {
|
||||||
|
Write-Host "Removing image '$ImageName'..." -ForegroundColor Yellow
|
||||||
|
podman rmi $ImageName 2>$null
|
||||||
|
Write-Host "Image removed." -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Done. To start again: .\pod-start.ps1" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
43
pod-stop.sh
Normal file
43
pod-stop.sh
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
###############################################################################
|
||||||
|
# pod-stop.sh — Stop and remove the o11v4 pod and all its containers
|
||||||
|
#
|
||||||
|
# Usage: ./pod-stop.sh
|
||||||
|
# ./pod-stop.sh --pod my-pod
|
||||||
|
# ./pod-stop.sh --remove-image # also delete the built image
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
POD_NAME="o11v4-pod"
|
||||||
|
IMAGE_NAME="o11v4"
|
||||||
|
REMOVE_IMAGE=false
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--pod) POD_NAME="$2"; shift 2 ;;
|
||||||
|
--image) IMAGE_NAME="$2"; shift 2 ;;
|
||||||
|
--remove-image) REMOVE_IMAGE=true; shift ;;
|
||||||
|
*) echo "Unknown option: $1"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Stopping pod '$POD_NAME'..."
|
||||||
|
|
||||||
|
# ── Stop and remove the pod (takes all containers with it) ──────────────────
|
||||||
|
podman pod stop "$POD_NAME" 2>/dev/null || true
|
||||||
|
podman pod rm -f "$POD_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "Pod stopped and removed."
|
||||||
|
|
||||||
|
# ── Optionally remove the image ─────────────────────────────────────────────
|
||||||
|
if [ "$REMOVE_IMAGE" = true ]; then
|
||||||
|
echo "Removing image '$IMAGE_NAME'..."
|
||||||
|
podman rmi "$IMAGE_NAME" 2>/dev/null || true
|
||||||
|
echo "Image removed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done. To start again: ./pod-start.sh"
|
||||||
|
echo ""
|
||||||
29
run.sh
Normal file
29
run.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Remove old /home/o11 entries from /etc/fstab
|
||||||
|
sed -i '/home\/o11/d' /etc/fstab
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Append new tmpfs entries to /etc/fstab
|
||||||
|
cat <<EOL >> /etc/fstab
|
||||||
|
|
||||||
|
tmpfs /home/o11/hls tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=70% 0 0
|
||||||
|
tmpfs /home/o11/dl tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=70% 0 0
|
||||||
|
EOL
|
||||||
|
|
||||||
|
# Mount all entries in /etc/fstab
|
||||||
|
mount -av
|
||||||
|
|
||||||
|
# Infinite loop to check if o11 is running
|
||||||
|
while true; do
|
||||||
|
if ! pgrep "o11v4" > /dev/null; then
|
||||||
|
# Start the o11 process
|
||||||
|
/home/o11/o11v4 -p 8484 -noramfs -f /usr/local/bin/ffmpeg -path "/home/o11/" -noautostart -plstreamname "%s [%p]" &
|
||||||
|
|
||||||
|
# Wait before checking again to give the process time to start
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait before checking again
|
||||||
|
sleep 20
|
||||||
|
done
|
||||||
112
server.js
Normal file
112
server.js
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
const https = require('https');
|
||||||
|
const http = require('http');
|
||||||
|
const express = require('express');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
|
const hostspath = '/etc/hosts';
|
||||||
|
const domain = 'lic.cryptolive.one';
|
||||||
|
const domain2 = 'lic.bitmaster.cc';
|
||||||
|
const ipAddress = '';
|
||||||
|
const portHttp = 80;
|
||||||
|
const portHttps = 443;
|
||||||
|
|
||||||
|
// Start Express Server
|
||||||
|
const app = express();
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({ extended: true }));
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
console.log(`Received POST request to ${req.url}`);
|
||||||
|
console.log('Headers:', req.headers);
|
||||||
|
console.log('Body:', req.body);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use('/', express.static('www'));
|
||||||
|
|
||||||
|
// Handle POST /lic requests
|
||||||
|
app.post('/lic', (req, res) => {
|
||||||
|
console.log('Received POST /lic request');
|
||||||
|
|
||||||
|
// Define the file path
|
||||||
|
const filePath = path.join(__dirname, 'lic.cr');
|
||||||
|
|
||||||
|
// Check if the file exists
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
console.error('File not found:', filePath);
|
||||||
|
return res.status(404).send('File not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the file as a response
|
||||||
|
res.sendFile(filePath, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error sending file:', err);
|
||||||
|
res.status(500).send('Error sending file');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Generate self-signed certificates if they don't exist
|
||||||
|
const certPath = './certs';
|
||||||
|
const keyFile = `${certPath}/key.pem`;
|
||||||
|
const certFile = `${certPath}/cert.pem`;
|
||||||
|
|
||||||
|
if (!fs.existsSync(certPath)) {
|
||||||
|
fs.mkdirSync(certPath, { recursive: true }); // Ensure the directory exists
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(keyFile) || !fs.existsSync(certFile)) {
|
||||||
|
exec(
|
||||||
|
`openssl req -x509 -newkey rsa:2048 -keyout ${keyFile} -out ${certFile} -days 365 -nodes -subj "/CN=localhost"`,
|
||||||
|
{ stdio: 'inherit' } // Show output in console
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
key: fs.readFileSync(keyFile),
|
||||||
|
cert: fs.readFileSync(certFile)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start HTTP and HTTPS servers
|
||||||
|
[80, 5454].forEach(port => {
|
||||||
|
http.createServer(app).listen(port, () => {
|
||||||
|
console.log(`HTTP server running on port ${port}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
https.createServer(options, app).listen(portHttps, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(`Error starting HTTPS server: ${err.message}`);
|
||||||
|
} else{
|
||||||
|
console.log(`HTTPS server running on port ${portHttps}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Function to update the /etc/hosts file
|
||||||
|
function updateHosts() {
|
||||||
|
try {
|
||||||
|
let content = fs.readFileSync(hostspath, 'utf8').split('\n');
|
||||||
|
|
||||||
|
content = content.filter(line => !line.includes(domain));
|
||||||
|
content.push(`${ipAddress} ${domain}`);
|
||||||
|
fs.writeFileSync(hostspath, content.join('\n'));
|
||||||
|
console.log(`Successfully mapped ${domain} to ${ipAddress} in ${hostspath}`);
|
||||||
|
|
||||||
|
content = fs.readFileSync(hostspath, 'utf8').split('\n');
|
||||||
|
content = content.filter(line => !line.includes(domain2));
|
||||||
|
content.push(`${ipAddress} ${domain2}`);
|
||||||
|
fs.writeFileSync(hostspath, content.join('\n'));
|
||||||
|
console.log(`Successfully mapped ${domain2} to ${ipAddress} in ${hostspath}`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error updating hosts file: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run tasks
|
||||||
|
updateHosts();
|
||||||
Loading…
Reference in New Issue
Block a user