mirror of
https://github.com/unraid/api.git
synced 2026-01-08 01:29:49 -06:00
fix: container update logic
This commit is contained in:
@@ -41,7 +41,22 @@ export class DockerManifestService {
|
||||
cacheData ??= await this.dockerPhpService.readCachedUpdateStatus();
|
||||
const containerData = cacheData[taggedRef];
|
||||
if (!containerData) return null;
|
||||
return containerData.status?.toLowerCase() === 'true';
|
||||
|
||||
const normalize = (digest?: string | null) => {
|
||||
const value = digest?.trim().toLowerCase();
|
||||
return value && value !== 'undef' ? value : null;
|
||||
};
|
||||
|
||||
const localDigest = normalize(containerData.local);
|
||||
const remoteDigest = normalize(containerData.remote);
|
||||
if (localDigest && remoteDigest) {
|
||||
return localDigest !== remoteDigest;
|
||||
}
|
||||
|
||||
const status = containerData.status?.toLowerCase();
|
||||
if (status === 'true') return true;
|
||||
if (status === 'false') return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
// Import the mocked pubsub parts
|
||||
import { pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js';
|
||||
import { DockerConfigService } from '@app/unraid-api/graph/resolvers/docker/docker-config.service.js';
|
||||
import { DockerManifestService } from '@app/unraid-api/graph/resolvers/docker/docker-manifest.service.js';
|
||||
import { DockerTemplateScannerService } from '@app/unraid-api/graph/resolvers/docker/docker-template-scanner.service.js';
|
||||
import { ContainerState, DockerContainer } from '@app/unraid-api/graph/resolvers/docker/docker.model.js';
|
||||
import { DockerService } from '@app/unraid-api/graph/resolvers/docker/docker.service.js';
|
||||
@@ -27,30 +28,40 @@ interface DockerError extends NodeJS.ErrnoException {
|
||||
address: string;
|
||||
}
|
||||
|
||||
const mockContainer = {
|
||||
start: vi.fn(),
|
||||
stop: vi.fn(),
|
||||
};
|
||||
const { mockDockerInstance, mockListContainers, mockGetContainer, mockListNetworks, mockContainer } =
|
||||
vi.hoisted(() => {
|
||||
const mockContainer = {
|
||||
start: vi.fn(),
|
||||
stop: vi.fn(),
|
||||
};
|
||||
|
||||
// Create properly typed mock functions
|
||||
const mockListContainers = vi.fn();
|
||||
const mockGetContainer = vi.fn().mockReturnValue(mockContainer);
|
||||
const mockListNetworks = vi.fn();
|
||||
const mockListContainers = vi.fn();
|
||||
const mockGetContainer = vi.fn().mockReturnValue(mockContainer);
|
||||
const mockListNetworks = vi.fn();
|
||||
|
||||
const mockDockerInstance = {
|
||||
getContainer: mockGetContainer,
|
||||
listContainers: mockListContainers,
|
||||
listNetworks: mockListNetworks,
|
||||
modem: {
|
||||
Promise: Promise,
|
||||
protocol: 'http',
|
||||
socketPath: '/var/run/docker.sock',
|
||||
headers: {},
|
||||
sshOptions: {
|
||||
agentForward: undefined,
|
||||
},
|
||||
},
|
||||
} as unknown as Docker;
|
||||
const mockDockerInstance = {
|
||||
getContainer: mockGetContainer,
|
||||
listContainers: mockListContainers,
|
||||
listNetworks: mockListNetworks,
|
||||
modem: {
|
||||
Promise: Promise,
|
||||
protocol: 'http',
|
||||
socketPath: '/var/run/docker.sock',
|
||||
headers: {},
|
||||
sshOptions: {
|
||||
agentForward: undefined,
|
||||
},
|
||||
},
|
||||
} as unknown as Docker;
|
||||
|
||||
return {
|
||||
mockDockerInstance,
|
||||
mockListContainers,
|
||||
mockGetContainer,
|
||||
mockListNetworks,
|
||||
mockContainer,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('dockerode', () => {
|
||||
return {
|
||||
@@ -113,6 +124,10 @@ const mockDockerTemplateScannerService = {
|
||||
syncMissingContainers: vi.fn().mockResolvedValue(false),
|
||||
};
|
||||
|
||||
const mockDockerManifestService = {
|
||||
refreshDigests: vi.fn().mockResolvedValue(true),
|
||||
};
|
||||
|
||||
// Mock NotificationsService
|
||||
const mockNotificationsService = {
|
||||
notifyIfUnique: vi.fn().mockResolvedValue(null),
|
||||
@@ -141,6 +156,8 @@ describe('DockerService', () => {
|
||||
});
|
||||
mockDockerTemplateScannerService.bootstrapScan.mockResolvedValue(undefined);
|
||||
mockDockerTemplateScannerService.syncMissingContainers.mockResolvedValue(false);
|
||||
mockDockerManifestService.refreshDigests.mockReset();
|
||||
mockDockerManifestService.refreshDigests.mockResolvedValue(true);
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
@@ -157,6 +174,10 @@ describe('DockerService', () => {
|
||||
provide: DockerTemplateScannerService,
|
||||
useValue: mockDockerTemplateScannerService,
|
||||
},
|
||||
{
|
||||
provide: DockerManifestService,
|
||||
useValue: mockDockerManifestService,
|
||||
},
|
||||
{
|
||||
provide: NotificationsService,
|
||||
useValue: mockNotificationsService,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { catchHandlers } from '@app/core/utils/misc/catch-handlers.js';
|
||||
import { sleep } from '@app/core/utils/misc/sleep.js';
|
||||
import { getters } from '@app/store/index.js';
|
||||
import { DockerConfigService } from '@app/unraid-api/graph/resolvers/docker/docker-config.service.js';
|
||||
import { DockerManifestService } from '@app/unraid-api/graph/resolvers/docker/docker-manifest.service.js';
|
||||
import {
|
||||
ContainerPortType,
|
||||
ContainerState,
|
||||
@@ -50,7 +51,8 @@ export class DockerService {
|
||||
constructor(
|
||||
@Inject(CACHE_MANAGER) private cacheManager: Cache,
|
||||
private readonly dockerConfigService: DockerConfigService,
|
||||
private readonly notificationsService: NotificationsService
|
||||
private readonly notificationsService: NotificationsService,
|
||||
private readonly dockerManifestService: DockerManifestService
|
||||
) {
|
||||
this.client = this.getDockerClient();
|
||||
}
|
||||
@@ -458,7 +460,9 @@ export class DockerService {
|
||||
this.logger.debug(`Invalidated container caches after updating ${id}`);
|
||||
|
||||
const updatedContainers = await this.getContainers({ skipCache: true });
|
||||
const updatedContainer = updatedContainers.find((c) => c.id === id);
|
||||
const updatedContainer = updatedContainers.find(
|
||||
(c) => c.names?.some((name) => name.replace(/^\//, '') === containerName) || c.id === id
|
||||
);
|
||||
if (!updatedContainer) {
|
||||
throw new Error(`Container ${id} not found after update`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user