mirror of
https://github.com/maxbarsukov/itmo.git
synced 2026-09-12 19:19:57 +05:00
feat(fog): ✨ add labs and reports
This commit is contained in:
parent
1d3aa14a60
commit
37f8b85021
4
7 оитв/лабораторные/lab1/.env.example
Normal file
4
7 оитв/лабораторные/lab1/.env.example
Normal file
@ -0,0 +1,4 @@
|
||||
REDIS_PASSWORD=password
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
68
7 оитв/лабораторные/lab1/.gitignore
vendored
Normal file
68
7 оитв/лабораторные/lab1/.gitignore
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
__pycache__/
|
||||
*.py[codz]
|
||||
*$py.class
|
||||
*.so
|
||||
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
.python-version
|
||||
Pipfile.lock
|
||||
poetry.lock
|
||||
poetry.toml
|
||||
__pypackages__/
|
||||
|
||||
*.rdb
|
||||
*.aof
|
||||
*.pid
|
||||
|
||||
.env
|
||||
.envrc
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
.idea/
|
||||
.vscode/
|
||||
18
7 оитв/лабораторные/lab1/Dockerfile
Normal file
18
7 оитв/лабораторные/lab1/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
FLASK_APP=app.py \
|
||||
FLASK_RUN_HOST=0.0.0.0 \
|
||||
FLASK_RUN_PORT=5000
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY app/requirements.txt ./
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY app/ ./
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]
|
||||
29
7 оитв/лабораторные/lab1/app/app.py
Normal file
29
7 оитв/лабораторные/lab1/app/app.py
Normal file
@ -0,0 +1,29 @@
|
||||
import os
|
||||
from flask import Flask, jsonify
|
||||
import redis
|
||||
|
||||
redis_client = redis.Redis(
|
||||
host=os.getenv("REDIS_HOST", "redis"),
|
||||
port=int(os.getenv("REDIS_PORT", "6379")),
|
||||
db=int(os.getenv("REDIS_DB", "0")),
|
||||
password=os.getenv("REDIS_PASSWORD"),
|
||||
decode_responses=True,
|
||||
)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
count = redis_client.incr("hits")
|
||||
return jsonify(visit_count=count), 200
|
||||
|
||||
@app.route("/health")
|
||||
def health():
|
||||
try:
|
||||
redis_client.ping()
|
||||
return jsonify(status="ok"), 200
|
||||
except redis.RedisError as exc:
|
||||
return jsonify(status="failed", detail=str(exc)), 500
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000)
|
||||
2
7 оитв/лабораторные/lab1/app/requirements.txt
Normal file
2
7 оитв/лабораторные/lab1/app/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Flask==2.3.3
|
||||
redis==5.0.1
|
||||
34
7 оитв/лабораторные/lab1/docker-compose.yml
Normal file
34
7 оитв/лабораторные/lab1/docker-compose.yml
Normal file
@ -0,0 +1,34 @@
|
||||
services:
|
||||
frontend:
|
||||
build: .
|
||||
image: lab1-frontend:latest
|
||||
ports:
|
||||
- "5002:5000"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- REDIS_HOST=${REDIS_HOST:-redis}
|
||||
- REDIS_PORT=${REDIS_PORT:-6379}
|
||||
- REDIS_DB=${REDIS_DB:-0}
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD}
|
||||
depends_on:
|
||||
- redis
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: any
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
env_file:
|
||||
- .env
|
||||
command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"]
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: any
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
BIN
7 оитв/лабораторные/lab1/docs/report.docx
Normal file
BIN
7 оитв/лабораторные/lab1/docs/report.docx
Normal file
Binary file not shown.
BIN
7 оитв/лабораторные/lab1/docs/report.pdf
Normal file
BIN
7 оитв/лабораторные/lab1/docs/report.pdf
Normal file
Binary file not shown.
7
7 оитв/лабораторные/lab2/.env.example
Normal file
7
7 оитв/лабораторные/lab2/.env.example
Normal file
@ -0,0 +1,7 @@
|
||||
REDIS_PASSWORD=password
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
APP_PORT=5000
|
||||
APP_NODE_PORT=31010
|
||||
APP_REPLICAS=3
|
||||
68
7 оитв/лабораторные/lab2/.gitignore
vendored
Normal file
68
7 оитв/лабораторные/lab2/.gitignore
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
__pycache__/
|
||||
*.py[codz]
|
||||
*$py.class
|
||||
*.so
|
||||
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
.python-version
|
||||
Pipfile.lock
|
||||
poetry.lock
|
||||
poetry.toml
|
||||
__pypackages__/
|
||||
|
||||
*.rdb
|
||||
*.aof
|
||||
*.pid
|
||||
|
||||
.env
|
||||
.envrc
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
.idea/
|
||||
.vscode/
|
||||
18
7 оитв/лабораторные/lab2/Dockerfile
Normal file
18
7 оитв/лабораторные/lab2/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
FLASK_APP=app.py \
|
||||
FLASK_RUN_HOST=0.0.0.0 \
|
||||
FLASK_RUN_PORT=5000
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY app/requirements.txt ./
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY app/ ./
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]
|
||||
29
7 оитв/лабораторные/lab2/app/app.py
Normal file
29
7 оитв/лабораторные/lab2/app/app.py
Normal file
@ -0,0 +1,29 @@
|
||||
import os
|
||||
from flask import Flask, jsonify
|
||||
import redis
|
||||
|
||||
redis_client = redis.Redis(
|
||||
host=os.getenv("REDIS_HOST", "redis"),
|
||||
port=int(os.getenv("REDIS_PORT", "6379")),
|
||||
db=int(os.getenv("REDIS_DB", "0")),
|
||||
password=os.getenv("REDIS_PASSWORD"),
|
||||
decode_responses=True,
|
||||
)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
count = redis_client.incr("hits")
|
||||
return jsonify(visit_count=count, message="Hello"), 200
|
||||
|
||||
@app.route("/health")
|
||||
def health():
|
||||
try:
|
||||
redis_client.ping()
|
||||
return jsonify(status="ok"), 200
|
||||
except redis.RedisError as exc:
|
||||
return jsonify(status="failed", detail=str(exc)), 500
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000)
|
||||
2
7 оитв/лабораторные/lab2/app/requirements.txt
Normal file
2
7 оитв/лабораторные/lab2/app/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Flask==2.3.3
|
||||
redis==5.0.1
|
||||
BIN
7 оитв/лабораторные/lab2/docs/report.docx
Normal file
BIN
7 оитв/лабораторные/lab2/docs/report.docx
Normal file
Binary file not shown.
BIN
7 оитв/лабораторные/lab2/docs/report.pdf
Normal file
BIN
7 оитв/лабораторные/lab2/docs/report.pdf
Normal file
Binary file not shown.
25
7 оитв/лабораторные/lab2/k8s/app-deployment.yaml
Normal file
25
7 оитв/лабораторные/lab2/k8s/app-deployment.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: python-app
|
||||
spec:
|
||||
replicas: ${APP_REPLICAS}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: python-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: python-app
|
||||
spec:
|
||||
containers:
|
||||
- name: python-app
|
||||
image: ${APP_IMAGE}
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: ${APP_PORT}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: app-config
|
||||
- secretRef:
|
||||
name: app-secrets
|
||||
12
7 оитв/лабораторные/lab2/k8s/app-service.yaml
Normal file
12
7 оитв/лабораторные/lab2/k8s/app-service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: python-app-service
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: python-app
|
||||
ports:
|
||||
- port: ${APP_PORT}
|
||||
targetPort: ${APP_PORT}
|
||||
nodePort: ${APP_NODE_PORT}
|
||||
16
7 оитв/лабораторные/lab2/k8s/config.yaml
Normal file
16
7 оитв/лабораторные/lab2/k8s/config.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: app-secrets
|
||||
type: Opaque
|
||||
stringData:
|
||||
REDIS_PASSWORD: password
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: app-config
|
||||
data:
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: "${REDIS_PORT}"
|
||||
REDIS_DB: "0"
|
||||
23
7 оитв/лабораторные/lab2/k8s/redis-deployment.yaml
Normal file
23
7 оитв/лабораторные/lab2/k8s/redis-deployment.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7-alpine
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: app-secrets
|
||||
command: ["sh", "-c", "redis-server --appendonly yes --requirepass $REDIS_PASSWORD"]
|
||||
ports:
|
||||
- containerPort: ${REDIS_PORT}
|
||||
11
7 оитв/лабораторные/lab2/k8s/redis-service.yaml
Normal file
11
7 оитв/лабораторные/lab2/k8s/redis-service.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: redis
|
||||
ports:
|
||||
- port: ${REDIS_PORT}
|
||||
targetPort: ${REDIS_PORT}
|
||||
26
7 оитв/лабораторные/lab3/cloud_dashboard/cloud_dashboard.py
Normal file
26
7 оитв/лабораторные/lab3/cloud_dashboard/cloud_dashboard.py
Normal file
@ -0,0 +1,26 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
import os
|
||||
import json
|
||||
|
||||
BROKER = os.getenv("MQTT_BROKER", "cloud-broker")
|
||||
PORT = int(os.getenv("MQTT_PORT", 1883))
|
||||
TOPIC = os.getenv("MQTT_TOPIC", "cloud/alerts")
|
||||
|
||||
def on_connect(client, userdata, flags, reason_code, properties):
|
||||
print(f"Connected to Cloud Broker with result code {reason_code}")
|
||||
client.subscribe(TOPIC)
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
try:
|
||||
data = json.loads(msg.payload.decode())
|
||||
print(f"ALERT RECEIVED: Temp={data.get('temp')}°C at {data.get('ts')}")
|
||||
except:
|
||||
print(f"Received raw message: {msg.payload.decode()}")
|
||||
|
||||
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
|
||||
print(f"Connecting to {BROKER}...")
|
||||
client.connect(BROKER, PORT, 60)
|
||||
client.loop_forever()
|
||||
61
7 оитв/лабораторные/lab3/docker-compose.yml
Normal file
61
7 оитв/лабораторные/lab3/docker-compose.yml
Normal file
@ -0,0 +1,61 @@
|
||||
services:
|
||||
edge-broker:
|
||||
image: eclipse-mosquitto:2
|
||||
container_name: edge-broker
|
||||
ports:
|
||||
- "1883:1883"
|
||||
volumes:
|
||||
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
networks:
|
||||
- factory-net
|
||||
|
||||
sensor:
|
||||
build: ./sensor
|
||||
container_name: sensor
|
||||
environment:
|
||||
- MQTT_BROKER=edge-broker
|
||||
- MQTT_TOPIC=factory/temp
|
||||
depends_on:
|
||||
- edge-broker
|
||||
networks:
|
||||
- factory-net
|
||||
|
||||
fog-node:
|
||||
image: nodered/node-red
|
||||
container_name: fog-node
|
||||
ports:
|
||||
- "1880:1880"
|
||||
environment:
|
||||
- TZ=Europe/Moscow
|
||||
volumes:
|
||||
- node-red-data:/data
|
||||
networks:
|
||||
- factory-net
|
||||
|
||||
cloud-broker:
|
||||
image: eclipse-mosquitto:2
|
||||
container_name: cloud-broker
|
||||
ports:
|
||||
- "1884:1883"
|
||||
volumes:
|
||||
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
networks:
|
||||
- factory-net
|
||||
|
||||
cloud-dashboard:
|
||||
build: ./cloud_dashboard
|
||||
container_name: cloud-dashboard
|
||||
environment:
|
||||
- MQTT_BROKER=cloud-broker
|
||||
- MQTT_TOPIC=cloud/alerts
|
||||
depends_on:
|
||||
- cloud-broker
|
||||
networks:
|
||||
- factory-net
|
||||
|
||||
networks:
|
||||
factory-net:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
node-red-data:
|
||||
BIN
7 оитв/лабораторные/lab3/docs/report.docx
Normal file
BIN
7 оитв/лабораторные/lab3/docs/report.docx
Normal file
Binary file not shown.
BIN
7 оитв/лабораторные/lab3/docs/report.pdf
Normal file
BIN
7 оитв/лабораторные/lab3/docs/report.pdf
Normal file
Binary file not shown.
2
7 оитв/лабораторные/lab3/mosquitto.conf
Normal file
2
7 оитв/лабораторные/lab3/mosquitto.conf
Normal file
@ -0,0 +1,2 @@
|
||||
listener 1883
|
||||
allow_anonymous true
|
||||
30
7 оитв/лабораторные/lab3/sensor/sensor.py
Normal file
30
7 оитв/лабораторные/lab3/sensor/sensor.py
Normal file
@ -0,0 +1,30 @@
|
||||
import time
|
||||
import random
|
||||
import json
|
||||
import paho.mqtt.client as mqtt
|
||||
import os
|
||||
|
||||
BROKER = os.getenv("MQTT_BROKER", "edge-broker")
|
||||
PORT = int(os.getenv("MQTT_PORT", 1883))
|
||||
TOPIC = os.getenv("MQTT_TOPIC", "factory/temp")
|
||||
|
||||
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||
|
||||
def connect():
|
||||
while True:
|
||||
try:
|
||||
client.connect(BROKER, PORT, 60)
|
||||
print(f"Connected to {BROKER}:{PORT}")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"Connection failed: {e}. Retrying in 5s...")
|
||||
time.sleep(5)
|
||||
|
||||
connect()
|
||||
|
||||
while True:
|
||||
temp = random.randint(20, 100)
|
||||
payload = json.dumps({"temp": temp, "ts": time.time()})
|
||||
client.publish(TOPIC, payload)
|
||||
print(f"Sent: {payload} to {TOPIC}")
|
||||
time.sleep(1)
|
||||
Loading…
Reference in New Issue
Block a user