Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions backend/image-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class ImageRepository {
remoteDigest = resRemote.stdout?.toString().trim();
}

imageInfo = new ImageInfo(remoteDigest, imageInfo.localDigest, imageInfo.localId);
imageInfo = new ImageInfo(remoteDigest, imageInfo.localDigest, imageInfo.localId, imageInfo.imageVersion);
this.updateInfo(stack, service, image, imageInfo);
}

Expand All @@ -40,10 +40,12 @@ export class ImageRepository {

let localId = "";
let localDigest = "";
let imageVersion: string | null = null;
if (resLocal.stdout) {
const localInspect = JSON.parse(resLocal.stdout!.toString());
if (Array.isArray(localInspect) && localInspect[0]) {
localId = localInspect[0].Id;
imageVersion = localInspect[0].Config?.Labels?.["org.opencontainers.image.version"] ?? null;

const localRepoDigest = localInspect[0].RepoDigests;
if (Array.isArray(localRepoDigest)) {
Expand All @@ -62,14 +64,14 @@ export class ImageRepository {
log.warn("updateLocal", "Image '" + image + "': Local id '" + localId + "' digest '" + localDigest + "'");
}

imageInfo = new ImageInfo(imageInfo.remoteDigest, localDigest, localId);
imageInfo = new ImageInfo(imageInfo.remoteDigest, localDigest, localId, imageVersion);
this.updateInfo(stack, service, image, imageInfo);

return imageInfo;
}

getImageInfo(stack: string, service: string, image: string) : ImageInfo {
return this.imageInfos.get(stack)?.get(this.imageKey(service, image)) ?? new ImageInfo("", "", "");
return this.imageInfos.get(stack)?.get(this.imageKey(service, image)) ?? new ImageInfo("", "", "", null);
}

private updateInfo(stack: string, service: string, image: string, imageInfo: ImageInfo) {
Expand All @@ -89,7 +91,8 @@ export class ImageInfo {
constructor(
public readonly remoteDigest: string,
public readonly localDigest: string,
public readonly localId: string
public readonly localId: string,
public readonly imageVersion: string | null
) {}

isImageUpdateAvailable() {
Expand Down
2 changes: 1 addition & 1 deletion backend/routers/api-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export class ApiRouter extends Router {
// GET /api/stacks — list stacks from all agents (local + remote)
router.get("/api/stacks", async (_req: Request, res: Response) => {
try {
type ServiceInfo = { name: string; containerName: string; image: string; state: string; status: string; health: string; imageUpdateAvailable: boolean };
type ServiceInfo = { name: string; containerName: string; image: string; state: string; status: string; health: string; imageUpdateAvailable: boolean; imageVersion?: string | null };
type StackInfo = { name: string; status: string; statusCode: number; isManagedByDockge: boolean; endpoint: string; autoUpdate: boolean; imageUpdatesAvailable: boolean; services: Record<string, ServiceInfo> };
const stacks: StackInfo[] = [];

Expand Down
3 changes: 2 additions & 1 deletion backend/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ export class Stack {
health: serviceInfo.Health,
recreateNecessary: recreateNecessary,
imageUpdateAvailable: serviceImageUpdateAvailable,
remoteImageDigest: imageInfo.remoteDigest
remoteImageDigest: imageInfo.remoteDigest,
imageVersion: imageInfo.imageVersion,
}
);

Expand Down
1 change: 1 addition & 0 deletions common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type ServiceData = {
recreateNecessary: boolean,
imageUpdateAvailable: boolean,
remoteImageDigest: string,
imageVersion: string | null,
}

export type SimpleStackData = {
Expand Down