feat: container sizes

This commit is contained in:
Pujit Mehrotra
2025-11-06 14:07:44 -05:00
parent 1ff22e546a
commit 57a5de7783
10 changed files with 372 additions and 7 deletions

View File

@@ -1121,6 +1121,12 @@ type DockerContainer implements Node {
"""Total size of all files in the container (in bytes)"""
sizeRootFs: BigInt
"""Size of writable layer (in bytes)"""
sizeRw: BigInt
"""Size of container logs (in bytes)"""
sizeLog: BigInt
labels: JSON
state: ContainerState!
status: String!

View File

@@ -100,6 +100,18 @@ export class DockerContainer extends Node {
})
sizeRootFs?: number;
@Field(() => GraphQLBigInt, {
nullable: true,
description: 'Size of writable layer (in bytes)',
})
sizeRw?: number;
@Field(() => GraphQLBigInt, {
nullable: true,
description: 'Size of container logs (in bytes)',
})
sizeLog?: number;
@Field(() => GraphQLJSON, { nullable: true })
labels?: Record<string, any>;

View File

@@ -31,6 +31,7 @@ describe('DockerResolver', () => {
useValue: {
getContainers: vi.fn(),
getNetworks: vi.fn(),
getContainerLogSizes: vi.fn(),
},
},
{
@@ -71,6 +72,8 @@ describe('DockerResolver', () => {
// Reset mocks before each test
vi.clearAllMocks();
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation(() => false);
vi.mocked(dockerService.getContainerLogSizes).mockResolvedValue(new Map());
});
it('should be defined', () => {
@@ -110,13 +113,15 @@ describe('DockerResolver', () => {
},
];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockReturnValue(false);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation(() => false);
const mockInfo = {} as any;
const result = await resolver.containers(false, mockInfo);
expect(result).toEqual(mockContainers);
expect(GraphQLFieldHelper.isFieldRequested).toHaveBeenCalledWith(mockInfo, 'sizeRootFs');
expect(GraphQLFieldHelper.isFieldRequested).toHaveBeenCalledWith(mockInfo, 'sizeRw');
expect(GraphQLFieldHelper.isFieldRequested).toHaveBeenCalledWith(mockInfo, 'sizeLog');
expect(dockerService.getContainers).toHaveBeenCalledWith({ skipCache: false, size: false });
});
@@ -137,7 +142,9 @@ describe('DockerResolver', () => {
},
];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockReturnValue(true);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation((_, field) => {
return field === 'sizeRootFs';
});
const mockInfo = {} as any;
@@ -147,10 +154,60 @@ describe('DockerResolver', () => {
expect(dockerService.getContainers).toHaveBeenCalledWith({ skipCache: false, size: true });
});
it('should request size when sizeRw field is requested', async () => {
const mockContainers: DockerContainer[] = [];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation((_, field) => {
return field === 'sizeRw';
});
const mockInfo = {} as any;
await resolver.containers(false, mockInfo);
expect(GraphQLFieldHelper.isFieldRequested).toHaveBeenCalledWith(mockInfo, 'sizeRw');
expect(dockerService.getContainers).toHaveBeenCalledWith({ skipCache: false, size: true });
});
it('should fetch log sizes when sizeLog field is requested', async () => {
const mockContainers: DockerContainer[] = [
{
id: '1',
autoStart: false,
command: 'test',
names: ['/test-container'],
created: 1234567890,
image: 'test-image',
imageId: 'test-image-id',
ports: [],
state: ContainerState.EXITED,
status: 'Exited',
},
];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation((_, field) => {
if (field === 'sizeLog') return true;
return false;
});
const logSizeMap = new Map<string, number>([['test-container', 42]]);
vi.mocked(dockerService.getContainerLogSizes).mockResolvedValue(logSizeMap);
const mockInfo = {} as any;
const result = await resolver.containers(false, mockInfo);
expect(GraphQLFieldHelper.isFieldRequested).toHaveBeenCalledWith(mockInfo, 'sizeLog');
expect(dockerService.getContainerLogSizes).toHaveBeenCalledWith(['test-container']);
expect(result[0]?.sizeLog).toBe(42);
expect(dockerService.getContainers).toHaveBeenCalledWith({ skipCache: false, size: false });
});
it('should request size when GraphQLFieldHelper indicates sizeRootFs is requested', async () => {
const mockContainers: DockerContainer[] = [];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockReturnValue(true);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation((_, field) => {
return field === 'sizeRootFs';
});
const mockInfo = {} as any;
@@ -162,7 +219,7 @@ describe('DockerResolver', () => {
it('should not request size when GraphQLFieldHelper indicates sizeRootFs is not requested', async () => {
const mockContainers: DockerContainer[] = [];
vi.mocked(dockerService.getContainers).mockResolvedValue(mockContainers);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockReturnValue(false);
vi.mocked(GraphQLFieldHelper.isFieldRequested).mockImplementation(() => false);
const mockInfo = {} as any;

View File

@@ -53,8 +53,29 @@ export class DockerResolver {
@Args('skipCache', { defaultValue: false, type: () => Boolean }) skipCache: boolean,
@Info() info: GraphQLResolveInfo
) {
const requestsSize = GraphQLFieldHelper.isFieldRequested(info, 'sizeRootFs');
const containers = await this.dockerService.getContainers({ skipCache, size: requestsSize });
const requestsRootFsSize = GraphQLFieldHelper.isFieldRequested(info, 'sizeRootFs');
const requestsRwSize = GraphQLFieldHelper.isFieldRequested(info, 'sizeRw');
const requestsLogSize = GraphQLFieldHelper.isFieldRequested(info, 'sizeLog');
const containers = await this.dockerService.getContainers({
skipCache,
size: requestsRootFsSize || requestsRwSize,
});
if (requestsLogSize) {
const names = Array.from(
new Set(
containers
.map((container) => container.names?.[0]?.replace(/^\//, '') || null)
.filter((name): name is string => Boolean(name))
)
);
const logSizes = await this.dockerService.getContainerLogSizes(names);
containers.forEach((container) => {
const normalized = container.names?.[0]?.replace(/^\//, '') || '';
container.sizeLog = normalized ? (logSizes.get(normalized) ?? 0) : 0;
});
}
const wasSynced = await this.dockerTemplateScannerService.syncMissingContainers(containers);
return wasSynced ? await this.dockerService.getContainers({ skipCache: true }) : containers;
}

View File

@@ -1,6 +1,6 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { readFile, unlink, writeFile } from 'fs/promises';
import { readFile, stat, unlink, writeFile } from 'fs/promises';
import { type Cache } from 'cache-manager';
import Docker from 'dockerode';
@@ -165,6 +165,7 @@ export class DockerService {
ContainerPortType.TCP,
})),
sizeRootFs: sizeValue,
sizeRw: (container as Docker.ContainerInfo & { SizeRw?: number }).SizeRw,
labels: container.Labels ?? {},
state:
typeof container.State === 'string'
@@ -237,6 +238,54 @@ export class DockerService {
return containersWithTemplatePaths;
}
public async getContainerLogSizes(containerNames: string[]): Promise<Map<string, number>> {
const logSizes = new Map<string, number>();
if (!Array.isArray(containerNames) || containerNames.length === 0) {
return logSizes;
}
for (const rawName of containerNames) {
const normalized = (rawName ?? '').replace(/^\//, '');
if (!normalized) {
logSizes.set(normalized, 0);
continue;
}
try {
const { stdout } = await execa('docker', [
'inspect',
'--format',
'{{json .LogPath}}',
normalized,
]);
const trimmed = stdout.trim();
if (!trimmed) {
logSizes.set(normalized, 0);
continue;
}
const logPath = JSON.parse(trimmed) as string | null;
if (!logPath || typeof logPath !== 'string' || !logPath.length) {
logSizes.set(normalized, 0);
continue;
}
const stats = await stat(logPath).catch(() => null);
logSizes.set(normalized, stats?.size ?? 0);
} catch (error) {
const message =
error instanceof Error ? error.message : String(error ?? 'unknown error');
this.logger.debug(
`Failed to determine log size for container ${normalized}: ${message}`
);
logSizes.set(normalized, 0);
}
}
return logSizes;
}
/**
* Get all Docker networks
* @returns All the in/active Docker networks on the system.

View File

@@ -0,0 +1,176 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useQuery } from '@vue/apollo-composable';
import { GET_DOCKER_CONTAINER_SIZES } from '@/components/Docker/docker-container-sizes.query';
import type { GetDockerContainerSizesQuery } from '@/composables/gql/graphql';
export interface Props {
open?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
open: false,
});
const emit = defineEmits<{
'update:open': [value: boolean];
}>();
const isOpen = computed({
get: () => props.open,
set: (value) => emit('update:open', value),
});
const { result, loading, refetch } = useQuery<GetDockerContainerSizesQuery>(
GET_DOCKER_CONTAINER_SIZES,
undefined,
{
fetchPolicy: 'network-only',
enabled: computed(() => isOpen.value),
}
);
const containers = computed(() => result.value?.docker?.containers ?? []);
const tableRows = computed(() => {
return containers.value
.map((container) => {
const primaryName = container.names?.[0]?.replace(/^\//, '') || 'Unknown';
const totalBytes = container.sizeRootFs ?? 0;
const writableBytes = container.sizeRw ?? 0;
const logBytes = container.sizeLog ?? 0;
return {
id: container.id,
name: primaryName,
totalBytes,
writableBytes,
logBytes,
};
})
.sort((a, b) => b.totalBytes - a.totalBytes)
.map((entry) => ({
id: entry.id,
name: entry.name,
total: formatBytes(entry.totalBytes),
writable: formatBytes(entry.writableBytes),
log: formatBytes(entry.logBytes),
}));
});
const totals = computed(() => {
const aggregate = containers.value.reduce(
(acc, container) => {
acc.total += container.sizeRootFs ?? 0;
acc.writable += container.sizeRw ?? 0;
acc.log += container.sizeLog ?? 0;
return acc;
},
{ total: 0, writable: 0, log: 0 }
);
return {
total: formatBytes(aggregate.total),
writable: formatBytes(aggregate.writable),
log: formatBytes(aggregate.log),
};
});
const columns = computed(() => [
{
accessorKey: 'name',
header: 'Container',
footer: 'Totals',
},
{
accessorKey: 'total',
header: 'Total',
footer: totals.value.total,
meta: { class: { td: 'text-right font-mono text-sm', th: 'text-right' } },
},
{
accessorKey: 'writable',
header: 'Writable',
footer: totals.value.writable,
meta: { class: { td: 'text-right font-mono text-sm', th: 'text-right' } },
},
{
accessorKey: 'log',
header: 'Log',
footer: totals.value.log,
meta: { class: { td: 'text-right font-mono text-sm', th: 'text-right' } },
},
]);
// Format byte counts into a short human-readable string (e.g. "1.2 GB").
function formatBytes(value?: number | null): string {
if (!Number.isFinite(value ?? NaN) || value === null || value === undefined) {
return '—';
}
if (value === 0) {
return '0 B';
}
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
let size = value;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex += 1;
}
const formatter = new Intl.NumberFormat(undefined, {
maximumFractionDigits: size < 10 ? 2 : 1,
minimumFractionDigits: size < 10 && unitIndex > 0 ? 1 : 0,
});
return `${formatter.format(size)} ${units[unitIndex]}`;
}
async function handleRefresh() {
await refetch();
}
</script>
<template>
<UModal
v-model:open="isOpen"
title="Container Sizes"
:ui="{ footer: 'justify-end', overlay: 'z-50', content: 'sm:max-w-4xl' }"
>
<template #body>
<div class="space-y-4">
<div class="flex items-center justify-between gap-3">
<p class="text-sm text-gray-500 dark:text-gray-400">
Includes total filesystem, writable layer, and log file sizes per container.
</p>
<UButton
size="sm"
variant="outline"
icon="i-lucide-refresh-cw"
:loading="loading"
@click="handleRefresh"
>
Refresh
</UButton>
</div>
<UTable
:data="tableRows"
:columns="columns"
:loading="loading"
sticky="header"
:ui="{ td: 'py-2 px-3', th: 'py-2 px-3 text-left', tfoot: 'bg-gray-50 dark:bg-gray-900' }"
>
<template #empty>
<div class="py-6 text-center text-sm text-gray-500 dark:text-gray-400">
No containers found.
</div>
</template>
</UTable>
</div>
</template>
</UModal>
</template>

View File

@@ -3,6 +3,7 @@ import { computed, onBeforeUnmount, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useQuery } from '@vue/apollo-composable';
import ContainerSizesModal from '@/components/Docker/ContainerSizesModal.vue';
import { GET_DOCKER_CONTAINERS } from '@/components/Docker/docker-containers.query';
import DockerAutostartSettings from '@/components/Docker/DockerAutostartSettings.vue';
import DockerContainersTable from '@/components/Docker/DockerContainersTable.vue';
@@ -50,6 +51,7 @@ const selectedIds = ref<string[]>([]);
const activeId = ref<string | null>(null);
const isSwitching = ref(false);
const viewMode = ref<'overview' | 'autostart'>('overview');
const showSizesModal = ref(false);
const ROUTE_QUERY_KEY = 'container';
const SWITCH_DELAY_MS = 150;
@@ -322,6 +324,15 @@ const isDetailsDisabled = computed(() => props.disabled || isSwitching.value);
>
Customize Start Order
</UButton>
<UButton
size="xs"
variant="outline"
icon="i-lucide-hard-drive"
:disabled="props.disabled"
@click="showSizesModal = true"
>
Container Size
</UButton>
</div>
</div>
<DockerContainersTable
@@ -436,5 +447,6 @@ const isDetailsDisabled = computed(() => props.disabled || isSwitching.value);
</UCard>
</div>
</div>
<ContainerSizesModal v-model:open="showSizesModal" />
</div>
</template>

View File

@@ -0,0 +1,16 @@
import { gql } from '@apollo/client';
export const GET_DOCKER_CONTAINER_SIZES = gql`
query GetDockerContainerSizes {
docker {
id
containers(skipCache: true) {
id
names
sizeRootFs
sizeRw
sizeLog
}
}
}
`;

View File

@@ -29,6 +29,7 @@ type Documents = {
"\n query Unified {\n settings {\n unified {\n id\n dataSchema\n uiSchema\n values\n }\n }\n }\n": typeof types.UnifiedDocument,
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": typeof types.UpdateConnectSettingsDocument,
"\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n labels\n }\n }\n }\n": typeof types.GetDockerActiveContainerDocument,
"\n query GetDockerContainerSizes {\n docker {\n id\n containers(skipCache: true) {\n id\n names\n sizeRootFs\n sizeRw\n sizeLog\n }\n }\n }\n": typeof types.GetDockerContainerSizesDocument,
"\n query GetDockerContainers($skipCache: Boolean = false) {\n docker {\n id\n containers(skipCache: $skipCache) {\n id\n names\n state\n status\n image\n created\n autoStart\n autoStartOrder\n autoStartWait\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n mounts\n }\n organizer(skipCache: $skipCache) {\n version\n views {\n id\n name\n rootId\n prefs\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n icon\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n networkSettings\n mounts\n created\n isUpdateAvailable\n isRebuildReady\n templatePath\n }\n }\n }\n }\n }\n }\n": typeof types.GetDockerContainersDocument,
"\n mutation CreateDockerFolderWithItems(\n $name: String!\n $parentId: String\n $sourceEntryIds: [String!]\n $position: Float\n ) {\n createDockerFolderWithItems(\n name: $name\n parentId: $parentId\n sourceEntryIds: $sourceEntryIds\n position: $position\n ) {\n version\n views {\n id\n name\n rootId\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n }\n": typeof types.CreateDockerFolderWithItemsDocument,
"\n mutation CreateDockerFolder($name: String!, $parentId: String, $childrenIds: [String!]) {\n createDockerFolder(name: $name, parentId: $parentId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n rootId\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n }\n }\n }\n }\n": typeof types.CreateDockerFolderDocument,
@@ -96,6 +97,7 @@ const documents: Documents = {
"\n query Unified {\n settings {\n unified {\n id\n dataSchema\n uiSchema\n values\n }\n }\n }\n": types.UnifiedDocument,
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": types.UpdateConnectSettingsDocument,
"\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n labels\n }\n }\n }\n": types.GetDockerActiveContainerDocument,
"\n query GetDockerContainerSizes {\n docker {\n id\n containers(skipCache: true) {\n id\n names\n sizeRootFs\n sizeRw\n sizeLog\n }\n }\n }\n": types.GetDockerContainerSizesDocument,
"\n query GetDockerContainers($skipCache: Boolean = false) {\n docker {\n id\n containers(skipCache: $skipCache) {\n id\n names\n state\n status\n image\n created\n autoStart\n autoStartOrder\n autoStartWait\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n mounts\n }\n organizer(skipCache: $skipCache) {\n version\n views {\n id\n name\n rootId\n prefs\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n icon\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n networkSettings\n mounts\n created\n isUpdateAvailable\n isRebuildReady\n templatePath\n }\n }\n }\n }\n }\n }\n": types.GetDockerContainersDocument,
"\n mutation CreateDockerFolderWithItems(\n $name: String!\n $parentId: String\n $sourceEntryIds: [String!]\n $position: Float\n ) {\n createDockerFolderWithItems(\n name: $name\n parentId: $parentId\n sourceEntryIds: $sourceEntryIds\n position: $position\n ) {\n version\n views {\n id\n name\n rootId\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n }\n": types.CreateDockerFolderWithItemsDocument,
"\n mutation CreateDockerFolder($name: String!, $parentId: String, $childrenIds: [String!]) {\n createDockerFolder(name: $name, parentId: $parentId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n rootId\n flatEntries {\n id\n type\n name\n parentId\n depth\n position\n path\n hasChildren\n childrenIds\n }\n }\n }\n }\n": types.CreateDockerFolderDocument,
@@ -222,6 +224,10 @@ export function graphql(source: "\n mutation UpdateConnectSettings($input: JSON
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n labels\n }\n }\n }\n"): (typeof documents)["\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports {\n privatePort\n publicPort\n type\n }\n hostConfig {\n networkMode\n }\n networkSettings\n labels\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query GetDockerContainerSizes {\n docker {\n id\n containers(skipCache: true) {\n id\n names\n sizeRootFs\n sizeRw\n sizeLog\n }\n }\n }\n"): (typeof documents)["\n query GetDockerContainerSizes {\n docker {\n id\n containers(skipCache: true) {\n id\n names\n sizeRootFs\n sizeRw\n sizeLog\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

View File

@@ -730,8 +730,12 @@ export type DockerContainer = Node & {
names: Array<Scalars['String']['output']>;
networkSettings?: Maybe<Scalars['JSON']['output']>;
ports: Array<ContainerPort>;
/** Size of container logs (in bytes) */
sizeLog?: Maybe<Scalars['BigInt']['output']>;
/** Total size of all files in the container (in bytes) */
sizeRootFs?: Maybe<Scalars['BigInt']['output']>;
/** Size of writable layer (in bytes) */
sizeRw?: Maybe<Scalars['BigInt']['output']>;
state: ContainerState;
status: Scalars['String']['output'];
templatePath?: Maybe<Scalars['String']['output']>;
@@ -2778,6 +2782,11 @@ export type GetDockerActiveContainerQueryVariables = Exact<{
export type GetDockerActiveContainerQuery = { __typename?: 'Query', docker: { __typename?: 'Docker', id: string, containers: Array<{ __typename?: 'DockerContainer', id: string, names: Array<string>, image: string, created: number, state: ContainerState, status: string, autoStart: boolean, networkSettings?: any | null, labels?: any | null, ports: Array<{ __typename?: 'ContainerPort', privatePort?: number | null, publicPort?: number | null, type: ContainerPortType }>, hostConfig?: { __typename?: 'ContainerHostConfig', networkMode: string } | null }> } };
export type GetDockerContainerSizesQueryVariables = Exact<{ [key: string]: never; }>;
export type GetDockerContainerSizesQuery = { __typename?: 'Query', docker: { __typename?: 'Docker', id: string, containers: Array<{ __typename?: 'DockerContainer', id: string, names: Array<string>, sizeRootFs?: number | null, sizeRw?: number | null, sizeLog?: number | null }> } };
export type GetDockerContainersQueryVariables = Exact<{
skipCache?: InputMaybe<Scalars['Boolean']['input']>;
}>;
@@ -3138,6 +3147,7 @@ export const GetPermissionsForRolesDocument = {"kind":"Document","definitions":[
export const UnifiedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Unified"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"settings"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"unified"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"dataSchema"}},{"kind":"Field","name":{"kind":"Name","value":"uiSchema"}},{"kind":"Field","name":{"kind":"Name","value":"values"}}]}}]}}]}}]} as unknown as DocumentNode<UnifiedQuery, UnifiedQueryVariables>;
export const UpdateConnectSettingsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateConnectSettings"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"JSON"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateSettings"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"restartRequired"}},{"kind":"Field","name":{"kind":"Name","value":"values"}}]}}]}}]} as unknown as DocumentNode<UpdateConnectSettingsMutation, UpdateConnectSettingsMutationVariables>;
export const GetDockerActiveContainerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDockerActiveContainer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PrefixedID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"docker"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"containers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"names"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"autoStart"}},{"kind":"Field","name":{"kind":"Name","value":"ports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"privatePort"}},{"kind":"Field","name":{"kind":"Name","value":"publicPort"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"hostConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"networkMode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"networkSettings"}},{"kind":"Field","name":{"kind":"Name","value":"labels"}}]}}]}}]}}]} as unknown as DocumentNode<GetDockerActiveContainerQuery, GetDockerActiveContainerQueryVariables>;
export const GetDockerContainerSizesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDockerContainerSizes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"docker"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"containers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"skipCache"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"names"}},{"kind":"Field","name":{"kind":"Name","value":"sizeRootFs"}},{"kind":"Field","name":{"kind":"Name","value":"sizeRw"}},{"kind":"Field","name":{"kind":"Name","value":"sizeLog"}}]}}]}}]}}]} as unknown as DocumentNode<GetDockerContainerSizesQuery, GetDockerContainerSizesQueryVariables>;
export const GetDockerContainersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDockerContainers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"skipCache"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}},"defaultValue":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"docker"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"containers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"skipCache"},"value":{"kind":"Variable","name":{"kind":"Name","value":"skipCache"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"names"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"autoStart"}},{"kind":"Field","name":{"kind":"Name","value":"autoStartOrder"}},{"kind":"Field","name":{"kind":"Name","value":"autoStartWait"}},{"kind":"Field","name":{"kind":"Name","value":"ports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"privatePort"}},{"kind":"Field","name":{"kind":"Name","value":"publicPort"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"hostConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"networkMode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"networkSettings"}},{"kind":"Field","name":{"kind":"Name","value":"mounts"}}]}},{"kind":"Field","name":{"kind":"Name","value":"organizer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"skipCache"},"value":{"kind":"Variable","name":{"kind":"Name","value":"skipCache"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"views"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"rootId"}},{"kind":"Field","name":{"kind":"Name","value":"prefs"}},{"kind":"Field","name":{"kind":"Name","value":"flatEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"parentId"}},{"kind":"Field","name":{"kind":"Name","value":"depth"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"hasChildren"}},{"kind":"Field","name":{"kind":"Name","value":"childrenIds"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"names"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"ports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"privatePort"}},{"kind":"Field","name":{"kind":"Name","value":"publicPort"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"autoStart"}},{"kind":"Field","name":{"kind":"Name","value":"hostConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"networkMode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"networkSettings"}},{"kind":"Field","name":{"kind":"Name","value":"mounts"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"isUpdateAvailable"}},{"kind":"Field","name":{"kind":"Name","value":"isRebuildReady"}},{"kind":"Field","name":{"kind":"Name","value":"templatePath"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetDockerContainersQuery, GetDockerContainersQueryVariables>;
export const CreateDockerFolderWithItemsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateDockerFolderWithItems"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"parentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sourceEntryIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"position"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createDockerFolderWithItems"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"parentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"parentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"sourceEntryIds"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sourceEntryIds"}}},{"kind":"Argument","name":{"kind":"Name","value":"position"},"value":{"kind":"Variable","name":{"kind":"Name","value":"position"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"views"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"rootId"}},{"kind":"Field","name":{"kind":"Name","value":"flatEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"parentId"}},{"kind":"Field","name":{"kind":"Name","value":"depth"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"hasChildren"}},{"kind":"Field","name":{"kind":"Name","value":"childrenIds"}},{"kind":"Field","name":{"kind":"Name","value":"meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"names"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"ports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"privatePort"}},{"kind":"Field","name":{"kind":"Name","value":"publicPort"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"autoStart"}},{"kind":"Field","name":{"kind":"Name","value":"hostConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"networkMode"}}]}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"isUpdateAvailable"}},{"kind":"Field","name":{"kind":"Name","value":"isRebuildReady"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<CreateDockerFolderWithItemsMutation, CreateDockerFolderWithItemsMutationVariables>;
export const CreateDockerFolderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateDockerFolder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"parentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"childrenIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createDockerFolder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"parentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"parentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"childrenIds"},"value":{"kind":"Variable","name":{"kind":"Name","value":"childrenIds"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"views"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"rootId"}},{"kind":"Field","name":{"kind":"Name","value":"flatEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"parentId"}},{"kind":"Field","name":{"kind":"Name","value":"depth"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"hasChildren"}},{"kind":"Field","name":{"kind":"Name","value":"childrenIds"}}]}}]}}]}}]}}]} as unknown as DocumentNode<CreateDockerFolderMutation, CreateDockerFolderMutationVariables>;