diff --git a/agent/docker.go b/agent/docker.go index 53b6ab53..d2ca654a 100644 --- a/agent/docker.go +++ b/agent/docker.go @@ -356,7 +356,7 @@ func (dm *dockerManager) updateContainerStats(ctr *container.ApiInfo, cacheTimeM // add empty values if they doesn't exist in map stats, initialized := dm.containerStatsMap[ctr.IdShort] if !initialized { - stats = &container.Stats{Name: name, Id: ctr.IdShort} + stats = &container.Stats{Name: name, Id: ctr.IdShort, Image: ctr.Image} dm.containerStatsMap[ctr.IdShort] = stats } diff --git a/internal/entities/container/container.go b/internal/entities/container/container.go index ae503d55..ae9df4e6 100644 --- a/internal/entities/container/container.go +++ b/internal/entities/container/container.go @@ -9,7 +9,7 @@ type ApiInfo struct { Names []string Status string State string - // Image string + Image string // ImageID string // Command string // Created int64 @@ -130,6 +130,7 @@ type Stats struct { Health DockerHealth `json:"-" cbor:"5,keyasint"` Status string `json:"-" cbor:"6,keyasint"` Id string `json:"-" cbor:"7,keyasint"` + Image string `json:"-" cbor:"8,keyasint"` // PrevCpu [2]uint64 `json:"-"` CpuSystem uint64 `json:"-"` CpuContainer uint64 `json:"-"` diff --git a/internal/hub/systems/system.go b/internal/hub/systems/system.go index 253ef347..78615a95 100644 --- a/internal/hub/systems/system.go +++ b/internal/hub/systems/system.go @@ -196,9 +196,10 @@ func createContainerRecords(app core.App, data []*container.Stats, systemId stri valueStrings := make([]string, 0, len(data)) for i, container := range data { suffix := fmt.Sprintf("%d", i) - valueStrings = append(valueStrings, fmt.Sprintf("({:id%[1]s}, {:system}, {:name%[1]s}, {:status%[1]s}, {:health%[1]s}, {:cpu%[1]s}, {:memory%[1]s}, {:net%[1]s}, {:updated})", suffix)) + valueStrings = append(valueStrings, fmt.Sprintf("({:id%[1]s}, {:system}, {:name%[1]s}, {:image%[1]s}, {:status%[1]s}, {:health%[1]s}, {:cpu%[1]s}, {:memory%[1]s}, {:net%[1]s}, {:updated})", suffix)) params["id"+suffix] = container.Id params["name"+suffix] = container.Name + params["image"+suffix] = container.Image params["status"+suffix] = container.Status params["health"+suffix] = container.Health params["cpu"+suffix] = container.Cpu @@ -206,7 +207,7 @@ func createContainerRecords(app core.App, data []*container.Stats, systemId stri params["net"+suffix] = container.NetworkSent + container.NetworkRecv } queryString := fmt.Sprintf( - "INSERT INTO containers (id, system, name, status, health, cpu, memory, net, updated) VALUES %s ON CONFLICT(id) DO UPDATE SET system = excluded.system, name = excluded.name, status = excluded.status, health = excluded.health, cpu = excluded.cpu, memory = excluded.memory, net = excluded.net, updated = excluded.updated", + "INSERT INTO containers (id, system, name, image, status, health, cpu, memory, net, updated) VALUES %s ON CONFLICT(id) DO UPDATE SET system = excluded.system, name = excluded.name, image = excluded.image, status = excluded.status, health = excluded.health, cpu = excluded.cpu, memory = excluded.memory, net = excluded.net, updated = excluded.updated", strings.Join(valueStrings, ","), ) _, err := app.DB().NewQuery(queryString).Bind(params).Execute() diff --git a/internal/migrations/0_collections_snapshot_0_14_0.go b/internal/migrations/0_collections_snapshot_0_14_1.go similarity index 98% rename from internal/migrations/0_collections_snapshot_0_14_0.go rename to internal/migrations/0_collections_snapshot_0_14_1.go index f59bf48d..f95a6b35 100644 --- a/internal/migrations/0_collections_snapshot_0_14_0.go +++ b/internal/migrations/0_collections_snapshot_0_14_1.go @@ -984,6 +984,20 @@ func init() { "required": true, "system": false, "type": "number" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3309110367", + "max": 0, + "min": 0, + "name": "image", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" } ], "indexes": [ diff --git a/internal/site/src/components/containers-table/containers-table-columns.tsx b/internal/site/src/components/containers-table/containers-table-columns.tsx index bed55238..3eb44079 100644 --- a/internal/site/src/components/containers-table/containers-table-columns.tsx +++ b/internal/site/src/components/containers-table/containers-table-columns.tsx @@ -8,7 +8,7 @@ import { ClockIcon, ContainerIcon, CpuIcon, - HashIcon, + LayersIcon, MemoryStickIcon, ServerIcon, ShieldCheckIcon, @@ -58,15 +58,15 @@ export const containerChartCols: ColumnDef[] = [ return {allSystems[getValue() as string]?.name ?? ""} }, }, - { - id: "id", - accessorFn: (record) => record.id, - sortingFn: (a, b) => a.original.id.localeCompare(b.original.id), - header: ({ column }) => , - cell: ({ getValue }) => { - return {getValue() as string} - }, - }, + // { + // id: "id", + // accessorFn: (record) => record.id, + // sortingFn: (a, b) => a.original.id.localeCompare(b.original.id), + // header: ({ column }) => , + // cell: ({ getValue }) => { + // return {getValue() as string} + // }, + // }, { id: "cpu", accessorFn: (record) => record.cpu, @@ -125,6 +125,15 @@ export const containerChartCols: ColumnDef[] = [ ) }, }, + { + id: "image", + sortingFn: (a, b) => a.original.image.localeCompare(b.original.image), + accessorFn: (record) => record.image, + header: ({ column }) => , + cell: ({ getValue }) => { + return {getValue() as string} + }, + }, { id: "status", accessorFn: (record) => record.status, diff --git a/internal/site/src/components/containers-table/containers-table.tsx b/internal/site/src/components/containers-table/containers-table.tsx index 6d4bced9..d896ae56 100644 --- a/internal/site/src/components/containers-table/containers-table.tsx +++ b/internal/site/src/components/containers-table/containers-table.tsx @@ -48,7 +48,7 @@ export default function ContainersTable({ systemId }: { systemId?: string }) { useEffect(() => { const pbOptions = { - fields: "id,name,cpu,memory,net,health,status,system,updated", + fields: "id,name,image,cpu,memory,net,health,status,system,updated", } const fetchData = (lastXMs: number) => { @@ -123,7 +123,8 @@ export default function ContainersTable({ systemId }: { systemId?: string }) { const name = container.name ?? "" const status = container.status ?? "" const healthLabel = ContainerHealthLabels[container.health as ContainerHealth] ?? "" - const searchString = `${systemName} ${id} ${name} ${healthLabel} ${status}`.toLowerCase() + const image = container.image ?? "" + const searchString = `${systemName} ${id} ${name} ${healthLabel} ${status} ${image}`.toLowerCase() return (filterValue as string) .toLowerCase() @@ -195,7 +196,7 @@ const AllContainersTable = memo( > {/* add header height to table size */}
- +
{rows.length ? ( @@ -325,11 +326,13 @@ function ContainerSheet({ sheetOpen, setSheetOpen, activeContainer }: { sheetOpe {container.name} - + {$allSystemsById.get()[container.system]?.name ?? ""} {container.status} + {container.image} + {container.id} {ContainerHealthLabels[container.health as ContainerHealth]} diff --git a/internal/site/src/types.d.ts b/internal/site/src/types.d.ts index eba8b07f..5d988c77 100644 --- a/internal/site/src/types.d.ts +++ b/internal/site/src/types.d.ts @@ -240,6 +240,7 @@ export interface ContainerRecord extends RecordModel { id: string system: string name: string + image: string cpu: number memory: number net: number diff --git a/supplemental/CHANGELOG.md b/supplemental/CHANGELOG.md index 0e29fc64..b26510ac 100644 --- a/supplemental/CHANGELOG.md +++ b/supplemental/CHANGELOG.md @@ -1,9 +1,13 @@ ## 0.14.1 -- Add `MFA_OTP` environment variable to enable email-based one-time password for users and/or superusers. +- Add `MFA_OTP` environment variable to enable email-based one-time password for users and/or superusers. + +- Add image name to containers table. (#1302) - Add spacing for long temperature chart tooltip. (#1299) +- Fix sorting by status in containers table. (#1294) + ## 0.14.0 - Add `/containers` page for viewing current status of all running containers. (#928)