Commit cb19eb49 authored by Mustafa Gezen's avatar Mustafa Gezen 🏗
Browse files

restructure before oidc

parent f132a6d3
......@@ -28,6 +28,7 @@ templates = Jinja2Templates(directory="ui/dist/templates")
async def serve_frontend(request: Request):
return templates.TemplateResponse("index.html", {
"request": request,
"distribution": settings.settings.distribution,
"koji_weburl": session.koji_config.get("weburl"),
"gitlab_url": f"https://{settings.settings.gitlab_host}{settings.settings.repo_prefix}"
})
......
from typing import List, Tuple, Optional
from pydantic import BaseModel, validator
from distrobuild.models import Import, Package, PackageModule, BuildStatus
class BuildRequest(BaseModel):
package_id: Optional[int]
package_name: Optional[str]
@validator('package_name')
def validate(cls, package_name, values):
if (not values.get('package_id') and not package_name) or (values.get('package_id') and package_name):
raise ValueError('either package_id or package_name is required')
return package_name
class BatchBuildRequest(BaseModel):
packages: List[BuildRequest]
def gen_body_filters(body_in) -> dict:
body = BuildRequest(**body_in)
if body.package_id:
return {"id": body.package_id}
if body.package_name:
return {"name": body.package_name}
async def create_build_order(package: Package) -> List[Tuple[int, int]]:
pkg_list = []
if package.is_package:
package_import = await Import.create(package_id=package.id, status=BuildStatus.QUEUED, version=8)
pkg_list.append((package.id, package_import.id))
if package.is_module:
subpackages = await PackageModule.filter(module_parent_package_id=package.id).all()
for subpackage in subpackages:
imports = await Import.filter(package_id=subpackage.package_id).all()
if not imports or len(imports) == 0:
subpackage_package = await Package.filter(id=subpackage.package_id).get()
pkg_list += await create_build_order(subpackage_package)
package_module_import = await Import.create(package_id=package.id, status=BuildStatus.QUEUED, version=8,
module=True)
pkg_list.append((package.id, package_module_import.id))
return pkg_list
from typing import Optional, List, Tuple
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import PlainTextResponse
from fastapi_pagination import Page, pagination_params
from fastapi_pagination.ext.tortoise import paginate
from pydantic import BaseModel, validator
from distrobuild.common import BuildRequest, gen_body_filters, BatchBuildRequest
from distrobuild.models import Build, Import, ImportCommit, Package, PackageModule, BuildStatus
from distrobuild.serialize import Build_Pydantic
from distrobuild_scheduler import build_package_task
from distrobuild_scheduler import import_package_task, build_package_task
router = APIRouter(prefix="/build")
class BuildRequest(BaseModel):
package_id: Optional[int]
package_name: Optional[str]
@validator('package_name')
def validate(cls, package_name, values):
if (not values.get('package_id') and not package_name) or (values.get('package_id') and package_name):
raise ValueError('either package_id or package_name is required')
return package_name
class BatchBuildRequest(BaseModel):
packages: List[BuildRequest]
def gen_body_filters(body_in) -> dict:
body = BuildRequest(**body_in)
if body.package_id:
return {"id": body.package_id}
if body.package_name:
return {"name": body.package_name}
router = APIRouter(prefix="/builds")
@router.get("/", response_model=Page[Build_Pydantic], dependencies=[Depends(pagination_params)])
......@@ -44,23 +15,6 @@ async def list_builds():
return await paginate(Build.all().order_by('-created_at').prefetch_related("package"))
# response_model causes some weird errors with Import. why?
# TODO: find out (removing response_model for now)
@router.get("/imports/", dependencies=[Depends(pagination_params)])
async def list_imports():
return await paginate(Import.all().order_by('-created_at').prefetch_related("package"))
@router.get("/imports/{import_id}/logs", response_class=PlainTextResponse)
async def get_import_logs(import_id: int):
import_obj = await Import.filter(id=import_id).get()
try:
with open(f"/tmp/import-{import_obj.id}.log") as f:
return f.read()
except FileNotFoundError:
raise HTTPException(404, detail="import not started")
@router.post("/", status_code=202)
async def queue_build(body: BuildRequest):
filters = gen_body_filters(body)
......@@ -90,46 +44,3 @@ async def batch_queue_build(body: BatchBuildRequest):
await queue_build(build_request)
return {}
async def create_build_order(package: Package) -> List[Tuple[int, int]]:
pkg_list = []
if package.is_package:
package_import = await Import.create(package_id=package.id, status=BuildStatus.QUEUED, version=8)
pkg_list.append((package.id, package_import.id))
if package.is_module:
subpackages = await PackageModule.filter(module_parent_package_id=package.id).all()
for subpackage in subpackages:
imports = await Import.filter(package_id=subpackage.package_id).all()
if not imports or len(imports) == 0:
subpackage_package = await Package.filter(id=subpackage.package_id).get()
pkg_list += await create_build_order(subpackage_package)
package_module_import = await Import.create(package_id=package.id, status=BuildStatus.QUEUED, version=8,
module=True)
pkg_list.append((package.id, package_module_import.id))
return pkg_list
@router.post("/imports/", status_code=202)
async def import_package_route(body: BuildRequest):
filters = gen_body_filters(body)
package = await Package.filter(**filters).get_or_none()
if not package:
raise HTTPException(404, detail="package does not exist")
build_order = await create_build_order(package)
await import_package_task(build_order[0][0], build_order[0][1], build_order[1:])
return {}
@router.post("/imports/batch", status_code=202)
async def batch_import_package(body: BatchBuildRequest):
for build_request in body.packages:
await import_package_route(build_request)
return {}
from fastapi import APIRouter, Depends, HTTPException
from fastapi_pagination import pagination_params
from fastapi_pagination.ext.tortoise import paginate
from starlette.responses import PlainTextResponse
from distrobuild.common import BuildRequest, gen_body_filters, BatchBuildRequest, create_build_order
from distrobuild.models import Import, Package
from distrobuild_scheduler import import_package_task
router = APIRouter(prefix="/imports")
# response_model causes some weird errors with Import. why?
# TODO: find out (removing response_model for now)
@router.get("/", dependencies=[Depends(pagination_params)])
async def list_imports():
return await paginate(Import.all().order_by('-created_at').prefetch_related("package"))
@router.get("/{import_id}/logs", response_class=PlainTextResponse)
async def get_import_logs(import_id: int):
import_obj = await Import.filter(id=import_id).get_or_none()
if not import_obj:
raise HTTPException(404, detail="import does not exist")
try:
with open(f"/tmp/import-{import_obj.id}.log") as f:
return f.read()
except FileNotFoundError:
raise HTTPException(412, detail="import not started or log has expired")
@router.post("/", status_code=202)
async def import_package_route(body: BuildRequest):
filters = gen_body_filters(body)
package = await Package.filter(**filters).get_or_none()
if not package:
raise HTTPException(404, detail="package does not exist")
build_order = await create_build_order(package)
await import_package_task(build_order[0][0], build_order[0][1], build_order[1:])
return {}
@router.post("/batch", status_code=202)
async def batch_import_package(body: BatchBuildRequest):
for build_request in body.packages:
await import_package_route(build_request)
return {}
......@@ -3,6 +3,10 @@ from pydantic import BaseSettings
class Settings(BaseSettings):
bugs_api_key: str
gitlab_api_key: str
# srpmproc
gitlab_host: str
repo_prefix: str
storage_addr: str
......@@ -10,8 +14,18 @@ class Settings(BaseSettings):
ssh_port: int = 22
ssh_key_location: Optional[str]
version: int = 8
bugs_api_key: str
gitlab_api_key: str
no_storage_download: bool = False
no_storage_upload: bool = False
# oidc
oidc_issuer: str
oidc_client_id: str
oidc_client_secret: str
# appearance
distribution: str = "Rocky Linux"
# scheduler options
broker_url: str
routing_key: str = "distrobuild"
workers: int = 10
......
import asyncio
import json
from typing import Optional
from distrobuild.settings import settings
async def import_project(import_id: int, source_rpm: str, module_mode: bool = False) -> dict:
async def import_project(import_id: int, source_rpm: str, module_mode: bool = False,
single_tag: Optional[str] = None) -> dict:
upstream_prefix = f"ssh://{settings.ssh_user}@{settings.gitlab_host}:{settings.ssh_port}{settings.repo_prefix}"
args = [
......@@ -17,16 +20,26 @@ async def import_project(import_id: int, source_rpm: str, module_mode: bool = Fa
"--storage-addr",
settings.storage_addr,
"--ssh-user",
settings.ssh_user
settings.ssh_user,
]
if settings.ssh_key_location:
args.append("--ssh-key-location")
args.append(settings.ssh_key_location)
if settings.no_storage_download:
args.append("--no-storage-download")
if settings.no_storage_upload:
args.append("--no-storage-upload")
if module_mode:
args.append("--module-mode")
if single_tag:
args.append("--single-tag")
args.append(single_tag)
f = open(f"/tmp/import-{import_id}.log", "w")
proc = await asyncio.create_subprocess_exec("srpmproc", *args, stdout=asyncio.subprocess.PIPE, stderr=f)
......
......@@ -8,7 +8,11 @@
<div id="root"></div>
<script>
window.SETTINGS = {'kojiWeburl': '{{ koji_weburl}}', 'gitlabUrl': '{{ gitlab_url }}'};
window.SETTINGS = {
'kojiWeburl': '{{ koji_weburl}}',
'gitlabUrl': '{{ gitlab_url }}',
'distribution': '{{ distribution }}',
};
</script>
</body>
</html>
\ No newline at end of file
</html>
......@@ -15,7 +15,7 @@ import { IPaginated, Axios, IImport, IBuild } from '../api';
import Link from 'carbon-components-react/lib/components/UIShell/Link';
const importHeaders = ['ID', 'Initiated', 'Package', 'Status', ''];
const buildHeaders = ['ID', 'Initiated', 'Package', 'Koji ID', 'Status'];
const buildHeaders = ['ID', 'Initiated', 'Package', 'Status', ''];
const statusToTag = (status) => {
switch (status) {
......@@ -38,13 +38,13 @@ export const Dashboard = () => {
React.useEffect(() => {
(async () => {
const [err, res] = await to(Axios.get('/build/imports/?size=50'));
const [err, res] = await to(Axios.get('/build/imports/?size=5'));
if (res) {
setImports(res.data);
}
})().then();
(async () => {
const [err, res] = await to(Axios.get('/build/?size=50'));
const [err, res] = await to(Axios.get('/build/?size=5'));
if (res) {
setBuilds(res.data);
}
......@@ -78,6 +78,7 @@ export const Dashboard = () => {
{new Date(item.created_at).toLocaleString()}
</TableCell>
<TableCell>{item.package.name}</TableCell>
<TableCell>{statusToTag(item.status)}</TableCell>
<TableCell>
<Link
target="_blank"
......@@ -86,7 +87,6 @@ export const Dashboard = () => {
{item.koji_id}
</Link>
</TableCell>
<TableCell>{statusToTag(item.status)}</TableCell>
</TableRow>
))}
</TableBody>
......
......@@ -15,19 +15,25 @@ import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import { Packages } from './Packages';
import { Dashboard } from './Dashboard';
import '../styles/header.css';
export const Root = () => {
return (
<BrowserRouter>
<Header aria-label="Distrobuild">
<HeaderName element={Link} to="/" prefix="Distrobuild">
[Rocky Linux]
[{window.SETTINGS.distribution}]
</HeaderName>
<HeaderNavigation>
<HeaderMenuItem element={Link} to="/packages">
Packages
</HeaderMenuItem>
</HeaderNavigation>
<HeaderGlobalBar></HeaderGlobalBar>
<HeaderNavigation className="right">
<HeaderMenuItem element={Link} to="/packages">
Packages
</HeaderMenuItem>
</HeaderNavigation>
</Header>
<div style={{ marginTop: '48px' }}>
<Switch>
......
export {};
interface IState {
authenticated: boolean;
}
declare global {
interface Window {
SETTINGS: any;
STATE: IState;
}
}
.bx--header__nav.right {
margin-left: auto;
}
.bx--header__nav.right::before {
display: none;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment