Skip to content

Commit

Permalink
chore: update nginx conf
Browse files Browse the repository at this point in the history
  • Loading branch information
alberto-abarzua committed Nov 16, 2023
1 parent 8c8c3b9 commit 918dab3
Show file tree
Hide file tree
Showing 30 changed files with 714 additions and 289 deletions.
1 change: 0 additions & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ COPY ./pdm.lock ./pdm.lock

COPY . .

RUN ls -la && sleep 5
RUN pdm remove ribot-controller || true && \
pdm remove ribot-controller --dev || true

Expand Down
2 changes: 1 addition & 1 deletion backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dev = [


[tool.pdm.scripts]
start = "pdm run uvicorn src.main:app --host 0.0.0.0"
start = "pdm run uvicorn src.main:app --host 0.0.0.0 --port ${BACKEND_HTTP_PORT} --reload"
isort = "isort src"
black = "black src"
pure_lint = "flake8 src"
Expand Down
10 changes: 10 additions & 0 deletions backend/src/routers/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,13 @@ def config_from_file(
def list_configs() -> Dict[Any, Any]:
CONFIG_PATH = Path(__file__).parent.parent / "config"
return {"configs": [str(f) for f in CONFIG_PATH.iterdir() if f.is_file()]}


@router.get("/websocket_info")
def websocket_info(
controller: ArmController = controller_dependency,
) -> Dict[Any, Any]:

return {
"websocket_port": controller.websocket_port,
}
152 changes: 152 additions & 0 deletions backend/src/utils/instance_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import socket
import threading
import subprocess
import os
import time
from pathlib import Path
import redis
import json
import random

PARENT_FILE_PATH = Path(__file__).parent


DOCKER_COMPOSE_FILE_PATH = PARENT_FILE_PATH / "firmware-controller-compose.yaml"


class InstanceGenerator:
def __init__(self):
self.docker_compose_path = str(DOCKER_COMPOSE_FILE_PATH)
self.redis_client = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)
self.start_instance_checker()

def get_instances(self):
return self.instances

@property
def instances(self):
json_str = self.redis_client.get('instances')
if json_str is None:
return {}
else:
return json.loads(str(json_str))

@instances.setter
def instances(self, value):
self.redis_client.set('instances', json.dumps(value))

def get_instance(self, uuid_str):
if uuid_str in self.instances:
return self.instances[uuid_str]
else:
return None

def isntance_checker_target_fun(self):
while True:
for uuid_str in self.instances:
instance = self.instances[uuid_str]
if time.time() - instance['time_started'] > 30 * 60:
self.destroy(uuid_str)
time.sleep(10)

def start_instance_checker(self):
thread = threading.Thread(target=self.isntance_checker_target_fun)
thread.start()

def get_free_port(self,start, end):
for _ in range(start, end):
port = random.randint(start, end)
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', port))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
except OSError:
continue
raise IOError("No free ports available in the specified range")


def get_project_name(self, uuid_str):
return f"rtwin_instance_{uuid_str}"

def get_or_create(self, uuid_str):
instances = self.instances

if uuid_str in instances:
return instances[uuid_str]

# Generate unique ports
backend_http_port = self.get_free_port()
controller_websocket_port = self.get_free_port()
controller_server_port = self.get_free_port()

# Set environment variables for Docker Compose
env_vars = {
"BACKEND_HTTP_PORT": str(backend_http_port),
"CONTROLLER_WEBSOCKET_PORT": str(controller_websocket_port),
"CONTROLLER_SERVER_PORT": str(controller_server_port),
"ESP_CONTROLLER_SERVER_PORT": str(controller_server_port),
}

# Define the project name based on UUID
project_name = self.get_project_name(uuid_str)

# Launch Docker Compose
# result = subprocess.run(
# ["docker-compose", "-f", self.docker_compose_path, "-p", project_name, "up", "-d"],
# env={**os.environ, **env_vars})

command = ["docker-compose", "-f", self.docker_compose_path, "-p", project_name, "up", "-d"]

result = subprocess.check_call(command, env={**os.environ, **env_vars})
if result != 0:
raise Exception("Docker Compose failed")

# Store instance data
instances[uuid_str] = {
"ports": {
"backend_http_port": backend_http_port,
"controller_websocket_port": controller_websocket_port,
"controller_server_port": controller_server_port
},
'time_started': time.time(),

}


self.instances = instances

return instances[uuid_str]

def destroy(self, uuid_str):
if uuid_str in self.instances:
project_name = self.get_project_name(uuid_str)
isntances = self.instances
instance = isntances[uuid_str]

# get env variables
env_vars = {
"BACKEND_HTTP_PORT": str(instance['ports']['backend_http_port']),
"CONTROLLER_WEBSOCKET_PORT": str(instance['ports']['controller_websocket_port']),
"CONTROLLER_SERVER_PORT": str(instance['ports']['controller_server_port']),
"ESP_CONTROLLER_SERVER_PORT": str(instance['ports']['controller_server_port']),
}
command = ["docker-compose", "-f", self.docker_compose_path, "-p", project_name, "down","--remove-orphans"]
result = subprocess.check_call(command, env={**os.environ, **env_vars})
if result != 0:
raise Exception("Docker Compose failed")
instances = self.instances
del instances[uuid_str]
self.instances = instances

def destroy_all(self):
instances = self.instances
for uuid_str in instances:
self.destroy(uuid_str)

def get_backend_port(self, uuid_str):
instances = self.instances
port = None
if uuid_str in instances:
port = instances[uuid_str]['ports']['backend_http_port']
return port
1 change: 1 addition & 0 deletions controller/src/ribot/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def __init__(

self.controller_server: ControllerServer = ControllerServer(self, server_port)
self.websocket_server: Optional[WebsocketServer] = WebsocketServer(self, websocket_port)
self.websocket_port = websocket_port
self.file_reload_thread: Optional[threading.Thread] = None

self.message_op_handlers: Dict[MessageOp, Callable[[Message], None]] = {
Expand Down
4 changes: 1 addition & 3 deletions docker_services/backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ services:
volumes:
- ../backend/src:/app/src
- ../backend/pyproject.toml:/app/pyproject.toml
- ../backend/src/config/main_arm.toml:/app/src/config/main_arm.toml
- ../backend/pdm.lock:/app/pdm.lock
- ../controller:/app/controller
ports:
Expand All @@ -19,8 +20,5 @@ services:
environment:
- BACKEND_HTTP_PORT
- CONTROLLER_WEBSOCKET_PORT
- BACKEND_UPDATE_RIBOT_CONTROLLER
- CONTROLLER_SERVER_PORT

volumes:
pdm_cache:
1 change: 1 addition & 0 deletions docker_services/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ services:
- PDM_OVERRIDE_VERSION=$CONTROLLER_PDM_OVERRIDE_VERSION
- PDM_INCREMENT_VERSION=$CONTROLLER_PDM_INCREMENT_VERSION
- CONTROLLER_PRINT_STATUS

1 change: 1 addition & 0 deletions docker_services/frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ services:
- VITE_ARM_SIMULATION_WEBSOCKET_PORT
- VITE_ARM_SIMULATION_WEBSOCKET_HOST
- VITE_ARM_SIMULATION_URL
- VITE_INSTANCIATOR_URL
31 changes: 29 additions & 2 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
import MainView from './views/MainView';
import instanciatorApi from '@/utils/instanciator_api';
import MainView from '@/views/MainView';
import { useEffect } from 'react';

function App() {
return <MainView></MainView>;
useEffect(() => {
console.log('useEffect triggered'); // Log when useEffect is triggered

const getBackendInfo = async () => {
console.log('getBackendInfo function called'); // Log at the start of getBackendInfo
let envBackendUrl = import.meta.env.VITE_BACKEND_URL;
console.log('VITE_BACKEND_URL:', envBackendUrl); // Log the environment variable

if (envBackendUrl === undefined || envBackendUrl === 'no_backend') {
console.log('Fetching backend URL from API'); // Log when fetching from API
const response = await instanciatorApi.get('/backend_url/');
console.log('Response from API:', response); // Log the response from the API
const { backend_url } = response.data;
window.localStorage.setItem('backendUrl', backend_url);
console.log('Backend URL saved to local storage from API:', backend_url);
} else {
console.log('Saving env variable to local storage:', envBackendUrl); // Log when saving from env variable
window.localStorage.setItem('backendUrl', envBackendUrl);
}
};

getBackendInfo().catch(console.error); // Call getBackendInfo and catch any errors
}, []);

return <MainView />;
}

export default App;
2 changes: 0 additions & 2 deletions frontend/src/components/actions/ActionContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const ActionContainer = ({ actionList, action = null }) => {
const dispatch = useDispatch();
const byId = useContext(byIdContext);
const [isOver, setIsOver] = useState(false);
console.log('IN action container', action);

actionList = actionList.map(action => byId[action.id]);
const [, drop] = useDrop({
Expand All @@ -30,7 +29,6 @@ const ActionContainer = ({ actionList, action = null }) => {
const reader = new FileReader();
reader.onload = event => {
const actionToAdd = JSON.parse(event.target.result);
console.log('action container drop', action);
dispatch(
actionListActions.addFromJson({
actionId: action ? action.id : null,
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/components/actions/ActionsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ const ActionPanel = () => {

const actionList = actionSlice.actions;
const byId = actionSlice.byId;
console.log(byId);
console.log(actionList);

const [running, setRunning] = useState(false);
const runningRef = useRef(false);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/actions/ToolAction.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ToolAction = ({ action, ...props }) => {

useEffect(() => {
let valid = toolValue.toolValue >= -100 && toolValue.toolValue <= 100;
dispatch(actionListActions.setValid({ actionId: id, valid: valid }));
dispatch(actionListActions.setValidStatus({ actionId: id, valid: valid }));

dispatch(actionListActions.setActionValue({ actionId: id, value: toolValue }));
}, [toolValue, dispatch, id]);
Expand Down
19 changes: 17 additions & 2 deletions frontend/src/components/armsimulation/ArmSimulation.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import api from '@/utils/api';
import { useEffect, useState } from 'react';
const ArmSimulation = () => {
const [websocketPort, setWebsocketPort] = useState(0);

const simulation_url = import.meta.env.VITE_ARM_SIMULATION_URL;
const websocket_port = import.meta.env.VITE_ARM_SIMULATION_WEBSOCKET_PORT;
const websocket_host = import.meta.env.VITE_ARM_SIMULATION_WEBSOCKET_HOST;

useEffect(() => {
const getWebsocketInfo = async () => {
const response = await api.get('/settings/websocket_info/');
const { websocket_port } = response.data;
setWebsocketPort(websocket_port);
};
getWebsocketInfo();

console.log('this is the websocket port');
console.log(websocketPort, simulation_url, websocket_host);
}, []);

return (
<div className="relative h-full w-full">
<iframe
src={`${simulation_url}/game.html?ip=${websocket_host}&port=${websocket_port}`}
src={`${simulation_url}/game.html?ip=${websocket_host}&port=${websocketPort}`}
className="absolute left-0 top-0 h-full w-full cursor-none border-none"
></iframe>
<div className="absolute inset-0 bg-transparent"></div>
Expand Down
9 changes: 4 additions & 5 deletions frontend/src/utils/api.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import axios from 'axios';

let backendUrl = import.meta.env.VITE_BACKEND_URL;
if (backendUrl && backendUrl.startsWith('"') && backendUrl.endsWith('"')) {
backendUrl = backendUrl.slice(1, -1);
}

const api = axios.create({
baseURL: backendUrl,
withCredentials: true,
baseURL: window.localStorage.getItem('backendUrl'),
});

api.interceptors.request.use(
Expand All @@ -18,4 +15,6 @@ api.interceptors.request.use(
}
);



export default api;
23 changes: 23 additions & 0 deletions frontend/src/utils/instanciator_api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

import axios from 'axios';

let instanciatorUrl = import.meta.env.VITE_INSTANCIATOR_URL;

console.log("instanciatorUrl: ", instanciatorUrl);
const instanciatorApi = axios.create({
baseURL: instanciatorUrl,
withCredentials: true,
});

instanciatorApi.interceptors.request.use(
config => {
return config;
},
error => {
return Promise.reject(error);
}
);


export default instanciatorApi;

5 changes: 0 additions & 5 deletions instanciator/.flake8

This file was deleted.

3 changes: 0 additions & 3 deletions instanciator/Dockerfile

This file was deleted.

Loading

0 comments on commit 918dab3

Please sign in to comment.