Compare commits

..
23 Commits
Author SHA1 Message Date
brb cb2e45e5ae updated ignored modules 2023-07-14 14:56:04 +02:00
brb 824215c37a flake8 compliant 2023-07-14 14:55:42 +02:00
brb 0e39795b26 added definition of external worker process 2023-07-14 14:54:13 +02:00
brb 32e06d0d4e removed usage of external worker process 2023-07-14 14:53:46 +02:00
brb fd18d9450e updated root post to start script execution in background task 2023-07-14 14:53:20 +02:00
brb 31ddd80fae updated function to run directly via os.system and not in subprocess 2023-07-14 14:52:49 +02:00
brb c6fccb9047 updated test script 2023-07-14 14:52:02 +02:00
brb 8841724740 updated execution of script 2023-07-13 13:12:11 +02:00
brb db66de65b1 updated script 2023-07-13 13:10:45 +02:00
brb 6b165aa0ff updated to find moved runner script 2023-07-13 12:54:32 +02:00
brb aca204aa80 moved gpu_runner script 2023-07-13 12:53:05 +02:00
brb 1ef127d85f updated execute runner script 2023-07-13 12:48:51 +02:00
brb c6c56ef1cf updated execute runner script 2023-07-13 12:46:53 +02:00
brb a6a3464e7e updated execute runner script 2023-07-13 12:46:24 +02:00
brb 86834b1d7c updated execute runner script 2023-07-13 12:45:04 +02:00
brb 479674f807 updated repo_dir 2023-07-13 12:44:00 +02:00
brb 1e2e3e5e03 removed dev env vars 2023-07-13 12:42:03 +02:00
brb 70d78e8fa1 fixed bug with dev env vars 2023-07-13 12:39:35 +02:00
brb ddb9e4f9b4 fixed bug 2023-07-13 12:37:32 +02:00
brb e57f083b14 fixed bug 2023-07-13 12:35:52 +02:00
brb b4f1eab752 added test printing of var 2023-07-13 12:35:11 +02:00
brb 320efedd50 added test printing of var 2023-07-13 12:33:55 +02:00
brb 176d09ca34 added test printing of var 2023-07-13 12:31:49 +02:00
10 changed files with 134 additions and 43 deletions
+4
View File
@@ -0,0 +1,4 @@
script: |
echo "start of script"
sleep 15
echo "end of script"
+28 -28
View File
@@ -1,17 +1,23 @@
import uvicorn import uvicorn
from fastapi import FastAPI, Request, HTTPException from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from dotenv import load_dotenv from dotenv import load_dotenv
import logging import logging
import os import os
import httpx
from utils import clone_repository, execute_runner_script from utils import clone_repository, execute_script
from setup_logging import setup_logging from setup_logging import setup_logging
from gitea_request import GiteaRequest from gitea_request import GiteaRequest
app = FastAPI() app = FastAPI()
async def post_callback(url: str, payload: dict):
async with httpx.AsyncClient() as client:
await client.post(url, json=payload)
@app.get('/', response_class=HTMLResponse) @app.get('/', response_class=HTMLResponse)
async def root(): async def root():
content_str = """ content_str = """
@@ -39,7 +45,7 @@ async def test(request: Request):
@app.post('/') @app.post('/')
def handle_event(request: GiteaRequest): def handle_event(request: GiteaRequest, background_tasks: BackgroundTasks):
""" Handle event from webhook. """ """ Handle event from webhook. """
# extract information # extract information
commit_msg = request.head_commit['message'] commit_msg = request.head_commit['message']
@@ -53,30 +59,23 @@ def handle_event(request: GiteaRequest):
) )
# clone repository # clone repository
local_repo_dir = clone_repository(repo_url) local_repo_dir = clone_repository(repo_url)
# locate runner script # # locate runner script
runner_script_path = local_repo_dir / 'runner_script.yml' # runner_script_path = (
if not runner_script_path.exists(): # local_repo_dir /
raise HTTPException( # '.gitea' /
status_code=200, # 'gpu_runner' /
detail="no runner_script.yml in repository root" # 'script.yml'
) # )
# execute runner script # if not runner_script_path.exists():
logging.info('rexecuting runner script') # raise HTTPException(
execute_runner_script(path=runner_script_path) # status_code=200,
# # TODO: create virtualenv? # detail=f"{runner_script_path} does not exist"
# # install requirements # )
# assert pipeline.requirements is not None # queue runner script
# requirements_path = local_repo_dir / pipeline.requirements background_tasks.add_task(
# os.system(f'pip install -r {requirements_path}') execute_script,
# for cmd in pipeline.script: local_repo_dir
# try: )
# os.system(cmd)
# except Exception as e:
# raise HTTPException(
# status_code=503,
# detail=f'failed running {cmd}: {e}'
# )
# send response # send response
raise HTTPException( raise HTTPException(
status_code=202, status_code=202,
@@ -94,5 +93,6 @@ if __name__ == '__main__':
uvicorn.run( uvicorn.run(
app=app, app=app,
host=listen_ip, host=listen_ip,
port=listen_port port=listen_port,
workers=1
) )
+1 -1
View File
@@ -1,6 +1,6 @@
[main] [main]
logger_level=debug logger_level=debug
repo_dir=/usr/src/app/repo repo_dir=repo
[fastapi] [fastapi]
listen_ip=0.0.0.0 listen_ip=0.0.0.0
+10 -1
View File
@@ -7,7 +7,8 @@ import os
from configparser import ConfigParser from configparser import ConfigParser
from pathlib import Path from pathlib import Path
import socket import socket
# from multiprocessing import Queue
# from worker import Worker
# load default values # load default values
config = ConfigParser() config = ConfigParser()
@@ -23,9 +24,17 @@ if __name__ == '__main__':
listen_ip = os.getenv('LISTEN_IP', default=LISTEN_IP) listen_ip = os.getenv('LISTEN_IP', default=LISTEN_IP)
listen_port = int(os.getenv('LISTEN_PORT', default=LISTEN_PORT)) listen_port = int(os.getenv('LISTEN_PORT', default=LISTEN_PORT))
own_ip = socket.gethostbyname(socket.gethostname()) own_ip = socket.gethostbyname(socket.gethostname())
# # setup work queue
# work_queue: Queue = Queue()
# # setup worker process
# worker = Worker(queue=work_queue)
# start server
logging.info(f'starting FastAPI server ({own_ip}:{listen_port})') logging.info(f'starting FastAPI server ({own_ip}:{listen_port})')
# try:
uvicorn.run( uvicorn.run(
app=app, app=app,
host=listen_ip, host=listen_ip,
port=listen_port port=listen_port
) )
# except KeyboardInterrupt:
# worker.stop()
+1 -1
View File
@@ -24,6 +24,6 @@ class RunnerScript(BaseModel):
if __name__ == '__main__': if __name__ == '__main__':
path = Path(__file__).parent.parent / 'runner_script.yml' path = Path('.gitea') / 'gpu_runner' / 'script.yml'
rs = RunnerScript.from_file(path) rs = RunnerScript.from_file(path)
print(rs) print(rs)
+47 -7
View File
@@ -4,14 +4,22 @@ from git import Repo
import logging import logging
import shutil import shutil
import os import os
from configparser import ConfigParser
from runner_script import RunnerScript from runner_script import RunnerScript
def clone_repository(repo_url: AnyHttpUrl) -> Path: # load default values
config = ConfigParser()
config.read(Path(__file__).parent / 'defaults.ini')
REPO_DIR = config.get('main', 'repo_dir')
def clone_repository(
repo_url: AnyHttpUrl,
repo_dir: str = REPO_DIR
) -> Path:
# extract repo name # extract repo name
repo_name = repo_url.split('/')[-1].replace('.git', '') repo_name = repo_url.split('/')[-1].replace('.git', '')
repo_dir = os.getenv('REPO_DIR', default=None)
assert repo_dir is not None
dst_dir = Path(repo_dir) / repo_name dst_dir = Path(repo_dir) / repo_name
# prepare repo download dir # prepare repo download dir
if dst_dir.exists(): if dst_dir.exists():
@@ -23,8 +31,40 @@ def clone_repository(repo_url: AnyHttpUrl) -> Path:
return dst_dir return dst_dir
def execute_runner_script(path: Path) -> None: def execute_script(
script_list = RunnerScript.from_file(path) local_repo_dir: Path
for cmd in script_list: ) -> None:
os.system(cmd) # locate the script
script_path = (
local_repo_dir /
'.gitea' /
'gpu_runner' /
'script.yml'
)
# determine original working dir
org_dir = os.getcwd()
# initialise command list
cmd_list = [
f'cd {local_repo_dir.resolve()}',
'virtualenv -p python3.10 venv',
'source venv/bin/activate',
]
# add in runner script
rs = RunnerScript.from_file(path=script_path)
for cmd in rs.script:
cmd_list.append(cmd)
# append cleanup commands
cmd_list.append('deactivate')
cmd_list.append(f'cd {org_dir}')
cmd_list.append(f'rm -rf {local_repo_dir.resolve()}')
# build command string
cmd_str = ' && '.join(cmd_list)
os.system(cmd_str)
logging.debug('finished') logging.debug('finished')
if __name__ == '__main__':
local_repo_dir = Path(__file__).parent.parent / 'repo' / 'gpu_runner'
execute_script(
local_repo_dir=local_repo_dir
)
+40
View File
@@ -0,0 +1,40 @@
from multiprocessing import Process, Queue
import time
from typing import List
import os
class Worker(object):
def __init__(self, queue: Queue):
self.run_flag = True
self.queue = queue
self.process = Process(
target=self.handle_jobs,
args=(self.queue,)
)
time.sleep(1)
self.process.start()
def stop(self):
self.queue.put(['exit'])
self.process.join()
@staticmethod
def handle_jobs(queue: Queue):
while True:
if queue.empty():
time.sleep(1)
continue
cmd_list: List[str] = queue.get()
print('received job:\n', cmd_list)
if cmd_list[0].lower() == 'exit':
break
cmd_str = ' && '.join(cmd_list)
os.system(cmd_str)
if __name__ == '__main__':
work_queue: Queue = Queue()
worker = Worker(queue=work_queue)
work_queue.put(['echo "hello world"', 'echo "hello world again"'])
worker.stop()
-2
View File
@@ -1,2 +0,0 @@
REPO_DIR = /repo
ENV = dev
+3
View File
@@ -11,3 +11,6 @@ ignore_missing_imports = True
[mypy-fastapi.*] [mypy-fastapi.*]
ignore_missing_imports = True ignore_missing_imports = True
[mypy-httpx.*]
ignore_missing_imports = True
-3
View File
@@ -1,3 +0,0 @@
script: |
echo "hello world"
echo "hello back"