mirror of
https://github.com/amir20/dozzle.git
synced 2026-08-07 19:11:57 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f393d0d3e6 | |||
| 9988271490 | |||
| 05f76c4f57 | |||
| 20c1adbd7e | |||
| d44ab349b9 | |||
| 21367bcc36 | |||
| 6ece0df082 |
Vendored
+2
@@ -122,6 +122,8 @@ declare module 'vue' {
|
||||
'Ph:globeSimple': typeof import('~icons/ph/globe-simple')['default']
|
||||
'Ph:stack': typeof import('~icons/ph/stack')['default']
|
||||
'Ph:stackSimple': typeof import('~icons/ph/stack-simple')['default']
|
||||
PhArrowDown: typeof import('~icons/ph/arrow-down')['default']
|
||||
PhArrowUp: typeof import('~icons/ph/arrow-up')['default']
|
||||
Popup: typeof import('./components/Popup.vue')['default']
|
||||
RandomColorTag: typeof import('./components/LogViewer/RandomColorTag.vue')['default']
|
||||
RelativeTime: typeof import('./components/common/RelativeTime.vue')['default']
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<div class="flex gap-1 md:gap-4">
|
||||
<div class="grid min-w-15 grid-cols-[auto_1fr] items-center gap-0.5 text-xs leading-none max-md:hidden">
|
||||
<PhArrowUp class="text-primary" />
|
||||
<span class="tabular-nums">{{ formatBytes(networkRate.tx, { short: true, decimals: 1 }) }}/s</span>
|
||||
<PhArrowDown class="text-secondary" />
|
||||
<span class="tabular-nums">{{ formatBytes(networkRate.rx, { short: true, decimals: 1 }) }}/s</span>
|
||||
</div>
|
||||
<StatMonitor
|
||||
:data="cpuData"
|
||||
:icon="PhCpu"
|
||||
@@ -35,9 +41,10 @@ const { containers } = defineProps<{
|
||||
containers: Container[];
|
||||
}>();
|
||||
|
||||
const totalStat = ref<Stat>({ cpu: 0, memory: 0, memoryUsage: 0 });
|
||||
const totalStat = ref<Stat>({ cpu: 0, memory: 0, memoryUsage: 0, networkRxTotal: 0, networkTxTotal: 0 });
|
||||
const { history, reset } = useSimpleRefHistory(totalStat, { capacity: 300 });
|
||||
const { hosts } = useHosts();
|
||||
const networkRate = ref({ rx: 0, tx: 0 });
|
||||
|
||||
const roundCPU = (num: number) => (Number.isInteger(num) ? num.toFixed(0) : num.toFixed(1));
|
||||
|
||||
@@ -65,33 +72,72 @@ watch(
|
||||
cpu: acc.cpu + item.cpu / cores,
|
||||
memory: acc.memory + item.memory,
|
||||
memoryUsage: acc.memoryUsage + item.memoryUsage,
|
||||
networkRxTotal: acc.networkRxTotal + item.networkRxTotal,
|
||||
networkTxTotal: acc.networkTxTotal + item.networkTxTotal,
|
||||
};
|
||||
},
|
||||
{ cpu: 0, memory: 0, memoryUsage: 0 },
|
||||
{ cpu: 0, memory: 0, memoryUsage: 0, networkRxTotal: 0, networkTxTotal: 0 },
|
||||
);
|
||||
initial.push(stat);
|
||||
}
|
||||
totalStat.value = initial[0];
|
||||
reset({ initial: initial.reverse() });
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const limits = computed(() => {
|
||||
return containers.reduce(
|
||||
(acc, container) => {
|
||||
const cores = toContainerCores(container);
|
||||
const hostInfo = hosts.value[container.host];
|
||||
// Group containers by host
|
||||
const containersByHost = new Map<string, Container[]>();
|
||||
containers.forEach((container) => {
|
||||
if (!containersByHost.has(container.host)) {
|
||||
containersByHost.set(container.host, []);
|
||||
}
|
||||
containersByHost.get(container.host)!.push(container);
|
||||
});
|
||||
|
||||
return {
|
||||
cpu: acc.cpu + cores,
|
||||
memory: acc.memory + (container.memoryLimit || hostInfo?.memTotal || 0),
|
||||
};
|
||||
},
|
||||
{ cpu: 0, memory: 0 },
|
||||
);
|
||||
let totalCpu = 0;
|
||||
let totalMemory = 0;
|
||||
|
||||
// Process each host independently
|
||||
containersByHost.forEach((hostContainers, hostId) => {
|
||||
const hostInfo = hosts.value[hostId];
|
||||
const hostTotalMemory = hostInfo?.memTotal || 0;
|
||||
const hostTotalCpu = hostInfo?.nCPU || 0;
|
||||
|
||||
// Check if any container lacks limits
|
||||
const hasUnlimitedCpu = hostContainers.some((c) => !c.cpuLimit || c.cpuLimit <= 0);
|
||||
const hasUnlimitedMemory = hostContainers.some((c) => !c.memoryLimit);
|
||||
|
||||
// Calculate CPU for this host
|
||||
if (hasUnlimitedCpu) {
|
||||
// At least one container has no limit, use host total
|
||||
totalCpu += hostTotalCpu;
|
||||
} else {
|
||||
// All containers have limits, sum them up (capped at host total)
|
||||
const sumCpu = hostContainers.reduce((sum, c) => sum + 1, 0);
|
||||
totalCpu += Math.min(sumCpu, hostTotalCpu);
|
||||
}
|
||||
|
||||
// Calculate Memory for this host
|
||||
if (hasUnlimitedMemory) {
|
||||
// At least one container has no limit, use host total
|
||||
totalMemory += hostTotalMemory;
|
||||
} else {
|
||||
// All containers have limits, sum them up (capped at host total)
|
||||
const sumMemory = hostContainers.reduce((sum, c) => sum + (c.memoryLimit || 0), 0);
|
||||
totalMemory += Math.min(sumMemory, hostTotalMemory);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
cpu: totalCpu,
|
||||
memory: totalMemory,
|
||||
};
|
||||
});
|
||||
|
||||
useIntervalFn(() => {
|
||||
const previousStat = totalStat.value;
|
||||
totalStat.value = containers.reduce(
|
||||
(acc, container) => {
|
||||
const cores = toContainerCores(container);
|
||||
@@ -99,10 +145,17 @@ useIntervalFn(() => {
|
||||
cpu: acc.cpu + container.stat.cpu / cores,
|
||||
memory: acc.memory + container.stat.memory,
|
||||
memoryUsage: acc.memoryUsage + container.stat.memoryUsage,
|
||||
networkRxTotal: acc.networkRxTotal + container.stat.networkRxTotal,
|
||||
networkTxTotal: acc.networkTxTotal + container.stat.networkTxTotal,
|
||||
};
|
||||
},
|
||||
{ cpu: 0, memory: 0, memoryUsage: 0 },
|
||||
{ cpu: 0, memory: 0, memoryUsage: 0, networkRxTotal: 0, networkTxTotal: 0 },
|
||||
);
|
||||
|
||||
networkRate.value = {
|
||||
rx: Math.max(0, totalStat.value.networkRxTotal - previousStat.networkRxTotal),
|
||||
tx: Math.max(0, totalStat.value.networkTxTotal - previousStat.networkTxTotal),
|
||||
};
|
||||
}, 1000);
|
||||
|
||||
const cpuData = computed(() =>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
<div class="bg-base-200 flex gap-1 rounded-sm p-px text-xs md:absolute md:-top-2 md:-left-0.5">
|
||||
<component :is="icon" class="text-sm" />
|
||||
<div class="font-bold select-none">
|
||||
<div class="font-bold tabular-nums select-none">
|
||||
{{ displayValue }}
|
||||
<span v-if="limit !== -1 && !mouseOver" class="max-md:hidden"> / {{ limit }} </span>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<component :is="icon" class="text-lg" />
|
||||
<span>{{ label }}</span>
|
||||
</div>
|
||||
<div class="mb-1.5 text-lg font-semibold">{{ formattedValue }}</div>
|
||||
<div class="text-base-content/60 mb-1 text-xs max-md:hidden">
|
||||
<div class="mb-1.5 text-lg font-semibold tabular-nums">{{ formattedValue }}</div>
|
||||
<div class="text-base-content/60 mb-1 text-xs tabular-nums max-md:hidden">
|
||||
avg {{ formatValue(average) }} • pk {{ formatValue(peak) }}
|
||||
</div>
|
||||
<BarChart class="h-8" :chartData="percentData" :barClass="barClass" />
|
||||
|
||||
@@ -51,7 +51,9 @@ export class Container {
|
||||
public readonly group?: string,
|
||||
public health?: ContainerHealth,
|
||||
) {
|
||||
this._stat = ref(stats.at(-1) || ({ cpu: 0, memory: 0, memoryUsage: 0 } as Stat));
|
||||
this._stat = ref(
|
||||
stats.at(-1) || ({ cpu: 0, memory: 0, memoryUsage: 0, networkRxTotal: 0, networkTxTotal: 0 } as Stat),
|
||||
);
|
||||
const { history } = useSimpleRefHistory(this._stat, { capacity: 300, deep: true, initial: stats });
|
||||
this._statsHistory = history;
|
||||
const { movingAverage } = useExponentialMovingAverage(this._stat, 0.2);
|
||||
|
||||
Vendored
+2
@@ -3,6 +3,8 @@ export interface ContainerStat {
|
||||
readonly cpu: number;
|
||||
readonly memory: number;
|
||||
readonly memoryUsage: number;
|
||||
readonly networkRxTotal: number;
|
||||
readonly networkTxTotal: number;
|
||||
}
|
||||
|
||||
export type ContainerJson = {
|
||||
|
||||
@@ -2,7 +2,7 @@ export function formatBytes(
|
||||
bytes: number,
|
||||
{ decimals = 2, short = false }: { decimals?: number; short?: boolean } = { decimals: 2, short: false },
|
||||
) {
|
||||
if (bytes === 0) return "0 Bytes";
|
||||
if (bytes === 0) return short ? "0B" : "0 Bytes";
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
@@ -4,8 +4,20 @@ title: What is Dozzle?
|
||||
|
||||
# What is Dozzle?
|
||||
|
||||
Dozzle is an open-source project sponsored by Docker OSS. It is a log viewer designed to simplify monitoring and debugging containers. This lightweight, web-based application offers real-time log streaming, filtering, and searching capabilities through an intuitive user interface.
|
||||
Dozzle is an open-source project sponsored by Docker OSS. It is a lightweight, web-based log viewer designed to simplify monitoring and debugging containerized applications across Docker, Docker Swarm, and Kubernetes environments.
|
||||
|
||||
Users can quickly access logs generated by their Docker containers, making it an essential tool for debugging and troubleshooting applications in a Docker environment. By default, Dozzle supports JSON logs with intelligent color coding.
|
||||
## Key Features
|
||||
|
||||
Dozzle is easy to install and configure, making it an ideal solution for developers and system administrators seeking an efficient, user-friendly log viewer for their Docker environment. The tool is available under the MIT license and is actively maintained by its developer, Amir Raminfar.
|
||||
**Real-time Monitoring**: Stream logs from running containers with instant updates through an intuitive web interface. Monitor CPU, memory, and network usage with live metrics and historical visualizations.
|
||||
|
||||
**Flexible Deployment**: Deploy as a standalone server for single or multi-host Docker monitoring, enable automatic discovery in Docker Swarm clusters, or monitor pod logs in Kubernetes environments.
|
||||
|
||||
**Advanced Log Handling**: Automatically detects and formats JSON logs with intelligent color coding. Supports simple text logs, structured JSON logs, and multi-line grouped entries with powerful filtering and search capabilities.
|
||||
|
||||
**Multi-Host Support**: Monitor containers across multiple Docker hosts simultaneously through a distributed agent architecture using gRPC.
|
||||
|
||||
**Interactive Terminal**: Attach to running containers or execute commands directly through the web interface.
|
||||
|
||||
**Lightweight & Fast**: Built with Go backend and Vue 3 frontend, Dozzle uses efficient streaming protocols (SSE/WebSocket) and requires minimal resources.
|
||||
|
||||
Dozzle is easy to install and configure, making it an ideal solution for developers and system administrators seeking an efficient log viewer for their containerized environments. The tool is available under the MIT license and is actively maintained by its developer, Amir Raminfar.
|
||||
|
||||
@@ -57,6 +57,7 @@ require (
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||
github.com/expr-lang/expr v1.17.7 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
|
||||
@@ -78,6 +78,8 @@ github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtz
|
||||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
||||
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/expr-lang/expr v1.17.7 h1:Q0xY/e/2aCIp8g9s/LGvMDCC5PxYlvHgDZRQ4y16JX8=
|
||||
github.com/expr-lang/expr v1.17.7/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
|
||||
+90
-216
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc v6.33.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.33.3
|
||||
// source: rpc.proto
|
||||
|
||||
package pb
|
||||
@@ -1272,220 +1272,94 @@ func (x *ContainerAttachResponse) GetStdout() []byte {
|
||||
|
||||
var File_rpc_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_rpc_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x09, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a,
|
||||
0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46,
|
||||
0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74,
|
||||
0x65, 0x72, 0x1a, 0x53, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65,
|
||||
0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x73, 0x22, 0x4d, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
|
||||
0x22, 0xd1, 0x01, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x06, 0x66,
|
||||
0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74,
|
||||
0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a,
|
||||
0x53, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a,
|
||||
0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
|
||||
0x22, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74,
|
||||
0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x12,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f, 0x67,
|
||||
0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x0a,
|
||||
0x17, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69,
|
||||
0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x05,
|
||||
0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x20,
|
||||
0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73,
|
||||
0x22, 0xbf, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79,
|
||||
0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05,
|
||||
0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30,
|
||||
0x0a, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70,
|
||||
0x65, 0x73, 0x22, 0x2c, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42,
|
||||
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
|
||||
0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x2e, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22,
|
||||
0x14, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x42, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53,
|
||||
0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04,
|
||||
0x73, 0x74, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53,
|
||||
0x74, 0x61, 0x74, 0x52, 0x04, 0x73, 0x74, 0x61, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x48, 0x6f, 0x73,
|
||||
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x10,
|
||||
0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x22, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x04,
|
||||
0x68, 0x6f, 0x73, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x1e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52,
|
||||
0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x6d, 0x0a, 0x16, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x05, 0x73, 0x74, 0x64,
|
||||
0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69,
|
||||
0x6e, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22,
|
||||
0x3d, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
|
||||
0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x2f,
|
||||
0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x22,
|
||||
0x90, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74,
|
||||
0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x05,
|
||||
0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x73,
|
||||
0x74, 0x64, 0x69, 0x6e, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52,
|
||||
0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x22, 0x31, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41,
|
||||
0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73,
|
||||
0x74, 0x64, 0x6f, 0x75, 0x74, 0x32, 0xa1, 0x08, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a,
|
||||
0x0d, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x12,
|
||||
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f,
|
||||
0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57,
|
||||
0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74,
|
||||
0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f,
|
||||
0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79,
|
||||
0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42,
|
||||
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
|
||||
0x12, 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61,
|
||||
0x74, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
|
||||
0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x27, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
|
||||
0x45, 0x78, 0x65, 0x63, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x43,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x12, 0x20,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x62, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
const file_rpc_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\trpc.proto\x12\bprotobuf\x1a\vtypes.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb1\x01\n" +
|
||||
"\x15ListContainersRequest\x12C\n" +
|
||||
"\x06filter\x18\x01 \x03(\v2+.protobuf.ListContainersRequest.FilterEntryR\x06filter\x1aS\n" +
|
||||
"\vFilterEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12.\n" +
|
||||
"\x05value\x18\x02 \x01(\v2\x18.protobuf.RepeatedStringR\x05value:\x028\x01\"(\n" +
|
||||
"\x0eRepeatedString\x12\x16\n" +
|
||||
"\x06values\x18\x01 \x03(\tR\x06values\"M\n" +
|
||||
"\x16ListContainersResponse\x123\n" +
|
||||
"\n" +
|
||||
"containers\x18\x01 \x03(\v2\x13.protobuf.ContainerR\n" +
|
||||
"containers\"\xd1\x01\n" +
|
||||
"\x14FindContainerRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x12B\n" +
|
||||
"\x06filter\x18\x02 \x03(\v2*.protobuf.FindContainerRequest.FilterEntryR\x06filter\x1aS\n" +
|
||||
"\vFilterEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12.\n" +
|
||||
"\x05value\x18\x02 \x01(\v2\x18.protobuf.RepeatedStringR\x05value:\x028\x01\"J\n" +
|
||||
"\x15FindContainerResponse\x121\n" +
|
||||
"\tcontainer\x18\x01 \x01(\v2\x13.protobuf.ContainerR\tcontainer\"\x89\x01\n" +
|
||||
"\x11StreamLogsRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" +
|
||||
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x12 \n" +
|
||||
"\vstreamTypes\x18\x03 \x01(\x05R\vstreamTypes\">\n" +
|
||||
"\x12StreamLogsResponse\x12(\n" +
|
||||
"\x05event\x18\x01 \x01(\v2\x12.protobuf.LogEventR\x05event\"\xc1\x01\n" +
|
||||
"\x17LogsBetweenDatesRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" +
|
||||
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x120\n" +
|
||||
"\x05until\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x05until\x12 \n" +
|
||||
"\vstreamTypes\x18\x04 \x01(\x05R\vstreamTypes\"\xbf\x01\n" +
|
||||
"\x15StreamRawBytesRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" +
|
||||
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x120\n" +
|
||||
"\x05until\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x05until\x12 \n" +
|
||||
"\vstreamTypes\x18\x04 \x01(\x05R\vstreamTypes\",\n" +
|
||||
"\x16StreamRawBytesResponse\x12\x12\n" +
|
||||
"\x04data\x18\x01 \x01(\fR\x04data\"\x15\n" +
|
||||
"\x13StreamEventsRequest\"F\n" +
|
||||
"\x14StreamEventsResponse\x12.\n" +
|
||||
"\x05event\x18\x01 \x01(\v2\x18.protobuf.ContainerEventR\x05event\"\x14\n" +
|
||||
"\x12StreamStatsRequest\"B\n" +
|
||||
"\x13StreamStatsResponse\x12+\n" +
|
||||
"\x04stat\x18\x01 \x01(\v2\x17.protobuf.ContainerStatR\x04stat\"\x11\n" +
|
||||
"\x0fHostInfoRequest\"6\n" +
|
||||
"\x10HostInfoResponse\x12\"\n" +
|
||||
"\x04host\x18\x01 \x01(\v2\x0e.protobuf.HostR\x04host\"\x1f\n" +
|
||||
"\x1dStreamContainerStartedRequest\"S\n" +
|
||||
"\x1eStreamContainerStartedResponse\x121\n" +
|
||||
"\tcontainer\x18\x01 \x01(\v2\x13.protobuf.ContainerR\tcontainer\"m\n" +
|
||||
"\x16ContainerActionRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x121\n" +
|
||||
"\x06action\x18\x02 \x01(\x0e2\x19.protobuf.ContainerActionR\x06action\"\x19\n" +
|
||||
"\x17ContainerActionResponse\"\xa8\x01\n" +
|
||||
"\x14ContainerExecRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x12\x18\n" +
|
||||
"\acommand\x18\x02 \x03(\tR\acommand\x12\x16\n" +
|
||||
"\x05stdin\x18\x03 \x01(\fH\x00R\x05stdin\x121\n" +
|
||||
"\x06resize\x18\x04 \x01(\v2\x17.protobuf.ResizePayloadH\x00R\x06resizeB\t\n" +
|
||||
"\apayload\"=\n" +
|
||||
"\rResizePayload\x12\x14\n" +
|
||||
"\x05width\x18\x01 \x01(\rR\x05width\x12\x16\n" +
|
||||
"\x06height\x18\x02 \x01(\rR\x06height\"/\n" +
|
||||
"\x15ContainerExecResponse\x12\x16\n" +
|
||||
"\x06stdout\x18\x01 \x01(\fR\x06stdout\"\x90\x01\n" +
|
||||
"\x16ContainerAttachRequest\x12 \n" +
|
||||
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x12\x16\n" +
|
||||
"\x05stdin\x18\x02 \x01(\fH\x00R\x05stdin\x121\n" +
|
||||
"\x06resize\x18\x03 \x01(\v2\x17.protobuf.ResizePayloadH\x00R\x06resizeB\t\n" +
|
||||
"\apayload\"1\n" +
|
||||
"\x17ContainerAttachResponse\x12\x16\n" +
|
||||
"\x06stdout\x18\x01 \x01(\fR\x06stdout2\xa1\b\n" +
|
||||
"\fAgentService\x12U\n" +
|
||||
"\x0eListContainers\x12\x1f.protobuf.ListContainersRequest\x1a .protobuf.ListContainersResponse\"\x00\x12R\n" +
|
||||
"\rFindContainer\x12\x1e.protobuf.FindContainerRequest\x1a\x1f.protobuf.FindContainerResponse\"\x00\x12K\n" +
|
||||
"\n" +
|
||||
"StreamLogs\x12\x1b.protobuf.StreamLogsRequest\x1a\x1c.protobuf.StreamLogsResponse\"\x000\x01\x12W\n" +
|
||||
"\x10LogsBetweenDates\x12!.protobuf.LogsBetweenDatesRequest\x1a\x1c.protobuf.StreamLogsResponse\"\x000\x01\x12W\n" +
|
||||
"\x0eStreamRawBytes\x12\x1f.protobuf.StreamRawBytesRequest\x1a .protobuf.StreamRawBytesResponse\"\x000\x01\x12Q\n" +
|
||||
"\fStreamEvents\x12\x1d.protobuf.StreamEventsRequest\x1a\x1e.protobuf.StreamEventsResponse\"\x000\x01\x12N\n" +
|
||||
"\vStreamStats\x12\x1c.protobuf.StreamStatsRequest\x1a\x1d.protobuf.StreamStatsResponse\"\x000\x01\x12o\n" +
|
||||
"\x16StreamContainerStarted\x12'.protobuf.StreamContainerStartedRequest\x1a(.protobuf.StreamContainerStartedResponse\"\x000\x01\x12C\n" +
|
||||
"\bHostInfo\x12\x19.protobuf.HostInfoRequest\x1a\x1a.protobuf.HostInfoResponse\"\x00\x12X\n" +
|
||||
"\x0fContainerAction\x12 .protobuf.ContainerActionRequest\x1a!.protobuf.ContainerActionResponse\"\x00\x12V\n" +
|
||||
"\rContainerExec\x12\x1e.protobuf.ContainerExecRequest\x1a\x1f.protobuf.ContainerExecResponse\"\x00(\x010\x01\x12\\\n" +
|
||||
"\x0fContainerAttach\x12 .protobuf.ContainerAttachRequest\x1a!.protobuf.ContainerAttachResponse\"\x00(\x010\x01B\x13Z\x11internal/agent/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_rpc_proto_rawDescOnce sync.Once
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v6.33.2
|
||||
// - protoc-gen-go-grpc v1.6.0
|
||||
// - protoc v6.33.3
|
||||
// source: rpc.proto
|
||||
|
||||
package pb
|
||||
@@ -266,40 +266,40 @@ type AgentServiceServer interface {
|
||||
type UnimplementedAgentServiceServer struct{}
|
||||
|
||||
func (UnimplementedAgentServiceServer) ListContainers(context.Context, *ListContainersRequest) (*ListContainersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListContainers not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method ListContainers not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) FindContainer(context.Context, *FindContainerRequest) (*FindContainerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FindContainer not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method FindContainer not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) StreamLogs(*StreamLogsRequest, grpc.ServerStreamingServer[StreamLogsResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamLogs not implemented")
|
||||
return status.Error(codes.Unimplemented, "method StreamLogs not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) LogsBetweenDates(*LogsBetweenDatesRequest, grpc.ServerStreamingServer[StreamLogsResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method LogsBetweenDates not implemented")
|
||||
return status.Error(codes.Unimplemented, "method LogsBetweenDates not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) StreamRawBytes(*StreamRawBytesRequest, grpc.ServerStreamingServer[StreamRawBytesResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamRawBytes not implemented")
|
||||
return status.Error(codes.Unimplemented, "method StreamRawBytes not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) StreamEvents(*StreamEventsRequest, grpc.ServerStreamingServer[StreamEventsResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamEvents not implemented")
|
||||
return status.Error(codes.Unimplemented, "method StreamEvents not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) StreamStats(*StreamStatsRequest, grpc.ServerStreamingServer[StreamStatsResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamStats not implemented")
|
||||
return status.Error(codes.Unimplemented, "method StreamStats not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) StreamContainerStarted(*StreamContainerStartedRequest, grpc.ServerStreamingServer[StreamContainerStartedResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method StreamContainerStarted not implemented")
|
||||
return status.Error(codes.Unimplemented, "method StreamContainerStarted not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) HostInfo(context.Context, *HostInfoRequest) (*HostInfoResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method HostInfo not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method HostInfo not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) ContainerAction(context.Context, *ContainerActionRequest) (*ContainerActionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ContainerAction not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method ContainerAction not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) ContainerExec(grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method ContainerExec not implemented")
|
||||
return status.Error(codes.Unimplemented, "method ContainerExec not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) ContainerAttach(grpc.BidiStreamingServer[ContainerAttachRequest, ContainerAttachResponse]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method ContainerAttach not implemented")
|
||||
return status.Error(codes.Unimplemented, "method ContainerAttach not implemented")
|
||||
}
|
||||
func (UnimplementedAgentServiceServer) mustEmbedUnimplementedAgentServiceServer() {}
|
||||
func (UnimplementedAgentServiceServer) testEmbeddedByValue() {}
|
||||
@@ -312,7 +312,7 @@ type UnsafeAgentServiceServer interface {
|
||||
}
|
||||
|
||||
func RegisterAgentServiceServer(s grpc.ServiceRegistrar, srv AgentServiceServer) {
|
||||
// If the following call pancis, it indicates UnimplementedAgentServiceServer was
|
||||
// If the following call panics, it indicates UnimplementedAgentServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
|
||||
+106
-137
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc v6.33.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.33.3
|
||||
// source: types.proto
|
||||
|
||||
package pb
|
||||
@@ -261,13 +261,15 @@ func (x *Container) GetFullyLoaded() bool {
|
||||
}
|
||||
|
||||
type ContainerStat struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
CpuPercent float64 `protobuf:"fixed64,2,opt,name=cpuPercent,proto3" json:"cpuPercent,omitempty"`
|
||||
MemoryUsage float64 `protobuf:"fixed64,3,opt,name=memoryUsage,proto3" json:"memoryUsage,omitempty"`
|
||||
MemoryPercent float64 `protobuf:"fixed64,4,opt,name=memoryPercent,proto3" json:"memoryPercent,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
CpuPercent float64 `protobuf:"fixed64,2,opt,name=cpuPercent,proto3" json:"cpuPercent,omitempty"`
|
||||
MemoryUsage float64 `protobuf:"fixed64,3,opt,name=memoryUsage,proto3" json:"memoryUsage,omitempty"`
|
||||
MemoryPercent float64 `protobuf:"fixed64,4,opt,name=memoryPercent,proto3" json:"memoryPercent,omitempty"`
|
||||
NetworkRxTotal uint64 `protobuf:"varint,5,opt,name=networkRxTotal,proto3" json:"networkRxTotal,omitempty"`
|
||||
NetworkTxTotal uint64 `protobuf:"varint,6,opt,name=networkTxTotal,proto3" json:"networkTxTotal,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ContainerStat) Reset() {
|
||||
@@ -328,6 +330,20 @@ func (x *ContainerStat) GetMemoryPercent() float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ContainerStat) GetNetworkRxTotal() uint64 {
|
||||
if x != nil {
|
||||
return x.NetworkRxTotal
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ContainerStat) GetNetworkTxTotal() uint64 {
|
||||
if x != nil {
|
||||
return x.NetworkTxTotal
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type LogFragment struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
|
||||
@@ -806,134 +822,87 @@ func (x *Host) GetDockerVersion() string {
|
||||
|
||||
var File_types_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_types_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xa2, 0x05, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6d, 0x61,
|
||||
0x67, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x49, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61,
|
||||
0x72, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74,
|
||||
0x74, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x74, 0x79, 0x12, 0x37, 0x0a,
|
||||
0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06,
|
||||
0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18,
|
||||
0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x52, 0x05,
|
||||
0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0e,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65,
|
||||
0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x11, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28,
|
||||
0x01, 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x66,
|
||||
0x75, 0x6c, 0x6c, 0x79, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0b, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x1a, 0x39, 0x0a,
|
||||
0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x87, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x70,
|
||||
0x75, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a,
|
||||
0x63, 0x70, 0x75, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65,
|
||||
0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x01, 0x52, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65,
|
||||
0x6e, 0x74, 0x22, 0x27, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x88, 0x02, 0x0a, 0x08,
|
||||
0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e,
|
||||
0x79, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74,
|
||||
0x72, 0x65, 0x61, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x77, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x29, 0x0a, 0x0d, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x22, 0x43, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x12, 0x33, 0x0a, 0x09, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x4c, 0x6f, 0x67, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x66, 0x72, 0x61,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x24, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x01, 0x0a,
|
||||
0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73,
|
||||
0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xaf, 0x03, 0x0a, 0x04,
|
||||
0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e,
|
||||
0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x77,
|
||||
0x61, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x77, 0x61, 0x72, 0x6d,
|
||||
0x12, 0x32, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74,
|
||||
0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61,
|
||||
0x62, 0x65, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f,
|
||||
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x6f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e,
|
||||
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x33, 0x0a,
|
||||
0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x09, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53,
|
||||
0x74, 0x6f, 0x70, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74,
|
||||
0x10, 0x02, 0x42, 0x13, 0x5a, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
const file_types_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vtypes.proto\x12\bprotobuf\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa2\x05\n" +
|
||||
"\tContainer\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" +
|
||||
"\x05image\x18\x03 \x01(\tR\x05image\x12\x16\n" +
|
||||
"\x06status\x18\x04 \x01(\tR\x06status\x12\x14\n" +
|
||||
"\x05state\x18\x05 \x01(\tR\x05state\x12\x18\n" +
|
||||
"\aImageId\x18\x06 \x01(\tR\aImageId\x124\n" +
|
||||
"\acreated\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\acreated\x124\n" +
|
||||
"\astarted\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\astarted\x12\x16\n" +
|
||||
"\x06health\x18\t \x01(\tR\x06health\x12\x12\n" +
|
||||
"\x04host\x18\n" +
|
||||
" \x01(\tR\x04host\x12\x10\n" +
|
||||
"\x03tty\x18\v \x01(\bR\x03tty\x127\n" +
|
||||
"\x06labels\x18\f \x03(\v2\x1f.protobuf.Container.LabelsEntryR\x06labels\x12-\n" +
|
||||
"\x05stats\x18\r \x03(\v2\x17.protobuf.ContainerStatR\x05stats\x12\x14\n" +
|
||||
"\x05group\x18\x0e \x01(\tR\x05group\x12\x18\n" +
|
||||
"\acommand\x18\x0f \x01(\tR\acommand\x126\n" +
|
||||
"\bfinished\x18\x10 \x01(\v2\x1a.google.protobuf.TimestampR\bfinished\x12 \n" +
|
||||
"\vmemoryLimit\x18\x11 \x01(\x04R\vmemoryLimit\x12\x1a\n" +
|
||||
"\bcpuLimit\x18\x12 \x01(\x01R\bcpuLimit\x12 \n" +
|
||||
"\vfullyLoaded\x18\x13 \x01(\bR\vfullyLoaded\x1a9\n" +
|
||||
"\vLabelsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xd7\x01\n" +
|
||||
"\rContainerStat\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1e\n" +
|
||||
"\n" +
|
||||
"cpuPercent\x18\x02 \x01(\x01R\n" +
|
||||
"cpuPercent\x12 \n" +
|
||||
"\vmemoryUsage\x18\x03 \x01(\x01R\vmemoryUsage\x12$\n" +
|
||||
"\rmemoryPercent\x18\x04 \x01(\x01R\rmemoryPercent\x12&\n" +
|
||||
"\x0enetworkRxTotal\x18\x05 \x01(\x04R\x0enetworkRxTotal\x12&\n" +
|
||||
"\x0enetworkTxTotal\x18\x06 \x01(\x04R\x0enetworkTxTotal\"'\n" +
|
||||
"\vLogFragment\x12\x18\n" +
|
||||
"\amessage\x18\x01 \x01(\tR\amessage\"\x88\x02\n" +
|
||||
"\bLogEvent\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\rR\x02id\x12 \n" +
|
||||
"\vcontainerId\x18\x02 \x01(\tR\vcontainerId\x12.\n" +
|
||||
"\amessage\x18\x03 \x01(\v2\x14.google.protobuf.AnyR\amessage\x128\n" +
|
||||
"\ttimestamp\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x14\n" +
|
||||
"\x05level\x18\x05 \x01(\tR\x05level\x12\x16\n" +
|
||||
"\x06stream\x18\x06 \x01(\tR\x06stream\x12\x12\n" +
|
||||
"\x04type\x18\a \x01(\tR\x04type\x12\x1e\n" +
|
||||
"\n" +
|
||||
"rawMessage\x18\b \x01(\tR\n" +
|
||||
"rawMessage\")\n" +
|
||||
"\rSingleMessage\x12\x18\n" +
|
||||
"\amessage\x18\x01 \x01(\tR\amessage\"C\n" +
|
||||
"\fGroupMessage\x123\n" +
|
||||
"\tfragments\x18\x01 \x03(\v2\x15.protobuf.LogFragmentR\tfragments\"$\n" +
|
||||
"\x0eComplexMessage\x12\x12\n" +
|
||||
"\x04data\x18\x01 \x01(\fR\x04data\"\x8c\x01\n" +
|
||||
"\x0eContainerEvent\x12\x18\n" +
|
||||
"\aactorId\x18\x01 \x01(\tR\aactorId\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04host\x18\x03 \x01(\tR\x04host\x128\n" +
|
||||
"\ttimestamp\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\"\xaf\x03\n" +
|
||||
"\x04Host\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12 \n" +
|
||||
"\vnodeAddress\x18\x03 \x01(\tR\vnodeAddress\x12\x14\n" +
|
||||
"\x05swarm\x18\x04 \x01(\bR\x05swarm\x122\n" +
|
||||
"\x06labels\x18\x05 \x03(\v2\x1a.protobuf.Host.LabelsEntryR\x06labels\x12(\n" +
|
||||
"\x0foperatingSystem\x18\x06 \x01(\tR\x0foperatingSystem\x12\x1c\n" +
|
||||
"\tosVersion\x18\a \x01(\tR\tosVersion\x12\x16\n" +
|
||||
"\x06osType\x18\b \x01(\tR\x06osType\x12\x1a\n" +
|
||||
"\bcpuCores\x18\t \x01(\rR\bcpuCores\x12\x16\n" +
|
||||
"\x06memory\x18\n" +
|
||||
" \x01(\x04R\x06memory\x12\"\n" +
|
||||
"\fagentVersion\x18\v \x01(\tR\fagentVersion\x12$\n" +
|
||||
"\rdockerVersion\x18\f \x01(\tR\rdockerVersion\x1a9\n" +
|
||||
"\vLabelsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01*3\n" +
|
||||
"\x0fContainerAction\x12\t\n" +
|
||||
"\x05Start\x10\x00\x12\b\n" +
|
||||
"\x04Stop\x10\x01\x12\v\n" +
|
||||
"\aRestart\x10\x02B\x13Z\x11internal/agent/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_types_proto_rawDescOnce sync.Once
|
||||
|
||||
@@ -171,10 +171,12 @@ func (s *server) StreamStats(in *pb.StreamStatsRequest, out pb.AgentService_Stre
|
||||
case stat := <-stats:
|
||||
out.Send(&pb.StreamStatsResponse{
|
||||
Stat: &pb.ContainerStat{
|
||||
Id: stat.ID,
|
||||
CpuPercent: stat.CPUPercent,
|
||||
MemoryPercent: stat.MemoryPercent,
|
||||
MemoryUsage: stat.MemoryUsage,
|
||||
Id: stat.ID,
|
||||
CpuPercent: stat.CPUPercent,
|
||||
MemoryPercent: stat.MemoryPercent,
|
||||
MemoryUsage: stat.MemoryUsage,
|
||||
NetworkRxTotal: stat.NetworkRxTotal,
|
||||
NetworkTxTotal: stat.NetworkTxTotal,
|
||||
},
|
||||
})
|
||||
case <-out.Context().Done():
|
||||
|
||||
@@ -98,10 +98,12 @@ func FromProto(c *pb.Container) Container {
|
||||
|
||||
// ContainerStat represent stats instant for a container
|
||||
type ContainerStat struct {
|
||||
ID string `json:"id"`
|
||||
CPUPercent float64 `json:"cpu"`
|
||||
MemoryPercent float64 `json:"memory"`
|
||||
MemoryUsage float64 `json:"memoryUsage"`
|
||||
ID string `json:"id"`
|
||||
CPUPercent float64 `json:"cpu"`
|
||||
MemoryPercent float64 `json:"memory"`
|
||||
MemoryUsage float64 `json:"memoryUsage"`
|
||||
NetworkRxTotal uint64 `json:"networkRxTotal"`
|
||||
NetworkTxTotal uint64 `json:"networkTxTotal"`
|
||||
}
|
||||
|
||||
// ContainerEvent represents events that are triggered
|
||||
|
||||
@@ -198,6 +198,7 @@ func (d *DockerClient) ContainerStats(ctx context.Context, id string, stats chan
|
||||
mem, memLimit float64
|
||||
previousCPU uint64
|
||||
previousSystem uint64
|
||||
networkRx, networkTx uint64
|
||||
)
|
||||
daemonOSType := response.OSType
|
||||
|
||||
@@ -213,15 +214,23 @@ func (d *DockerClient) ContainerStats(ctx context.Context, id string, stats chan
|
||||
mem = float64(v.MemoryStats.PrivateWorkingSet)
|
||||
}
|
||||
|
||||
// Calculate total network bytes across all interfaces
|
||||
for _, netStats := range v.Networks {
|
||||
networkRx += netStats.RxBytes
|
||||
networkTx += netStats.TxBytes
|
||||
}
|
||||
|
||||
if cpuPercent > 0 || mem > 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case stats <- container.ContainerStat{
|
||||
ID: id,
|
||||
CPUPercent: cpuPercent,
|
||||
MemoryPercent: memPercent,
|
||||
MemoryUsage: mem,
|
||||
ID: id,
|
||||
CPUPercent: cpuPercent,
|
||||
MemoryPercent: memPercent,
|
||||
MemoryUsage: mem,
|
||||
NetworkRxTotal: networkRx,
|
||||
NetworkTxTotal: networkTx,
|
||||
}:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,8 @@ func (k *K8sClient) ContainerEvents(ctx context.Context, ch chan<- container.Con
|
||||
}
|
||||
|
||||
func (k *K8sClient) ContainerStats(ctx context.Context, id string, stats chan<- container.ContainerStat) error {
|
||||
panic("not implemented")
|
||||
// Stats collection is implemented in stats_collector.go using K8s metrics API
|
||||
panic("not implemented - use K8sStatsCollector instead")
|
||||
}
|
||||
|
||||
func (k *K8sClient) Ping(ctx context.Context) error {
|
||||
|
||||
@@ -105,9 +105,11 @@ func (sc *K8sStatsCollector) Start(parentCtx context.Context) bool {
|
||||
for _, pod := range metricList.Items {
|
||||
for _, c := range pod.Containers {
|
||||
stat := container.ContainerStat{
|
||||
ID: pod.Namespace + ":" + pod.Name + ":" + c.Name,
|
||||
CPUPercent: float64(c.Usage.Cpu().MilliValue()) / 1000 * 100,
|
||||
MemoryUsage: c.Usage.Memory().AsApproximateFloat64(),
|
||||
ID: pod.Namespace + ":" + pod.Name + ":" + c.Name,
|
||||
CPUPercent: float64(c.Usage.Cpu().MilliValue()) / 1000 * 100,
|
||||
MemoryUsage: c.Usage.Memory().AsApproximateFloat64(),
|
||||
NetworkRxTotal: 0, // K8s metrics API doesn't expose network stats by default
|
||||
NetworkTxTotal: 0, // Would require custom metrics or cAdvisor integration
|
||||
}
|
||||
log.Trace().Interface("stat", stat).Msg("k8s stats")
|
||||
sc.subscribers.Range(func(c context.Context, stats chan<- container.ContainerStat) bool {
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/amir20/dozzle/internal/container"
|
||||
container_support "github.com/amir20/dozzle/internal/support/container"
|
||||
"github.com/expr-lang/expr"
|
||||
"github.com/expr-lang/expr/vm"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Manager handles notification subscriptions and matching
|
||||
type Manager struct {
|
||||
subscriptions []*compiledSubscription
|
||||
mu sync.RWMutex
|
||||
activeStreams map[string]*activeStream // containerID -> stream info
|
||||
containerCache map[string]Container // containerID -> notification.Container
|
||||
containerService ContainerService
|
||||
dispatcher Dispatcher
|
||||
}
|
||||
|
||||
// activeStream tracks a single log stream and all subscriptions watching it
|
||||
type activeStream struct {
|
||||
container Container // notification.Container
|
||||
subscriptions []*compiledSubscription // All subscriptions watching this container
|
||||
cancel context.CancelFunc // Cancel function for the stream
|
||||
}
|
||||
|
||||
// compiledSubscription wraps a Subscription with compiled expr programs
|
||||
type compiledSubscription struct {
|
||||
subscription *Subscription
|
||||
containerProgram *vm.Program // Always non-nil
|
||||
logProgram *vm.Program // Always non-nil
|
||||
}
|
||||
|
||||
// ContainerService provides access to containers and log streaming
|
||||
type ContainerService interface {
|
||||
ListAllContainers(labels container.ContainerLabels) ([]container.Container, []error)
|
||||
FindContainer(host, id string, labels container.ContainerLabels) (*container_support.ContainerService, error)
|
||||
SubscribeContainersStarted(ctx context.Context, containers chan<- container.Container, filter container_support.ContainerFilter)
|
||||
}
|
||||
|
||||
// NewManager creates a new notification manager
|
||||
func NewManager(containerService ContainerService, dispatcher Dispatcher) *Manager {
|
||||
return &Manager{
|
||||
subscriptions: make([]*compiledSubscription, 0),
|
||||
activeStreams: make(map[string]*activeStream),
|
||||
containerCache: make(map[string]Container),
|
||||
containerService: containerService,
|
||||
dispatcher: dispatcher,
|
||||
}
|
||||
}
|
||||
|
||||
// LoadSubscriptions loads and compiles multiple subscriptions (replaces existing)
|
||||
func (m *Manager) LoadSubscriptions(subs []*Subscription) error {
|
||||
m.mu.Lock()
|
||||
m.subscriptions = make([]*compiledSubscription, 0, len(subs))
|
||||
m.mu.Unlock()
|
||||
|
||||
for _, sub := range subs {
|
||||
if err := m.AddSubscription(sub); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Int("count", len(subs)).Msg("loaded notification subscriptions")
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddSubscription adds a single subscription
|
||||
func (m *Manager) AddSubscription(sub *Subscription) error {
|
||||
cs, err := m.compileSubscription(sub)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
m.subscriptions = append(m.subscriptions, cs)
|
||||
m.mu.Unlock()
|
||||
|
||||
log.Info().Str("subscription", sub.Name).Msg("added notification subscription")
|
||||
return nil
|
||||
}
|
||||
|
||||
// compileSubscription compiles expr programs for a subscription
|
||||
func (m *Manager) compileSubscription(sub *Subscription) (*compiledSubscription, error) {
|
||||
if sub.ContainerFilter == "" {
|
||||
return nil, fmt.Errorf("container_filter is required for subscription %q", sub.Name)
|
||||
}
|
||||
if sub.LogFilter == "" {
|
||||
return nil, fmt.Errorf("log_filter is required for subscription %q", sub.Name)
|
||||
}
|
||||
|
||||
cs := &compiledSubscription{
|
||||
subscription: sub,
|
||||
}
|
||||
|
||||
// Compile container filter (required)
|
||||
containerProgram, err := expr.Compile(sub.ContainerFilter, expr.Env(Container{}))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("subscription", sub.Name).Msg("failed to compile container filter")
|
||||
return nil, fmt.Errorf("failed to compile container_filter for %q: %w", sub.Name, err)
|
||||
}
|
||||
cs.containerProgram = containerProgram
|
||||
|
||||
// Compile log filter (required)
|
||||
logProgram, err := expr.Compile(sub.LogFilter, expr.Env(Log{}))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("subscription", sub.Name).Msg("failed to compile log filter")
|
||||
return nil, fmt.Errorf("failed to compile log_filter for %q: %w", sub.Name, err)
|
||||
}
|
||||
cs.logProgram = logProgram
|
||||
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
// Start begins monitoring containers and streaming logs for matching subscriptions
|
||||
// Only starts if there are subscriptions configured
|
||||
func (m *Manager) Start(ctx context.Context) error {
|
||||
m.mu.RLock()
|
||||
hasSubscriptions := len(m.subscriptions) > 0
|
||||
m.mu.RUnlock()
|
||||
|
||||
if !hasSubscriptions {
|
||||
log.Debug().Msg("no subscriptions configured, skipping notification manager start")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subscribe to new containers that match our filters
|
||||
newContainers := make(chan container.Container)
|
||||
m.containerService.SubscribeContainersStarted(ctx, newContainers, func(c *container.Container) bool {
|
||||
matchingSubs := m.getMatchingSubscriptions(c)
|
||||
return len(matchingSubs) > 0
|
||||
})
|
||||
|
||||
// Handle new containers in background
|
||||
go func() {
|
||||
for c := range newContainers {
|
||||
m.startContainerStream(ctx, &c)
|
||||
}
|
||||
}()
|
||||
|
||||
// Get all existing containers and start streaming matching ones
|
||||
containers, errs := m.containerService.ListAllContainers(nil)
|
||||
for _, err := range errs {
|
||||
log.Warn().Err(err).Msg("error listing containers for notifications")
|
||||
}
|
||||
|
||||
// Check each container and start streaming only if it matches any subscription
|
||||
for _, c := range containers {
|
||||
if c.State == "running" {
|
||||
matchingSubs := m.getMatchingSubscriptions(&c)
|
||||
if len(matchingSubs) > 0 {
|
||||
m.startContainerStream(ctx, &c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// startContainerStream starts a single log stream for a container
|
||||
// All matching subscriptions will receive logs from this one stream
|
||||
func (m *Manager) startContainerStream(ctx context.Context, c *container.Container) {
|
||||
// Check if already streaming
|
||||
m.mu.RLock()
|
||||
_, exists := m.activeStreams[c.ID]
|
||||
m.mu.RUnlock()
|
||||
|
||||
if exists {
|
||||
return
|
||||
}
|
||||
|
||||
// Find which subscriptions match this container
|
||||
matchingSubs := m.getMatchingSubscriptions(c)
|
||||
if len(matchingSubs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("container", c.Name).
|
||||
Int("subscriptions", len(matchingSubs)).
|
||||
Msg("starting log stream for notification subscriptions")
|
||||
|
||||
// Convert to notification.Container and cache it
|
||||
notifContainer := NewContainer(c)
|
||||
m.mu.Lock()
|
||||
m.containerCache[c.ID] = notifContainer
|
||||
m.mu.Unlock()
|
||||
|
||||
streamCtx, cancel := context.WithCancel(ctx)
|
||||
|
||||
stream := &activeStream{
|
||||
container: notifContainer,
|
||||
subscriptions: matchingSubs,
|
||||
cancel: cancel,
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeStreams[c.ID] = stream
|
||||
m.mu.Unlock()
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
m.mu.Lock()
|
||||
delete(m.activeStreams, c.ID)
|
||||
m.mu.Unlock()
|
||||
}()
|
||||
|
||||
logs := make(chan *container.LogEvent)
|
||||
|
||||
// Stream logs in separate goroutine
|
||||
go func() {
|
||||
containerService, err := m.containerService.FindContainer(c.Host, c.ID, nil)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error finding container for notification streaming")
|
||||
return
|
||||
}
|
||||
|
||||
err = containerService.StreamLogs(streamCtx, time.Now(), container.STDOUT|container.STDERR, logs)
|
||||
if err != nil && err != context.Canceled {
|
||||
log.Error().Err(err).Msg("error streaming logs for notification")
|
||||
}
|
||||
close(logs)
|
||||
}()
|
||||
|
||||
// Process logs - check against all matching subscriptions
|
||||
for logEvent := range logs {
|
||||
for _, cs := range matchingSubs {
|
||||
m.processLogEvent(logEvent, c.ID, cs)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// getMatchingSubscriptions returns subscriptions that match a container
|
||||
func (m *Manager) getMatchingSubscriptions(c *container.Container) []*compiledSubscription {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
containerCtx := NewContainer(c)
|
||||
matching := make([]*compiledSubscription, 0)
|
||||
|
||||
for _, cs := range m.subscriptions {
|
||||
if m.matchesContainer(cs.containerProgram, containerCtx) {
|
||||
matching = append(matching, cs)
|
||||
}
|
||||
}
|
||||
|
||||
return matching
|
||||
}
|
||||
|
||||
// matchesContainer evaluates the container filter expression
|
||||
func (m *Manager) matchesContainer(program *vm.Program, containerCtx Container) bool {
|
||||
result, err := expr.Run(program, containerCtx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error evaluating container filter")
|
||||
return false
|
||||
}
|
||||
|
||||
match, ok := result.(bool)
|
||||
if !ok {
|
||||
log.Error().Msg("container filter did not return boolean")
|
||||
return false
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
// processLogEvent evaluates a log event against the subscription's log filter
|
||||
func (m *Manager) processLogEvent(logEvent *container.LogEvent, containerID string, cs *compiledSubscription) {
|
||||
// Lookup notification.Container from cache
|
||||
m.mu.RLock()
|
||||
notifContainer, ok := m.containerCache[containerID]
|
||||
m.mu.RUnlock()
|
||||
|
||||
if !ok {
|
||||
log.Warn().Str("container", containerID).Msg("container not in cache")
|
||||
return
|
||||
}
|
||||
|
||||
logCtx := NewLog(logEvent, notifContainer)
|
||||
|
||||
// Evaluate log filter (program is never nil)
|
||||
if m.matchesLog(cs.logProgram, logCtx) {
|
||||
m.triggerWebhook(cs.subscription, logCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// matchesLog evaluates the log filter expression
|
||||
func (m *Manager) matchesLog(program *vm.Program, logCtx Log) bool {
|
||||
result, err := expr.Run(program, logCtx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error evaluating log filter")
|
||||
return false
|
||||
}
|
||||
|
||||
match, ok := result.(bool)
|
||||
if !ok {
|
||||
log.Error().Msg("log filter did not return boolean")
|
||||
return false
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
// triggerWebhook sends the notification
|
||||
func (m *Manager) triggerWebhook(sub *Subscription, logCtx Log) {
|
||||
payload := WebhookPayload{
|
||||
SubscriptionName: sub.Name,
|
||||
Timestamp: time.Now(),
|
||||
Container: logCtx.Container,
|
||||
Log: LogEvent{
|
||||
Message: logCtx.Message,
|
||||
Level: logCtx.Level,
|
||||
Timestamp: logCtx.Timestamp,
|
||||
},
|
||||
}
|
||||
|
||||
m.dispatcher.Dispatch(sub, payload)
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config represents the YAML configuration structure
|
||||
type Config struct {
|
||||
Dispatcher DispatcherConfig `yaml:"dispatcher"`
|
||||
Subscriptions []*Subscription `yaml:"subscriptions"`
|
||||
}
|
||||
|
||||
// LoadFromFile loads config and returns a fully configured Manager
|
||||
func LoadFromFile(path string, containerService ContainerService) (*Manager, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil // No config file is fine, return nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read notifications config: %w", err)
|
||||
}
|
||||
|
||||
var config Config
|
||||
if err := yaml.Unmarshal(data, &config); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse notifications config: %w", err)
|
||||
}
|
||||
|
||||
// Validate dispatcher config
|
||||
if config.Dispatcher.Type == "" {
|
||||
config.Dispatcher.Type = "simple" // Default to simple
|
||||
}
|
||||
if config.Dispatcher.URL == "" {
|
||||
return nil, fmt.Errorf("dispatcher.url is required")
|
||||
}
|
||||
|
||||
// Validate subscriptions
|
||||
for _, sub := range config.Subscriptions {
|
||||
if sub.Name == "" {
|
||||
return nil, fmt.Errorf("subscription missing name")
|
||||
}
|
||||
if sub.ContainerFilter == "" {
|
||||
return nil, fmt.Errorf("subscription %q missing container_filter", sub.Name)
|
||||
}
|
||||
if sub.LogFilter == "" {
|
||||
return nil, fmt.Errorf("subscription %q missing log_filter", sub.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Create dispatcher based on type
|
||||
var dispatcher Dispatcher
|
||||
switch config.Dispatcher.Type {
|
||||
case "simple":
|
||||
dispatcher = NewWebhookDispatcher(&config.Dispatcher)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported dispatcher type: %s", config.Dispatcher.Type)
|
||||
}
|
||||
|
||||
// Create and configure manager
|
||||
manager := NewManager(containerService, dispatcher)
|
||||
if err := manager.LoadSubscriptions(config.Subscriptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return manager, nil
|
||||
}
|
||||
|
||||
// SaveToFile saves dispatcher config and subscriptions to a YAML file
|
||||
func SaveToFile(path string, dispatcher *DispatcherConfig, subs []*Subscription) error {
|
||||
config := Config{
|
||||
Dispatcher: *dispatcher,
|
||||
Subscriptions: subs,
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(&config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal notifications config: %w", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
return fmt.Errorf("failed to write notifications config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/amir20/dozzle/internal/container"
|
||||
)
|
||||
|
||||
// DispatcherConfig represents global dispatcher configuration
|
||||
type DispatcherConfig struct {
|
||||
// Type determines the dispatcher type (webhook, dozzle-service, etc.)
|
||||
Type string `yaml:"type"` // "webhook" is default
|
||||
|
||||
// URL is the endpoint for the dispatcher service
|
||||
URL string `yaml:"url"`
|
||||
|
||||
// APIKey for authenticating with the dispatcher service
|
||||
APIKey string `yaml:"api_key,omitempty"`
|
||||
|
||||
// Headers to include in all requests
|
||||
Headers map[string]string `yaml:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// Subscription represents a notification rule
|
||||
type Subscription struct {
|
||||
// Name is a human-readable name for this subscription
|
||||
Name string `yaml:"name"`
|
||||
|
||||
// ContainerFilter is an expr expression to match containers (REQUIRED)
|
||||
// Expression receives a Container object with: Name, Labels, Host, State
|
||||
// Example: Name == "nginx" || Labels["app"] == "web"
|
||||
ContainerFilter string `yaml:"container_filter"`
|
||||
|
||||
// LogFilter is an expr expression to match log events (REQUIRED)
|
||||
// Expression receives a Log object with: Message, Level, Timestamp, Container
|
||||
// Example: Level == "error" || Message contains "panic"
|
||||
LogFilter string `yaml:"log_filter"`
|
||||
}
|
||||
|
||||
// Container represents container information for expr evaluation (internal type)
|
||||
type Container struct {
|
||||
Name string `expr:"Name"`
|
||||
Labels map[string]string `expr:"Labels"`
|
||||
Host string `expr:"Host"`
|
||||
State string `expr:"State"`
|
||||
}
|
||||
|
||||
// Log represents log event information for expr evaluation
|
||||
type Log struct {
|
||||
Message any `expr:"Message"`
|
||||
Level string `expr:"Level"`
|
||||
Timestamp time.Time `expr:"Timestamp"`
|
||||
Container Container `expr:"Container"`
|
||||
}
|
||||
|
||||
// WebhookPayload is the structure sent to webhook endpoints
|
||||
type WebhookPayload struct {
|
||||
SubscriptionName string `json:"subscription_name"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Container Container `json:"container"`
|
||||
Log LogEvent `json:"log"`
|
||||
}
|
||||
|
||||
// LogEvent represents the log in the webhook payload
|
||||
type LogEvent struct {
|
||||
Message any `json:"message"`
|
||||
Level string `json:"level"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// NewContainer converts container.Container to notification.Container
|
||||
func NewContainer(c *container.Container) Container {
|
||||
return Container{
|
||||
Name: c.Name,
|
||||
Labels: c.Labels,
|
||||
Host: c.Host,
|
||||
State: c.State,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLog creates a Log from container.LogEvent and notification.Container
|
||||
func NewLog(logEvent *container.LogEvent, notifContainer Container) Log {
|
||||
timestamp := time.Unix(0, logEvent.Timestamp)
|
||||
|
||||
// Extract message - keep as any type for expr flexibility
|
||||
var message any = logEvent.Message
|
||||
|
||||
// For grouped logs, join fragments into single string for easier matching
|
||||
if fragments, ok := logEvent.Message.([]container.LogFragment); ok {
|
||||
parts := make([]string, len(fragments))
|
||||
for i, frag := range fragments {
|
||||
parts[i] = frag.Message
|
||||
}
|
||||
message = strings.Join(parts, "\n")
|
||||
}
|
||||
|
||||
return Log{
|
||||
Message: message,
|
||||
Level: logEvent.Level,
|
||||
Timestamp: timestamp,
|
||||
Container: notifContainer,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Dispatcher is the interface for sending notifications
|
||||
type Dispatcher interface {
|
||||
Dispatch(subscription *Subscription, payload WebhookPayload)
|
||||
}
|
||||
|
||||
// WebhookDispatcher handles async webhook delivery
|
||||
type WebhookDispatcher struct {
|
||||
client *http.Client
|
||||
config *DispatcherConfig
|
||||
}
|
||||
|
||||
// NewWebhookDispatcher creates a new webhook dispatcher
|
||||
func NewWebhookDispatcher(config *DispatcherConfig) *WebhookDispatcher {
|
||||
return &WebhookDispatcher{
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch sends a webhook payload asynchronously
|
||||
func (d *WebhookDispatcher) Dispatch(subscription *Subscription, payload WebhookPayload) {
|
||||
url := d.config.URL
|
||||
go func() {
|
||||
body, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("url", url).Msg("failed to marshal webhook payload")
|
||||
return
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(body))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("url", url).Msg("failed to create webhook request")
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", "Dozzle-Notifications/1.0")
|
||||
|
||||
// Add API key if configured
|
||||
if d.config.APIKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+d.config.APIKey)
|
||||
}
|
||||
|
||||
// Add custom headers
|
||||
for key, value := range d.config.Headers {
|
||||
req.Header.Set(key, value)
|
||||
}
|
||||
|
||||
resp, err := d.client.Do(req)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("url", url).Msg("failed to send webhook")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
log.Warn().
|
||||
Int("status", resp.StatusCode).
|
||||
Str("url", url).
|
||||
Str("subscription", payload.SubscriptionName).
|
||||
Msg("webhook returned error status")
|
||||
} else {
|
||||
log.Debug().
|
||||
Int("status", resp.StatusCode).
|
||||
Str("url", url).
|
||||
Str("subscription", payload.SubscriptionName).
|
||||
Msg("webhook delivered successfully")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -122,6 +122,12 @@ func (m *MultiHostService) SubscribeEventsAndStats(ctx context.Context, events c
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MultiHostService) SubscribeEvents(ctx context.Context, events chan<- container.ContainerEvent) {
|
||||
for _, client := range m.manager.List() {
|
||||
client.SubscribeEvents(ctx, events)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MultiHostService) SubscribeContainersStarted(ctx context.Context, containers chan<- container.Container, filter container_support.ContainerFilter) {
|
||||
newContainers := make(chan container.Container)
|
||||
for _, client := range m.manager.List() {
|
||||
|
||||
@@ -96,6 +96,10 @@ func (m *K8sClusterService) SubscribeEventsAndStats(ctx context.Context, events
|
||||
m.client.SubscribeStats(ctx, stats)
|
||||
}
|
||||
|
||||
func (m *K8sClusterService) SubscribeEvents(ctx context.Context, events chan<- container.ContainerEvent) {
|
||||
m.client.SubscribeEvents(ctx, events)
|
||||
}
|
||||
|
||||
func (m *K8sClusterService) SubscribeContainersStarted(ctx context.Context, containers chan<- container.Container, filter container_support.ContainerFilter) {
|
||||
newContainers := make(chan container.Container)
|
||||
m.client.SubscribeContainersStarted(ctx, newContainers)
|
||||
|
||||
+15
-13
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/amir20/dozzle/internal/auth"
|
||||
"github.com/amir20/dozzle/internal/container"
|
||||
"github.com/amir20/dozzle/internal/notification"
|
||||
container_support "github.com/amir20/dozzle/internal/support/container"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -34,19 +35,20 @@ const (
|
||||
|
||||
// Config is a struct for configuring the web service
|
||||
type Config struct {
|
||||
Base string
|
||||
Addr string
|
||||
Version string
|
||||
Hostname string
|
||||
NoAnalytics bool
|
||||
Dev bool
|
||||
Mode string
|
||||
Authorization Authorization
|
||||
EnableActions bool
|
||||
EnableShell bool
|
||||
DisableAvatars bool
|
||||
ReleaseCheckMode ReleaseCheckMode
|
||||
Labels container.ContainerLabels
|
||||
Base string
|
||||
Addr string
|
||||
Version string
|
||||
Hostname string
|
||||
NoAnalytics bool
|
||||
Dev bool
|
||||
Mode string
|
||||
Authorization Authorization
|
||||
EnableActions bool
|
||||
EnableShell bool
|
||||
DisableAvatars bool
|
||||
ReleaseCheckMode ReleaseCheckMode
|
||||
Labels container.ContainerLabels
|
||||
NotificationManager *notification.Manager
|
||||
}
|
||||
|
||||
type Authorization struct {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/amir20/dozzle/internal/auth"
|
||||
"github.com/amir20/dozzle/internal/docker"
|
||||
"github.com/amir20/dozzle/internal/k8s"
|
||||
"github.com/amir20/dozzle/internal/notification"
|
||||
"github.com/amir20/dozzle/internal/support/cli"
|
||||
docker_support "github.com/amir20/dozzle/internal/support/docker"
|
||||
k8s_support "github.com/amir20/dozzle/internal/support/k8s"
|
||||
@@ -108,15 +109,18 @@ func main() {
|
||||
log.Fatal().Str("mode", args.Mode).Msg("Invalid mode")
|
||||
}
|
||||
|
||||
srv := createServer(args, hostService)
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
notificationManager := initializeNotifications(ctx, hostService)
|
||||
|
||||
srv := createServer(args, hostService, notificationManager)
|
||||
go func() {
|
||||
log.Info().Msgf("Accepting connections on %s", args.Addr)
|
||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||
log.Fatal().Err(err).Msg("failed to listen")
|
||||
}
|
||||
}()
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
<-ctx.Done()
|
||||
stop()
|
||||
@@ -137,7 +141,56 @@ func fileExists(filename string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func createServer(args cli.Args, hostService web.HostService) *http.Server {
|
||||
func initializeSimpleAuth(authTTL string) web.Authorizer {
|
||||
log.Debug().Msg("Using simple authentication")
|
||||
|
||||
userFilePath := "./data/users.yml"
|
||||
if !fileExists(userFilePath) {
|
||||
userFilePath = "./data/users.yaml"
|
||||
if !fileExists(userFilePath) {
|
||||
log.Fatal().Msg("No users.yaml or users.yml file found.")
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug().Msgf("Reading %s file", filepath.Base(userFilePath))
|
||||
|
||||
db, err := auth.ReadUsersFromFile(userFilePath)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Could not read users file: %s", userFilePath)
|
||||
}
|
||||
|
||||
log.Debug().Int("users", len(db.Users)).Msg("Loaded users")
|
||||
ttl := time.Duration(0)
|
||||
if authTTL != "session" {
|
||||
ttl, err = time.ParseDuration(authTTL)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Could not parse auth ttl")
|
||||
}
|
||||
}
|
||||
return auth.NewSimpleAuth(db, ttl)
|
||||
}
|
||||
|
||||
func initializeNotifications(ctx context.Context, hostService web.HostService) *notification.Manager {
|
||||
notificationsPath := "./data/notifications.yml"
|
||||
manager, err := notification.LoadFromFile(notificationsPath, hostService)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to load notifications config")
|
||||
return nil
|
||||
}
|
||||
|
||||
if manager == nil {
|
||||
return nil // No config file
|
||||
}
|
||||
|
||||
if err := manager.Start(ctx); err != nil {
|
||||
log.Error().Err(err).Msg("failed to start notification manager")
|
||||
return nil
|
||||
}
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
func createServer(args cli.Args, hostService web.HostService, notificationManager *notification.Manager) *http.Server {
|
||||
_, dev := os.LookupEnv("DEV")
|
||||
|
||||
var releaseCheckMode web.ReleaseCheckMode = web.Automatic
|
||||
@@ -158,33 +211,8 @@ func createServer(args cli.Args, hostService web.HostService) *http.Server {
|
||||
provider = web.FORWARD_PROXY
|
||||
authorizer = auth.NewForwardProxyAuth(args.AuthHeaderUser, args.AuthHeaderEmail, args.AuthHeaderName, args.AuthHeaderFilter, args.AuthHeaderRoles)
|
||||
} else if args.AuthProvider == "simple" {
|
||||
log.Debug().Msg("Using simple authentication")
|
||||
provider = web.SIMPLE
|
||||
|
||||
userFilePath := "./data/users.yml"
|
||||
if !fileExists(userFilePath) {
|
||||
userFilePath = "./data/users.yaml"
|
||||
if !fileExists(userFilePath) {
|
||||
log.Fatal().Msg("No users.yaml or users.yml file found.")
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug().Msgf("Reading %s file", filepath.Base(userFilePath))
|
||||
|
||||
db, err := auth.ReadUsersFromFile(userFilePath)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Could not read users file: %s", userFilePath)
|
||||
}
|
||||
|
||||
log.Debug().Int("users", len(db.Users)).Msg("Loaded users")
|
||||
ttl := time.Duration(0)
|
||||
if args.AuthTTL != "session" {
|
||||
ttl, err = time.ParseDuration(args.AuthTTL)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Could not parse auth ttl")
|
||||
}
|
||||
}
|
||||
authorizer = auth.NewSimpleAuth(db, ttl)
|
||||
authorizer = initializeSimpleAuth(args.AuthTTL)
|
||||
}
|
||||
|
||||
authTTL := time.Duration(0)
|
||||
@@ -211,11 +239,12 @@ func createServer(args cli.Args, hostService web.HostService) *http.Server {
|
||||
TTL: authTTL,
|
||||
LogoutUrl: args.AuthLogoutUrl,
|
||||
},
|
||||
EnableActions: args.EnableActions,
|
||||
EnableShell: args.EnableShell,
|
||||
DisableAvatars: args.DisableAvatars,
|
||||
ReleaseCheckMode: releaseCheckMode,
|
||||
Labels: args.Filter,
|
||||
EnableActions: args.EnableActions,
|
||||
EnableShell: args.EnableShell,
|
||||
DisableAvatars: args.DisableAvatars,
|
||||
ReleaseCheckMode: releaseCheckMode,
|
||||
Labels: args.Filter,
|
||||
NotificationManager: notificationManager,
|
||||
}
|
||||
|
||||
assets, err := fs.Sub(content, "dist")
|
||||
|
||||
+5
-5
@@ -6,7 +6,7 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/amir20/dozzle/issues"
|
||||
},
|
||||
"packageManager": "pnpm@10.27.0",
|
||||
"packageManager": "pnpm@10.28.0",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -30,10 +30,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@duckdb/duckdb-wasm": "1.33.1-dev16.0",
|
||||
"@iconify-json/carbon": "^1.2.15",
|
||||
"@iconify-json/carbon": "^1.2.16",
|
||||
"@iconify-json/cil": "^1.2.3",
|
||||
"@iconify-json/ic": "^1.2.4",
|
||||
"@iconify-json/material-symbols": "^1.2.50",
|
||||
"@iconify-json/material-symbols": "^1.2.51",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@iconify-json/mdi-light": "^1.2.2",
|
||||
"@iconify-json/octicon": "^1.2.19",
|
||||
@@ -74,12 +74,12 @@
|
||||
"devDependencies": {
|
||||
"@apache-arrow/esnext-esm": "^21.1.0",
|
||||
"@iconify-json/ion": "^1.2.6",
|
||||
"@iconify-json/material-symbols-light": "^1.2.50",
|
||||
"@iconify-json/material-symbols-light": "^1.2.51",
|
||||
"@iconify-json/ri": "^1.2.7",
|
||||
"@pinia/testing": "^1.0.3",
|
||||
"@playwright/test": "^1.57.0",
|
||||
"@types/lodash.debounce": "^4.0.9",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/node": "^25.0.6",
|
||||
"@vitejs/plugin-vue": "6.0.3",
|
||||
"@vue/compiler-sfc": "^3.5.26",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
|
||||
Generated
+58
-58
@@ -15,8 +15,8 @@ importers:
|
||||
specifier: 1.33.1-dev16.0
|
||||
version: 1.33.1-dev16.0
|
||||
'@iconify-json/carbon':
|
||||
specifier: ^1.2.15
|
||||
version: 1.2.15
|
||||
specifier: ^1.2.16
|
||||
version: 1.2.16
|
||||
'@iconify-json/cil':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
@@ -24,8 +24,8 @@ importers:
|
||||
specifier: ^1.2.4
|
||||
version: 1.2.4
|
||||
'@iconify-json/material-symbols':
|
||||
specifier: ^1.2.50
|
||||
version: 1.2.50
|
||||
specifier: ^1.2.51
|
||||
version: 1.2.51
|
||||
'@iconify-json/mdi':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
@@ -46,7 +46,7 @@ importers:
|
||||
version: 0.5.19(tailwindcss@4.1.18)
|
||||
'@tailwindcss/vite':
|
||||
specifier: 4.1.18
|
||||
version: 4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
version: 4.1.18(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
'@vueuse/components':
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0(vue@3.5.26(typescript@5.9.3))
|
||||
@@ -109,22 +109,22 @@ importers:
|
||||
version: 30.0.0(@babel/parser@7.28.5)(vue@3.5.26(typescript@5.9.3))
|
||||
unplugin-vue-macros:
|
||||
specifier: ^2.14.5
|
||||
version: 2.14.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(esbuild@0.27.1)(rollup@4.53.3)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(vue@3.5.26(typescript@5.9.3))
|
||||
version: 2.14.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(esbuild@0.27.1)(rollup@4.53.3)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(vue@3.5.26(typescript@5.9.3))
|
||||
unplugin-vue-router:
|
||||
specifier: ^0.19.2
|
||||
version: 0.19.2(@vue/compiler-sfc@3.5.26)(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
vite:
|
||||
specifier: 7.3.1
|
||||
version: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
version: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite-plugin-vue-layouts:
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
version: 0.11.0(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
vite-svg-loader:
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(vue@3.5.26(typescript@5.9.3))
|
||||
vitepress:
|
||||
specifier: 1.6.4
|
||||
version: 1.6.4(@algolia/client-search@5.23.4)(@types/node@25.0.3)(fuse.js@7.1.0)(lightningcss@1.30.2)(postcss@8.5.6)(search-insights@2.17.3)(sortablejs@1.15.6)(terser@5.39.0)(typescript@5.9.3)
|
||||
version: 1.6.4(@algolia/client-search@5.23.4)(@types/node@25.0.6)(fuse.js@7.1.0)(lightningcss@1.30.2)(postcss@8.5.6)(search-insights@2.17.3)(sortablejs@1.15.6)(terser@5.39.0)(typescript@5.9.3)
|
||||
vue:
|
||||
specifier: ^3.5.26
|
||||
version: 3.5.26(typescript@5.9.3)
|
||||
@@ -142,8 +142,8 @@ importers:
|
||||
specifier: ^1.2.6
|
||||
version: 1.2.6
|
||||
'@iconify-json/material-symbols-light':
|
||||
specifier: ^1.2.50
|
||||
version: 1.2.50
|
||||
specifier: ^1.2.51
|
||||
version: 1.2.51
|
||||
'@iconify-json/ri':
|
||||
specifier: ^1.2.7
|
||||
version: 1.2.7
|
||||
@@ -157,11 +157,11 @@ importers:
|
||||
specifier: ^4.0.9
|
||||
version: 4.0.9
|
||||
'@types/node':
|
||||
specifier: ^25.0.3
|
||||
version: 25.0.3
|
||||
specifier: ^25.0.6
|
||||
version: 25.0.6
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: 6.0.3
|
||||
version: 6.0.3(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
|
||||
version: 6.0.3(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue/compiler-sfc':
|
||||
specifier: ^3.5.26
|
||||
version: 3.5.26
|
||||
@@ -197,13 +197,13 @@ importers:
|
||||
version: 2.13.1
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@25.0.3)(typescript@5.9.3)
|
||||
version: 10.9.2(@types/node@25.0.6)(typescript@5.9.3)
|
||||
typescript:
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^4.0.16
|
||||
version: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
version: 4.0.16(@types/node@25.0.6)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vue-component-type-helpers:
|
||||
specifier: 3.2.2
|
||||
version: 3.2.2
|
||||
@@ -942,8 +942,8 @@ packages:
|
||||
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@iconify-json/carbon@1.2.15':
|
||||
resolution: {integrity: sha512-9tW0nZY5QtKkMhuYzW09BM1345SyXNuA+gx2ub0j/fnfHOD5XVimMJ/D76H3tTez25NJbPYCLIQoFhvJc1HVBQ==}
|
||||
'@iconify-json/carbon@1.2.16':
|
||||
resolution: {integrity: sha512-R50UiC4NgPdnoSI3OzaZ/PzKYFVHAsAi3tENWgxvTxjYND3WHiUiG0qfJ0dPuaxwIW/l/2TnZwMPbbedd/+qIQ==}
|
||||
|
||||
'@iconify-json/cil@1.2.3':
|
||||
resolution: {integrity: sha512-byZH2wJeow6DO/+mYGwjlG5Gm2ZARJ1Rpr7Ryh4EcAFU0rH+AWoKbAUrBZMh1EU7jsVI4bKM95SLSsrWQ44sEw==}
|
||||
@@ -954,11 +954,11 @@ packages:
|
||||
'@iconify-json/ion@1.2.6':
|
||||
resolution: {integrity: sha512-JftEXKfjvJNn3SrGeSBrG/waRkjeTpLdMLNLwpAX4NgI14QgJoAeXEh2iZjNPqioAkeIgErX4Bi6mnFwpjk3BQ==}
|
||||
|
||||
'@iconify-json/material-symbols-light@1.2.50':
|
||||
resolution: {integrity: sha512-Ehvmar2TPoYxmKgB5szeIMlmvA/mIc7gzUoQ5/AWFG+N6d4T53uCHwxnXFf1nXPWlpf0+cv26AXMJC6W5mkdrQ==}
|
||||
'@iconify-json/material-symbols-light@1.2.51':
|
||||
resolution: {integrity: sha512-S0LR5LITSeybVfVK1Hnbjcv7/JdqVKu2ZFhpLiU2KYBkU6TbsFy3jQnKjxPNZxffxNTnxpf11hWFsvkYZGyS7Q==}
|
||||
|
||||
'@iconify-json/material-symbols@1.2.50':
|
||||
resolution: {integrity: sha512-71tjHR70h46LHtBFab3fAd2V/wPTO7JMV5lKnRn3IcF303LaFgAlO0BZeTJDcmCv9d0snRZmnoLZAJVD7/eisw==}
|
||||
'@iconify-json/material-symbols@1.2.51':
|
||||
resolution: {integrity: sha512-GkxlK8ocHi3NVVozaW62jm3qR9fNY3xX2penFtIRvoe1OtNhJ2KD4KRzv8x34pugMOAZYK8sALMcU30gDgCi1A==}
|
||||
|
||||
'@iconify-json/mdi-light@1.2.2':
|
||||
resolution: {integrity: sha512-86UV9uyNve8zRFWiPrOrrDp9GDzsZM7plYV/on4VjgLLqXlyriuy541eHZB7LIOzTUyIPVli7QiUpBbTtBhsFw==}
|
||||
@@ -1601,8 +1601,8 @@ packages:
|
||||
'@types/node@24.10.3':
|
||||
resolution: {integrity: sha512-gqkrWUsS8hcm0r44yn7/xZeV1ERva/nLgrLxFRUGb7aoNMIJfZJ3AC261zDQuOAKC7MiXai1WCpYc48jAHoShQ==}
|
||||
|
||||
'@types/node@25.0.3':
|
||||
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==}
|
||||
'@types/node@25.0.6':
|
||||
resolution: {integrity: sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q==}
|
||||
|
||||
'@types/unist@3.0.3':
|
||||
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
||||
@@ -4738,7 +4738,7 @@ snapshots:
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
|
||||
'@iconify-json/carbon@1.2.15':
|
||||
'@iconify-json/carbon@1.2.16':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
@@ -4754,11 +4754,11 @@ snapshots:
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@iconify-json/material-symbols-light@1.2.50':
|
||||
'@iconify-json/material-symbols-light@1.2.51':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
'@iconify-json/material-symbols@1.2.50':
|
||||
'@iconify-json/material-symbols@1.2.51':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
@@ -5244,12 +5244,12 @@ snapshots:
|
||||
postcss-selector-parser: 6.0.10
|
||||
tailwindcss: 4.1.18
|
||||
|
||||
'@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
'@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@tailwindcss/node': 4.1.18
|
||||
'@tailwindcss/oxide': 4.1.18
|
||||
tailwindcss: 4.1.18
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
|
||||
'@trysound/sax@0.2.0': {}
|
||||
|
||||
@@ -5314,7 +5314,7 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
'@types/node@25.0.3':
|
||||
'@types/node@25.0.6':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -5365,15 +5365,15 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.3.0': {}
|
||||
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.39.0))(vue@3.5.26(typescript@5.9.3))':
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@25.0.6)(lightningcss@1.30.2)(terser@5.39.0))(vue@3.5.26(typescript@5.9.3))':
|
||||
dependencies:
|
||||
vite: 5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.39.0)
|
||||
vite: 5.4.21(@types/node@25.0.6)(lightningcss@1.30.2)(terser@5.39.0)
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
'@vitejs/plugin-vue@6.0.3(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))':
|
||||
'@vitejs/plugin-vue@6.0.3(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.53
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
'@vitest/expect@4.0.16':
|
||||
@@ -5385,13 +5385,13 @@ snapshots:
|
||||
chai: 6.2.1
|
||||
tinyrainbow: 3.0.3
|
||||
|
||||
'@vitest/mocker@4.0.16(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
'@vitest/mocker@4.0.16(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@vitest/spy': 4.0.16
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.21
|
||||
optionalDependencies:
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
|
||||
'@vitest/pretty-format@4.0.16':
|
||||
dependencies:
|
||||
@@ -5547,12 +5547,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
'@vue-macros/devtools@0.4.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
'@vue-macros/devtools@0.4.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
sirv: 3.0.1
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
@@ -7593,14 +7593,14 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
ts-node@10.9.2(@types/node@25.0.3)(typescript@5.9.3):
|
||||
ts-node@10.9.2(@types/node@25.0.6)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.6
|
||||
acorn: 8.14.1
|
||||
acorn-walk: 8.3.4
|
||||
arg: 4.1.3
|
||||
@@ -7695,12 +7695,12 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@vueuse/core': 14.1.0(vue@3.5.26(typescript@5.9.3))
|
||||
|
||||
unplugin-combine@1.2.1(esbuild@0.27.1)(rollup@4.53.3)(unplugin@1.16.1)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)):
|
||||
unplugin-combine@1.2.1(esbuild@0.27.1)(rollup@4.53.3)(unplugin@1.16.1)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)):
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.1
|
||||
rollup: 4.53.3
|
||||
unplugin: 1.16.1
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
|
||||
unplugin-icons@22.5.0(@vue/compiler-sfc@3.5.26):
|
||||
dependencies:
|
||||
@@ -7748,7 +7748,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
unplugin-vue-macros@2.14.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(esbuild@0.27.1)(rollup@4.53.3)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(vue@3.5.26(typescript@5.9.3)):
|
||||
unplugin-vue-macros@2.14.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(esbuild@0.27.1)(rollup@4.53.3)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-tsc@3.2.2(typescript@5.9.3))(vue@3.5.26(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue-macros/better-define': 1.11.4(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/boolean-prop': 0.5.5(vue@3.5.26(typescript@5.9.3))
|
||||
@@ -7763,7 +7763,7 @@ snapshots:
|
||||
'@vue-macros/define-render': 1.6.6(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/define-slots': 1.2.6(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/define-stylex': 0.2.3(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/devtools': 0.4.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
'@vue-macros/devtools': 0.4.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
'@vue-macros/export-expose': 0.3.5(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/export-props': 0.6.5(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/export-render': 0.3.5(vue@3.5.26(typescript@5.9.3))
|
||||
@@ -7780,7 +7780,7 @@ snapshots:
|
||||
'@vue-macros/short-vmodel': 1.5.5(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue-macros/volar': 0.30.15(typescript@5.9.3)(vue-tsc@3.2.2(typescript@5.9.3))(vue@3.5.26(typescript@5.9.3))
|
||||
unplugin: 1.16.1
|
||||
unplugin-combine: 1.2.1(esbuild@0.27.1)(rollup@4.53.3)(unplugin@1.16.1)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
unplugin-combine: 1.2.1(esbuild@0.27.1)(rollup@4.53.3)(unplugin@1.16.1)(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
unplugin-vue-define-options: 1.5.5(vue@3.5.26(typescript@5.9.3))
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
@@ -7862,11 +7862,11 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-plugin-vue-layouts@0.11.0(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3)):
|
||||
vite-plugin-vue-layouts@0.11.0(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3)):
|
||||
dependencies:
|
||||
debug: 4.4.0
|
||||
fast-glob: 3.3.3
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
vue-router: 4.6.4(vue@3.5.26(typescript@5.9.3))
|
||||
transitivePeerDependencies:
|
||||
@@ -7877,18 +7877,18 @@ snapshots:
|
||||
svgo: 3.3.2
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
vite@5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.39.0):
|
||||
vite@5.4.21(@types/node@25.0.6)(lightningcss@1.30.2)(terser@5.39.0):
|
||||
dependencies:
|
||||
esbuild: 0.25.10
|
||||
postcss: 8.5.6
|
||||
rollup: 4.52.4
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.6
|
||||
fsevents: 2.3.3
|
||||
lightningcss: 1.30.2
|
||||
terser: 5.39.0
|
||||
|
||||
vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2):
|
||||
vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.1
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@@ -7897,7 +7897,7 @@ snapshots:
|
||||
rollup: 4.53.3
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.6
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.6.1
|
||||
lightningcss: 1.30.2
|
||||
@@ -7905,7 +7905,7 @@ snapshots:
|
||||
tsx: 4.19.2
|
||||
yaml: 2.8.2
|
||||
|
||||
vitepress@1.6.4(@algolia/client-search@5.23.4)(@types/node@25.0.3)(fuse.js@7.1.0)(lightningcss@1.30.2)(postcss@8.5.6)(search-insights@2.17.3)(sortablejs@1.15.6)(terser@5.39.0)(typescript@5.9.3):
|
||||
vitepress@1.6.4(@algolia/client-search@5.23.4)(@types/node@25.0.6)(fuse.js@7.1.0)(lightningcss@1.30.2)(postcss@8.5.6)(search-insights@2.17.3)(sortablejs@1.15.6)(terser@5.39.0)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@docsearch/css': 3.8.2
|
||||
'@docsearch/js': 3.8.2(@algolia/client-search@5.23.4)(search-insights@2.17.3)
|
||||
@@ -7914,7 +7914,7 @@ snapshots:
|
||||
'@shikijs/transformers': 2.5.0
|
||||
'@shikijs/types': 2.5.0
|
||||
'@types/markdown-it': 14.1.2
|
||||
'@vitejs/plugin-vue': 5.2.4(vite@5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.39.0))(vue@3.5.26(typescript@5.9.3))
|
||||
'@vitejs/plugin-vue': 5.2.4(vite@5.4.21(@types/node@25.0.6)(lightningcss@1.30.2)(terser@5.39.0))(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue/devtools-api': 7.7.2
|
||||
'@vue/shared': 3.5.18
|
||||
'@vueuse/core': 12.8.2(typescript@5.9.3)
|
||||
@@ -7923,7 +7923,7 @@ snapshots:
|
||||
mark.js: 8.11.1
|
||||
minisearch: 7.1.2
|
||||
shiki: 2.5.0
|
||||
vite: 5.4.21(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.39.0)
|
||||
vite: 5.4.21(@types/node@25.0.6)(lightningcss@1.30.2)(terser@5.39.0)
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
postcss: 8.5.6
|
||||
@@ -7954,10 +7954,10 @@ snapshots:
|
||||
- typescript
|
||||
- universal-cookie
|
||||
|
||||
vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2):
|
||||
vitest@4.0.16(@types/node@25.0.6)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.0.16
|
||||
'@vitest/mocker': 4.0.16(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
'@vitest/mocker': 4.0.16(vite@7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2))
|
||||
'@vitest/pretty-format': 4.0.16
|
||||
'@vitest/runner': 4.0.16
|
||||
'@vitest/snapshot': 4.0.16
|
||||
@@ -7974,10 +7974,10 @@ snapshots:
|
||||
tinyexec: 1.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tinyrainbow: 3.0.3
|
||||
vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@25.0.6)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.39.0)(tsx@4.19.2)(yaml@2.8.2)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.6
|
||||
jsdom: 27.4.0(postcss@8.5.6)
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
|
||||
@@ -34,6 +34,8 @@ message ContainerStat {
|
||||
double cpuPercent = 2;
|
||||
double memoryUsage = 3;
|
||||
double memoryPercent = 4;
|
||||
uint64 networkRxTotal = 5;
|
||||
uint64 networkTxTotal = 6;
|
||||
}
|
||||
|
||||
message LogFragment {
|
||||
|
||||
Reference in New Issue
Block a user