feat: complete OCI registry implementation with docker push/pull support

A lightweight OCI (Open Container Initiative) registry implementation written in Go.
This commit is contained in:
loveuer
2025-11-09 22:46:27 +08:00
commit 29088a6b54
45 changed files with 5629 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
import { useEffect, useState } from 'react'
import { Box, Typography, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, CircularProgress, Alert } from '@mui/material'
interface RegistryImage {
id: number
name: string
upload_time: string
size: number
}
// Format bytes to human readable format
function formatSize(bytes: number): string {
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`
}
export default function RegistryImageList() {
const [images, setImages] = useState<RegistryImage[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
let abort = false
async function fetchImages() {
setLoading(true)
setError(null)
try {
const res = await fetch('/api/v1/registry/image/list')
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const result = await res.json()
// Backend returns: {status, msg, data: {images: [...]}}
const list: RegistryImage[] = result.data?.images || []
if (!abort) setImages(list)
} catch (e: any) {
if (!abort) setError(e.message)
} finally {
if (!abort) setLoading(false)
}
}
fetchImages()
return () => { abort = true }
}, [])
return (
<Box>
<Typography variant="h5" gutterBottom></Typography>
{loading && <CircularProgress />}
{error && <Alert severity="error">: {error}</Alert>}
{!loading && !error && (
<Paper>
<TableContainer>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{images.map(img => (
<TableRow key={img.id} hover>
<TableCell>{img.id}</TableCell>
<TableCell>{img.name}</TableCell>
<TableCell>{img.upload_time}</TableCell>
<TableCell>{formatSize(img.size)}</TableCell>
</TableRow>
))}
{images.length === 0 && (
<TableRow>
<TableCell colSpan={4} align="center"></TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
</Paper>
)}
</Box>
)
}