mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-12-15 01:55:48 -07:00
Restore repo hash endpoint and align device list
This commit is contained in:
@@ -146,11 +146,21 @@ export default function DeviceList({ onSelectDevice }) {
|
|||||||
const [assignTargets, setAssignTargets] = useState([]); // hostnames
|
const [assignTargets, setAssignTargets] = useState([]); // hostnames
|
||||||
|
|
||||||
const [repoHash, setRepoHash] = useState(null);
|
const [repoHash, setRepoHash] = useState(null);
|
||||||
|
const lastRepoFetchRef = useRef(0);
|
||||||
|
|
||||||
const fetchLatestRepoHash = useCallback(async () => {
|
const fetchLatestRepoHash = useCallback(async (options = {}) => {
|
||||||
|
const { force = false } = options || {};
|
||||||
|
const now = Date.now();
|
||||||
|
const elapsed = now - lastRepoFetchRef.current;
|
||||||
|
if (!force && repoHash && elapsed >= 0 && elapsed < 60_000) {
|
||||||
|
return repoHash;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams({ repo: "bunny-lab-io/Borealis", branch: "main" });
|
const params = new URLSearchParams({ repo: "bunny-lab-io/Borealis", branch: "main" });
|
||||||
const resp = await fetch(`/api/repo/current_hash?${params.toString()}`);
|
if (force) {
|
||||||
|
params.set("refresh", "1");
|
||||||
|
}
|
||||||
|
const resp = await fetch(`/api/agent/repo_hash?${params.toString()}`);
|
||||||
const json = await resp.json();
|
const json = await resp.json();
|
||||||
const sha = (json?.sha || "").trim();
|
const sha = (json?.sha || "").trim();
|
||||||
if (!resp.ok || !sha) {
|
if (!resp.ok || !sha) {
|
||||||
@@ -158,14 +168,19 @@ export default function DeviceList({ onSelectDevice }) {
|
|||||||
err.response = json;
|
err.response = json;
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
setRepoHash((prev) => sha || prev || null);
|
lastRepoFetchRef.current = now;
|
||||||
|
setRepoHash((prev) => (sha ? sha : prev || null));
|
||||||
return sha || null;
|
return sha || null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("Failed to fetch repository hash", err);
|
console.warn("Failed to fetch repository hash", err);
|
||||||
|
if (!force && repoHash) {
|
||||||
|
return repoHash;
|
||||||
|
}
|
||||||
|
lastRepoFetchRef.current = now;
|
||||||
setRepoHash((prev) => prev || null);
|
setRepoHash((prev) => prev || null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, []);
|
}, [repoHash]);
|
||||||
|
|
||||||
const computeAgentVersion = useCallback((agentHashValue, repoHashValue) => {
|
const computeAgentVersion = useCallback((agentHashValue, repoHashValue) => {
|
||||||
const agentHash = (agentHashValue || "").trim();
|
const agentHash = (agentHashValue || "").trim();
|
||||||
@@ -179,7 +194,7 @@ export default function DeviceList({ onSelectDevice }) {
|
|||||||
const { refreshRepo = false } = options || {};
|
const { refreshRepo = false } = options || {};
|
||||||
let repoSha = repoHash;
|
let repoSha = repoHash;
|
||||||
if (refreshRepo || !repoSha) {
|
if (refreshRepo || !repoSha) {
|
||||||
const fetched = await fetchLatestRepoHash();
|
const fetched = await fetchLatestRepoHash({ force: refreshRepo });
|
||||||
if (fetched) repoSha = fetched;
|
if (fetched) repoSha = fetched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -356,6 +356,44 @@ def health():
|
|||||||
return jsonify({"status": "ok"})
|
return jsonify({"status": "ok"})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/api/agent/repo_hash", methods=["GET"])
|
||||||
|
def api_agent_repo_hash():
|
||||||
|
try:
|
||||||
|
repo = (request.args.get('repo') or _DEFAULT_REPO).strip()
|
||||||
|
branch = (request.args.get('branch') or _DEFAULT_BRANCH).strip()
|
||||||
|
refresh_flag = (request.args.get('refresh') or '').strip().lower()
|
||||||
|
ttl_raw = request.args.get('ttl')
|
||||||
|
if '/' not in repo:
|
||||||
|
return jsonify({"error": "repo must be in the form owner/name"}), 400
|
||||||
|
try:
|
||||||
|
ttl = int(ttl_raw) if ttl_raw else _REPO_HASH_INTERVAL
|
||||||
|
except ValueError:
|
||||||
|
ttl = _REPO_HASH_INTERVAL
|
||||||
|
ttl = max(30, min(ttl, 3600))
|
||||||
|
force_refresh = refresh_flag in {'1', 'true', 'yes', 'force', 'refresh'}
|
||||||
|
if repo == _DEFAULT_REPO and branch == _DEFAULT_BRANCH:
|
||||||
|
result = _refresh_default_repo_hash(force=force_refresh)
|
||||||
|
else:
|
||||||
|
result = _fetch_repo_head(repo, branch, ttl_seconds=ttl, force_refresh=force_refresh)
|
||||||
|
sha = (result.get('sha') or '').strip()
|
||||||
|
payload = {
|
||||||
|
'repo': repo,
|
||||||
|
'branch': branch,
|
||||||
|
'sha': sha if sha else None,
|
||||||
|
'cached': bool(result.get('cached')),
|
||||||
|
'age_seconds': result.get('age_seconds'),
|
||||||
|
'source': result.get('source'),
|
||||||
|
}
|
||||||
|
if result.get('error'):
|
||||||
|
payload['error'] = result['error']
|
||||||
|
if sha:
|
||||||
|
return jsonify(payload)
|
||||||
|
return jsonify(payload), 503
|
||||||
|
except Exception as exc:
|
||||||
|
_write_service_log('server', f'/api/agent/repo_hash error: {exc}')
|
||||||
|
return jsonify({"error": "internal error"}), 500
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/repo/current_hash", methods=["GET"])
|
@app.route("/api/repo/current_hash", methods=["GET"])
|
||||||
def api_repo_current_hash():
|
def api_repo_current_hash():
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user