sync for dev 033026
This commit is contained in:
@ -56,6 +56,7 @@ REAL_API_KEY: "{{ lookup('password', '/dev/null length=64 chars=ascii_letters,di
|
||||
|
||||
# dashboard vars
|
||||
service_control_web_folder: "{{ service_folder }}/web"
|
||||
service_control_docker_folder: "{{ service_folder }}/docker"
|
||||
public_dashboard: true
|
||||
custom_port: "80"
|
||||
web_src: "/web"
|
||||
@ -63,19 +64,21 @@ web_src: "/web"
|
||||
# other vars
|
||||
quick_refresh: false
|
||||
x64_arch: true
|
||||
refresh_special: false
|
||||
special_server: "none"
|
||||
|
||||
# cosmostat_settings, will be for special_server defaults
|
||||
noisy_test: false
|
||||
debug_output: true
|
||||
debug_output: false
|
||||
secure_api: true
|
||||
push_redis: false
|
||||
run_background : true
|
||||
log_output: true
|
||||
update_frequency: "1"
|
||||
cosmostat_server: true
|
||||
cosmostat_server_api: "https://cosmostat.testy-cal.com/"
|
||||
cosmostat_server: false
|
||||
cosmostat_server_api: "https://cosmostat.matt-cloud.com/"
|
||||
local_api_address: "http://{{ cosmostat_server_ip }}:{{ custom_api_port }}/"
|
||||
cosmostat_server_reporter: false
|
||||
cosmostat_server_reporter: true
|
||||
# setting this to true for default install
|
||||
disable_local_api: true
|
||||
...
|
||||
@ -21,7 +21,8 @@ app_settings = {
|
||||
"REAL_API_KEY": ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(256)),
|
||||
"disable_local_api": False,
|
||||
"local_api_address": "http://10.200.27.20:5000/",
|
||||
"cosmostat_server_ip": "10.200.27.20"
|
||||
"cosmostat_server_ip": "10.200.27.20",
|
||||
"api_bind_ip": "192.168.37.1"
|
||||
}
|
||||
|
||||
with open('cosmostat_settings.yaml', 'r') as f:
|
||||
@ -71,10 +72,7 @@ def service_gateway_ip():
|
||||
return result
|
||||
|
||||
def redis_gateway_ip():
|
||||
if cosmostat_settings["secure_api"]:
|
||||
return cosmostat_bind_ip()
|
||||
else:
|
||||
return "0.0.0.0"
|
||||
return cosmostat_bind_ip()
|
||||
|
||||
def cosmostat_server_api():
|
||||
return cosmostat_settings["cosmostat_server_api"]
|
||||
|
||||
@ -170,11 +170,10 @@ def get_php_summary():
|
||||
system_components.append(this_component)
|
||||
|
||||
if run_cosmostat_server():
|
||||
print(cosmostat_client.name)
|
||||
client_uuid = cosmostat_server.get_uuid_from_hostname(cosmostat_client.name)
|
||||
print(client_uuid)
|
||||
data_timestamp = cosmostat_server.get_system(client_uuid)
|
||||
print(data_timestamp)
|
||||
log_string = f"Cosmostat Client Name: {cosmostat_client.name} - UUID: {client_uuid}- Timestamp: {data_timestamp}"
|
||||
log_data(log_output = log_string, log_level = "log_output")
|
||||
component_age = {
|
||||
"component_name": "Data Timestamp",
|
||||
"info_strings": f"Data is {data_timestamp} seconds old"
|
||||
@ -221,7 +220,10 @@ def create_client():
|
||||
if not cosmostat_server.check_uuid(payload["uuid"]):
|
||||
result = run_create_client(payload)
|
||||
else:
|
||||
result = {"message": "object already exists, skipping creation"}
|
||||
result = {
|
||||
"message": "object already exists, skipping creation",
|
||||
"system_exists": "True"
|
||||
}
|
||||
return jsonify(result), 200
|
||||
|
||||
# api to validate Cosmostat Class
|
||||
@ -280,6 +282,7 @@ def run_update_client(this_client):
|
||||
|
||||
return {
|
||||
"status": update_status,
|
||||
"client_updated": "True",
|
||||
"uuid": this_client["uuid"],
|
||||
"redis_data": this_client,
|
||||
"timestamp_update": timestamp_update
|
||||
@ -296,6 +299,7 @@ def run_create_client(this_client):
|
||||
update_status = f'created client {this_client["short_id"]}'
|
||||
return {
|
||||
"status": update_status,
|
||||
"client_created": "True",
|
||||
"uuid": this_client["uuid"],
|
||||
"client_properties": this_client,
|
||||
"timestamp_update": timestamp_update
|
||||
@ -372,13 +376,15 @@ def get_client_details():
|
||||
# Cosmostat Client Reporter
|
||||
def client_update():
|
||||
api_url = f"{cosmostat_server_api()}update_client"
|
||||
print(api_url)
|
||||
payload = get_client_payload(get_client_redis_data(human_readable = False), "redis_data")
|
||||
log_data(log_output = f"API Update Called - {api_url}", log_level = "debug_output")
|
||||
log_data(log_output = "client_update - redis data from local client:", log_level = "noisy_test")
|
||||
log_data(log_output = payload, log_level = "noisy_test")
|
||||
# execute API call
|
||||
result = client_submission_handler(api_url, payload)
|
||||
client_api_initialize()
|
||||
if not result or not result.get('client_updated'):
|
||||
log_data(log_output = f"Client not updated, initializing", log_level = "log_output")
|
||||
result = client_api_initialize()
|
||||
return result
|
||||
|
||||
# Cosmostat Client Initializer
|
||||
@ -434,6 +440,7 @@ if __name__ == '__main__':
|
||||
######################################
|
||||
### Main Functions
|
||||
######################################
|
||||
log_data(log_output = f"Main Function Start", log_level = "log_output")
|
||||
|
||||
# instantiate and return the Client System object
|
||||
def new_cosmos_client():
|
||||
@ -480,9 +487,13 @@ if __name__ == '__main__':
|
||||
######################################
|
||||
|
||||
# local client System Class Object
|
||||
log_data(log_output = f"Cosmostat Client Start", log_level = "log_output")
|
||||
cosmostat_client = new_cosmos_client()
|
||||
cosmostat_client.update_system_state()
|
||||
|
||||
# remote client reporter
|
||||
if app_settings["cosmostat_server_reporter"] and not app_settings["cosmostat_server"]:
|
||||
log_data(log_output = f"Initialize Client Reporter", log_level = "log_output")
|
||||
client_api_initialize()
|
||||
|
||||
######################################
|
||||
@ -491,15 +502,19 @@ if __name__ == '__main__':
|
||||
|
||||
cosmostat_server = None
|
||||
if run_cosmostat_server():
|
||||
log_data(log_output = f"Cosmostat Server Start", log_level = "log_output")
|
||||
cosmostat_server = new_cosmostat_server()
|
||||
this_client = get_client_payload(get_php_summary(), "client_properties")
|
||||
timestamp_update = cosmostat_server.add_system(system_dictionary = this_client)
|
||||
# moving this here so all the bits exist
|
||||
client_update()
|
||||
|
||||
######################################
|
||||
# send initial stats update to redis
|
||||
######################################
|
||||
|
||||
if app_settings["push_redis"] and not app_settings["disable_local_api"]:
|
||||
log_data(log_output = f"Initial Redis Push", log_level = "log_output")
|
||||
update_redis_server()
|
||||
|
||||
######################################
|
||||
@ -507,6 +522,7 @@ if __name__ == '__main__':
|
||||
######################################
|
||||
|
||||
if app_settings["run_background"] and not app_settings["disable_local_api"]:
|
||||
log_data(log_output = f"Background Function Initializing", log_level = "log_output")
|
||||
log_data(log_output = "Loading flask background subroutine...", log_level = "log_output")
|
||||
|
||||
scheduler.add_job(id='background_loop',
|
||||
@ -523,16 +539,18 @@ if __name__ == '__main__':
|
||||
######################################
|
||||
# Flask API
|
||||
######################################
|
||||
print(f"gateway: {service_gateway_ip()} - port: {service_api_port()}")
|
||||
log_data(log_output = f"gateway: {service_gateway_ip()} - port: {service_api_port()}", log_level = "log_output")
|
||||
if not app_settings["disable_local_api"]:
|
||||
log_data(log_output = f"Main API Start", log_level = "log_output")
|
||||
app.run(debug=False, host=service_gateway_ip(), port=service_api_port())
|
||||
else:
|
||||
# if local API disabled, phone home if configured
|
||||
print("Internal API Disabled.")
|
||||
log_data(log_output = f"Internal API Disabled", log_level = "log_output")
|
||||
cosmostat_client.update_system_state()
|
||||
client_update()
|
||||
while True:
|
||||
if int(time.time()) % 5 == 0 and not cosmostat_client.check_system_timer():
|
||||
cosmostat_client.update_system_state()
|
||||
client_update()
|
||||
time.sleep(0.5)
|
||||
cosmostat_client.update_system_state()
|
||||
client_update()
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
@ -91,7 +91,8 @@
|
||||
"Clock Speed"
|
||||
],
|
||||
"php_extra" :[
|
||||
"CPU Model"
|
||||
"CPU Model",
|
||||
"Core Count"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -236,12 +237,13 @@
|
||||
"name": "DVD",
|
||||
"description": "{Device Path} is a DVD or Virtual DVD drive.",
|
||||
"multi_check": "True",
|
||||
"device_list": "lsblk -d -o NAME,SIZE | grep sr0| awk '{print $1}'",
|
||||
"device_list": "lsblk -d -o NAME,SIZE | grep sr0 | awk '{print $1}'",
|
||||
"properties": {
|
||||
"Device Name": "echo {this_device}",
|
||||
"Device Path": "lsblk -d -o NAME,SIZE | grep -v -e 0B -e NAME | awk '{{print \"/dev/\"$1}}' | grep {this_device}",
|
||||
"Total Capacity": "lsblk -d -o NAME,SIZE | grep {this_device} | awk '{{print $2}}'"
|
||||
},
|
||||
"precheck": "lspci | grep sr0 | wc -l",
|
||||
"metrics": {
|
||||
"placeholder": ""
|
||||
}
|
||||
|
||||
91
files/docker/Dockerfile
Normal file
91
files/docker/Dockerfile
Normal file
@ -0,0 +1,91 @@
|
||||
# ------------------------------------------------------------------
|
||||
# 1. Base image
|
||||
# ------------------------------------------------------------------
|
||||
# We use a slim Debian base so we can use apt‑get to pull every
|
||||
# component in one go. Debian Bookworm contains all the
|
||||
# packages we need (nodejs 18, redis, nginx, php8‑fpm, etc.).
|
||||
# ------------------------------------------------------------------
|
||||
FROM php:8.0-apache
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 2. Build arguments – handy if you want to change the port numbers
|
||||
# without touching the Dockerfile
|
||||
# ------------------------------------------------------------------
|
||||
ARG REDIS_PORT=6379
|
||||
ARG NODE_PORT=3000
|
||||
ARG PHP_PORT=8080
|
||||
ARG NGX_PORT=80
|
||||
|
||||
ENV REDIS_PORT=${REDIS_PORT}
|
||||
ENV NODE_PORT=${NODE_PORT}
|
||||
ENV PHP_PORT=${PHP_PORT}
|
||||
ENV NGX_PORT=${NGX_PORT}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 3. Install all the system packages we need
|
||||
# ------------------------------------------------------------------
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
curl gnupg ca-certificates \
|
||||
nodejs npm \
|
||||
redis-server \
|
||||
nginx \
|
||||
supervisor \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 4. Prepare the working directories
|
||||
# ------------------------------------------------------------------
|
||||
# Node app
|
||||
WORKDIR /app
|
||||
COPY web/node_server/package.json ./
|
||||
RUN npm install
|
||||
COPY web/node_server/ ./
|
||||
|
||||
# Web‑dashboard static files
|
||||
COPY web/html /var/www/html/
|
||||
|
||||
# API settings file
|
||||
COPY cosmostat_settings.yaml /app/cosmostat_settings.yaml
|
||||
|
||||
# Nginx config – you can keep the same file you used for the
|
||||
# proxy service in the compose file. It will proxy 3000 (WS)
|
||||
# and 8080 (PHP) to the local container.
|
||||
COPY web/proxy/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 5. Supervisord configuration
|
||||
# ------------------------------------------------------------------
|
||||
# Create a minimal supervisord.conf that will launch the four
|
||||
# services from the same container.
|
||||
RUN mkdir -p /etc/supervisor/conf.d && \
|
||||
cat > /etc/supervisor/conf.d/supervisord.conf <<EOF
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:redis]
|
||||
command=/usr/bin/redis-server --port ${REDIS_PORT}
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=root
|
||||
|
||||
[program:node]
|
||||
command=npm run start
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=root
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g 'daemon off;'
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=root
|
||||
EOF
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 6. Expose the ports
|
||||
# ------------------------------------------------------------------
|
||||
EXPOSE ${REDIS_PORT} ${NGX_PORT}
|
||||
|
||||
# 7. Default command – start supervisord
|
||||
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||
48
files/docker/Dockerfile-1
Normal file
48
files/docker/Dockerfile-1
Normal file
@ -0,0 +1,48 @@
|
||||
FROM php:8.0-apache
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
curl \
|
||||
sudo \
|
||||
redis-server \
|
||||
nginx \
|
||||
supervisor \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Node application
|
||||
COPY web/node_server/ .
|
||||
RUN npm install --only=production
|
||||
|
||||
#RUN npm ci --production
|
||||
|
||||
# PHP static files (public web root)
|
||||
COPY web/html/ /var/www/html/
|
||||
|
||||
# NGINX config (overwrites the default)
|
||||
COPY web/proxy/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Shared settings file (read‑only)
|
||||
COPY cosmostat_settings.yaml /app/cosmostat_settings.yaml
|
||||
|
||||
# Supervisor configuration
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
# Entrypoint script
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
EXPOSE 6379
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||
|
||||
|
||||
6
files/docker/entrypoint.sh
Normal file
6
files/docker/entrypoint.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
# Ensure the shared config file is readable
|
||||
chmod 644 /app/cosmostat_settings.yaml
|
||||
|
||||
# Let Supervisor do the heavy lifting
|
||||
exec "$@"
|
||||
22
files/docker/supervisord.conf
Normal file
22
files/docker/supervisord.conf
Normal file
@ -0,0 +1,22 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:redis]
|
||||
command=/usr/bin/redis-server
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile=/dev/stderr
|
||||
|
||||
[program:node]
|
||||
command=sh -c "cd /app && node server.js"
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile=/dev/stderr
|
||||
|
||||
[program:apache]
|
||||
command=/usr/sbin/httpd -DFOREGROUND
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile=/dev/stderr
|
||||
|
||||
[program:nginx]
|
||||
command=nginx -g "daemon off;"
|
||||
stdout_logfile=/dev/stdout
|
||||
stderr_logfile=/dev/stderr
|
||||
@ -6,7 +6,7 @@ function h(string $s): string
|
||||
}
|
||||
|
||||
// Load API data
|
||||
$raw_api_settings = file('/opt/api_settings/cosmostat_settings.yaml',
|
||||
$raw_api_settings = file('/app/cosmostat_settings.yaml',
|
||||
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
|
||||
$api_settings = [];
|
||||
|
||||
@ -15,25 +15,20 @@
|
||||
pingTimeout: 5000,
|
||||
pingInterval: 25000,
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Color constants
|
||||
========================================================== */
|
||||
const GREEN = [ 39, 174, 96]; // #27ae60
|
||||
const YELLOW = [243, 156, 18]; // #f39c12
|
||||
const RED = [192, 57, 43]; // #c0392b
|
||||
|
||||
/* ==========================================================
|
||||
Helpers
|
||||
========================================================== */
|
||||
const hostTimestamps = {}; // keyed by short_id
|
||||
|
||||
const toRgb = (r, g, b) => `rgb(${r},${g},${b})`;
|
||||
|
||||
const T20 = 20 * 1000;
|
||||
const T40 = 40 * 1000;
|
||||
const T60 = 60 * 1000;
|
||||
|
||||
function getFreshnessColor(ageMs) {
|
||||
if (ageMs <= T20) {
|
||||
return toRgb(...GREEN);
|
||||
@ -54,19 +49,16 @@
|
||||
}
|
||||
return toRgb(...RED);
|
||||
}
|
||||
|
||||
function safeSetText(id, txt) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = txt;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Get the short_id from the query string
|
||||
========================================================== */
|
||||
function getSelectedId() {
|
||||
return new URLSearchParams(window.location.search).get('host') || '';
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Sidebar building - uses short_id for status key
|
||||
========================================================== */
|
||||
@ -75,30 +67,24 @@
|
||||
const current = Array.from(ul.children).map(li => li.dataset.id);
|
||||
const newIds = systemList.map(s => s.short_id);
|
||||
if (arraysEqual(current, newIds)) return;
|
||||
|
||||
const selected = getSelectedId().toLowerCase();
|
||||
ul.innerHTML = ''; // reset list
|
||||
|
||||
systemList.forEach(item => {
|
||||
const li = document.createElement('li');
|
||||
|
||||
// status dot - keyed by short_id
|
||||
const status = document.createElement('span');
|
||||
status.className = 'host-status';
|
||||
status.dataset.id = item.short_id;
|
||||
|
||||
// link - display hostname, encode short_id in URL
|
||||
const a = document.createElement('a');
|
||||
a.href = '?host=' + encodeURIComponent(item.short_id);
|
||||
a.textContent = item.hostname;
|
||||
if (item.short_id.toLowerCase() === selected) a.classList.add('active');
|
||||
|
||||
li.appendChild(status);
|
||||
li.appendChild(a);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Update status colors every second
|
||||
========================================================== */
|
||||
@ -113,9 +99,7 @@
|
||||
if (span) span.style.backgroundColor = color;
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(updateStatusColors, 1000);
|
||||
|
||||
/* ==========================================================
|
||||
Utility helpers
|
||||
========================================================== */
|
||||
@ -124,7 +108,6 @@
|
||||
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderGenericTable(containerId, data, emptyMsg) {
|
||||
const container = document.getElementById(containerId);
|
||||
if (!Array.isArray(data) || !data.length) {
|
||||
@ -138,7 +121,6 @@
|
||||
container.innerHTML = '';
|
||||
container.appendChild(table);
|
||||
}
|
||||
|
||||
function mergeRowsByName(rows) {
|
||||
const groups = {}; // { Source: { Metric: [], Data: [] } }
|
||||
rows.forEach(r => {
|
||||
@ -156,7 +138,6 @@
|
||||
Data: g.Data,
|
||||
}));
|
||||
}
|
||||
|
||||
function orderRows(rows) {
|
||||
const priority = ['System', 'CPU', 'RAM'];
|
||||
const map = {};
|
||||
@ -167,7 +148,6 @@
|
||||
return ai - bi;
|
||||
});
|
||||
}
|
||||
|
||||
function buildTable(rows) {
|
||||
const cols = ['Source', 'Metric', 'Data'];
|
||||
const table = document.createElement('table');
|
||||
@ -200,12 +180,10 @@
|
||||
});
|
||||
return table;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Handle incoming data
|
||||
========================================================== */
|
||||
let lastUpdate = Date.now();
|
||||
|
||||
function handleSummary(raw) {
|
||||
lastUpdate = Date.now(); // reset watchdog
|
||||
let payload;
|
||||
@ -215,25 +193,20 @@
|
||||
return;
|
||||
}
|
||||
} else payload = raw;
|
||||
|
||||
if (!Array.isArray(payload) || !payload.length) {
|
||||
safeSetText('client_summary', 'No data available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the list first (so <span> elements exist)
|
||||
buildList(payload);
|
||||
|
||||
// Store the timestamp for every short_id
|
||||
payload.forEach(hostObj => {
|
||||
if (hostObj.short_id && hostObj.data_timestamp) {
|
||||
hostTimestamps[hostObj.short_id] = hostObj.data_timestamp; // seconds
|
||||
}
|
||||
});
|
||||
|
||||
// Immediately update colors for the current view
|
||||
updateStatusColors();
|
||||
|
||||
// Metric table for selected host
|
||||
const selectedId = getSelectedId();
|
||||
const hostObj = payload.find(h => h.short_id === selectedId) || payload[0];
|
||||
@ -242,7 +215,6 @@
|
||||
: [];
|
||||
renderGenericTable('host_metrics', hostData, 'No Stats available');
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Socket event wiring
|
||||
========================================================== */
|
||||
@ -258,7 +230,6 @@
|
||||
safeSetText('client_summary', `Re-connected (attempt ${attempt})`);
|
||||
requestSummary();
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Request logic
|
||||
========================================================== */
|
||||
@ -266,7 +237,6 @@
|
||||
if (!socket.connected) return; // guard against stale emits
|
||||
socket.emit('get_client_summary'); // server will reply via client_summary
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Recursive polling
|
||||
========================================================== */
|
||||
@ -279,7 +249,6 @@
|
||||
socket.on('connect', () => {
|
||||
if (!pollTimer) pollLoop();
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Watchdog - force reconnect if no data for 15 s
|
||||
========================================================== */
|
||||
@ -291,7 +260,6 @@
|
||||
setTimeout(watchdog, 5000);
|
||||
}
|
||||
watchdog();
|
||||
|
||||
/* ==========================================================
|
||||
Keep the 'active' link in sync when the URL changes
|
||||
========================================================== */
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
<?php
|
||||
# load API settings, this requires a simple yaml file
|
||||
$raw_api_settings = file('/opt/api_settings/cosmostat_settings.yaml', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$raw_api_settings = file('/app/cosmostat_settings.yaml', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$api_settings = [];
|
||||
foreach ($raw_api_settings as $line) {
|
||||
if ($line[0] === '#') {
|
||||
|
||||
@ -13,6 +13,15 @@
|
||||
state: stopped
|
||||
scope: user
|
||||
|
||||
# create service working folder
|
||||
- name: Cosmostat - API - create cosmos user service folder
|
||||
file:
|
||||
path: "{{ user_service_folder }}"
|
||||
state: directory
|
||||
owner: "{{ service_user }}"
|
||||
group: "{{ service_user }}"
|
||||
mode: '0755'
|
||||
|
||||
- name: Cosmostat - API - copy api files
|
||||
copy:
|
||||
src: api/
|
||||
|
||||
@ -59,6 +59,14 @@
|
||||
# allow user services to "linger"
|
||||
- name: Cosmostat - Init - cosmos user enable linger
|
||||
shell: "loginctl enable-linger {{ service_user }}"
|
||||
register: user_linger
|
||||
|
||||
# - name: Reboot target after linger change
|
||||
# reboot:
|
||||
# msg: "Cosmostat - Init - Rebooting target for linger enable"
|
||||
# pre_reboot_delay: 10
|
||||
# reboot_timeout: 600
|
||||
# when: user_linger.changed
|
||||
|
||||
# create service working folder
|
||||
- name: Cosmostat - Init - create cosmostat service folder
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
---
|
||||
|
||||
# refresh when refresh
|
||||
#- name: Quick refresh
|
||||
# when: refresh_special | bool
|
||||
# set_fact:
|
||||
# quick_refresh: true
|
||||
|
||||
# initializa environment
|
||||
- name: Initialize Environment
|
||||
when: not quick_refresh | bool
|
||||
@ -7,6 +13,7 @@
|
||||
|
||||
# set up API
|
||||
- name: Build API
|
||||
when: false
|
||||
include_tasks: api.yaml
|
||||
|
||||
# set up web stack
|
||||
|
||||
@ -3,45 +3,64 @@
|
||||
# This part sets up cosmostat web dashboard
|
||||
###############################################
|
||||
|
||||
- name: Cosmostat - Web - stop containers
|
||||
when: not quick_refresh | bool
|
||||
shell: "docker-compose -f {{ service_control_web_folder }}/docker-compose.yaml down"
|
||||
ignore_errors: yes
|
||||
#- name: Cosmostat - Web - stop containers
|
||||
# community.docker.docker_compose_v2:
|
||||
# project_src: "{{ service_control_docker_folder }}"
|
||||
# state: stopped
|
||||
# ignore_errors: yes
|
||||
|
||||
# Create web Folder
|
||||
- name: "Cosmostat - Web - create {{ service_control_web_folder }}"
|
||||
file:
|
||||
path: "{{ service_control_web_folder }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: "{{ service_user }}"
|
||||
group: "{{ service_user }}"
|
||||
#- name: "Cosmostat - Web - create {{ service_control_web_folder }}"
|
||||
# file:
|
||||
# path: "{{ service_control_web_folder }}"
|
||||
# state: directory
|
||||
# mode: '0755'
|
||||
# owner: "{{ service_user }}"
|
||||
# group: "{{ service_user }}"
|
||||
|
||||
- name: Cosmostat - Web - copy docker files
|
||||
copy:
|
||||
src: "web/"
|
||||
dest: "{{ service_control_web_folder }}"
|
||||
src: "docker/"
|
||||
dest: "{{ service_control_docker_folder }}"
|
||||
mode: 0755
|
||||
owner: "{{ service_user }}"
|
||||
group: "{{ service_user }}"
|
||||
|
||||
- name: Cosmostat - Web - copy web files
|
||||
copy:
|
||||
src: "web/"
|
||||
dest: "{{ service_control_docker_folder }}/web"
|
||||
mode: 0755
|
||||
owner: "{{ service_user }}"
|
||||
group: "{{ service_user }}"
|
||||
|
||||
- name: Cosmostat - Web - template docker-compose.yaml
|
||||
template:
|
||||
src: docker-compose-single.yaml
|
||||
dest: "{{ service_control_docker_folder }}/docker-compose.yaml"
|
||||
mode: 0644
|
||||
|
||||
- name: "Cosmostat - Web - template cosmostat_settings.yaml"
|
||||
template:
|
||||
src: cosmostat_settings.yaml
|
||||
dest: "{{ service_control_docker_folder }}/cosmostat_settings.yaml"
|
||||
owner: "{{ service_user }}"
|
||||
group: "{{ service_user }}"
|
||||
mode: 0644
|
||||
|
||||
#######################
|
||||
# configure as server
|
||||
- name: Cosmostat - Web - Configure Server Dashboard
|
||||
when: cosmostat_server | bool
|
||||
include_tasks: server.yaml
|
||||
|
||||
- name: Cosmostat - Web - template docker-compose.yaml
|
||||
template:
|
||||
src: docker-compose-php.yaml
|
||||
dest: "{{ service_control_web_folder }}/docker-compose.yaml"
|
||||
mode: 0644
|
||||
#- name: Cosmostat - Web - Start containers
|
||||
# community.docker.docker_compose_v2:
|
||||
# project_src: "{{ service_control_web_folder }}"
|
||||
# state: present
|
||||
# register: docker_output
|
||||
#- debug: |
|
||||
# msg="{{ docker_output.actions }}"
|
||||
|
||||
- name: Cosmostat - Web - Start containers
|
||||
shell: "docker-compose -f {{ service_control_web_folder }}/docker-compose.yaml up -d"
|
||||
register: docker_output
|
||||
- debug: |
|
||||
msg="{{ docker_output.stdout_lines }}"
|
||||
msg="{{ docker_output.stderr_lines }}"
|
||||
|
||||
...
|
||||
@ -34,12 +34,11 @@ services:
|
||||
- "{{ docker_gateway }}:8080:80"
|
||||
volumes:
|
||||
- ./html:/var/www/html/
|
||||
- "{{ api_service_folder }}/cosmostat_settings.yaml:/opt/api_settings/cosmostat_settings.yaml:ro"
|
||||
- "{{ api_service_folder }}/cosmostat_settings.yaml:/app/cosmostat_settings.yaml:ro"
|
||||
networks:
|
||||
- cosmostat_net
|
||||
restart: always
|
||||
|
||||
# public_dashboard: {{ public_dashboard }}
|
||||
cosmostat_nginx_proxy:
|
||||
container_name: cosmostat_nginx_proxy
|
||||
image: nginx:latest
|
||||
|
||||
35
templates/docker-compose-single.yaml
Normal file
35
templates/docker-compose-single.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
services:
|
||||
# cosmostat:
|
||||
# container_name: cosmostat
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: Dockerfile
|
||||
# ports:
|
||||
# - "{{ docker_gateway }}:6379:6379"
|
||||
# - "{{ (docker_gateway + ':') if not public_dashboard | bool else '' }}{{ custom_port }}:80"
|
||||
# networks:
|
||||
# - cosmostat_net
|
||||
# restart: always
|
||||
|
||||
cosmostat_all:
|
||||
container_name: cosmostat_all
|
||||
image: cosmostat-all:latest
|
||||
restart: always
|
||||
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
networks:
|
||||
- cosmostat_net
|
||||
|
||||
ports:
|
||||
- "{{ docker_gateway }}:6379:6379"
|
||||
- "{{ (docker_gateway + ':') if not public_dashboard | bool else '' }}{{ custom_port }}:80"
|
||||
volumes:
|
||||
- "/opt/cosmostat/docker/web/html:/var/www/html"
|
||||
- "/opt/cosmostat/docker/web/node_server:/app"
|
||||
- "/opt/cosmostat/cosmostat_settings.yaml:/app/cosmostat_settings.yaml:ro"
|
||||
|
||||
networks:
|
||||
cosmostat_net:
|
||||
external: true
|
||||
@ -11,4 +11,4 @@ Restart=always
|
||||
{{ extra_service_options }}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=default.target
|
||||
|
||||
Reference in New Issue
Block a user