mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-23 05:56:17 +01:00
Compare commits
38 Commits
split-syst
...
v0.18.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af0c1d3af7 | ||
|
|
9ad3cd0ab9 | ||
|
|
00def272b0 | ||
|
|
383913505f | ||
|
|
ca8cb78c29 | ||
|
|
8821fb5dd0 | ||
|
|
3279a6ca53 | ||
|
|
6a1a98d73f | ||
|
|
1f067aad5b | ||
|
|
1388711105 | ||
|
|
618e5b4cc1 | ||
|
|
42c3ca5db5 | ||
|
|
534791776b | ||
|
|
0c6c53fc7d | ||
|
|
0dfd5ce07d | ||
|
|
2cd6d46f7c | ||
|
|
c333a9fadd | ||
|
|
ba3d1c66f0 | ||
|
|
7276e533ce | ||
|
|
8b84231042 | ||
|
|
77da744008 | ||
|
|
5da7a21119 | ||
|
|
78d742c712 | ||
|
|
1c97ea3e2c | ||
|
|
3d970defe9 | ||
|
|
6282794004 | ||
|
|
475c53a55d | ||
|
|
4547ff7b5d | ||
|
|
e7b4be3dc5 | ||
|
|
2bd85e04fc | ||
|
|
f6ab5f2af1 | ||
|
|
7d943633a3 | ||
|
|
7fff3c999a | ||
|
|
a9068a11a9 | ||
|
|
d3d102516c | ||
|
|
32131439f9 | ||
|
|
d17685c540 | ||
|
|
e59f8eee36 |
@@ -76,6 +76,18 @@ builds:
|
|||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: riscv64
|
goarch: riscv64
|
||||||
|
|
||||||
|
- id: beszel-agent-linux-amd64-glibc
|
||||||
|
binary: beszel-agent
|
||||||
|
main: internal/cmd/agent/agent.go
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
flags:
|
||||||
|
- -tags=glibc
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- id: beszel-agent
|
- id: beszel-agent
|
||||||
formats: [tar.gz]
|
formats: [tar.gz]
|
||||||
@@ -89,6 +101,15 @@ archives:
|
|||||||
- goos: windows
|
- goos: windows
|
||||||
formats: [zip]
|
formats: [zip]
|
||||||
|
|
||||||
|
- id: beszel-agent-linux-amd64-glibc
|
||||||
|
formats: [tar.gz]
|
||||||
|
ids:
|
||||||
|
- beszel-agent-linux-amd64-glibc
|
||||||
|
name_template: >-
|
||||||
|
{{ .Binary }}_
|
||||||
|
{{- .Os }}_
|
||||||
|
{{- .Arch }}_glibc
|
||||||
|
|
||||||
- id: beszel
|
- id: beszel
|
||||||
formats: [tar.gz]
|
formats: [tar.gz]
|
||||||
ids:
|
ids:
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ func NewAgent(dataDir ...string) (agent *Agent, err error) {
|
|||||||
slog.Warn("Invalid DISK_USAGE_CACHE", "err", err)
|
slog.Warn("Invalid DISK_USAGE_CACHE", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up slog with a log level determined by the LOG_LEVEL env var
|
// Set up slog with a log level determined by the LOG_LEVEL env var
|
||||||
if logLevelStr, exists := GetEnv("LOG_LEVEL"); exists {
|
if logLevelStr, exists := GetEnv("LOG_LEVEL"); exists {
|
||||||
switch strings.ToLower(logLevelStr) {
|
switch strings.ToLower(logLevelStr) {
|
||||||
@@ -103,7 +104,17 @@ func NewAgent(dataDir ...string) (agent *Agent, err error) {
|
|||||||
agent.dockerManager = newDockerManager()
|
agent.dockerManager = newDockerManager()
|
||||||
|
|
||||||
// initialize system info
|
// initialize system info
|
||||||
agent.refreshStaticInfo()
|
agent.refreshSystemDetails()
|
||||||
|
|
||||||
|
// SMART_INTERVAL env var to update smart data at this interval
|
||||||
|
if smartIntervalEnv, exists := GetEnv("SMART_INTERVAL"); exists {
|
||||||
|
if duration, err := time.ParseDuration(smartIntervalEnv); err == nil && duration > 0 {
|
||||||
|
agent.systemDetails.SmartInterval = duration
|
||||||
|
slog.Info("SMART_INTERVAL", "duration", duration)
|
||||||
|
} else {
|
||||||
|
slog.Warn("Invalid SMART_INTERVAL", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// initialize connection manager
|
// initialize connection manager
|
||||||
agent.connectionManager = newConnectionManager(agent)
|
agent.connectionManager = newConnectionManager(agent)
|
||||||
@@ -166,7 +177,7 @@ func (a *Agent) gatherStats(options common.DataRequestOptions) *system.CombinedD
|
|||||||
Info: a.systemInfo,
|
Info: a.systemInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include static info only when requested
|
// Include static system details only when requested
|
||||||
if options.IncludeDetails {
|
if options.IncludeDetails {
|
||||||
data.Details = &a.systemDetails
|
data.Details = &a.systemDetails
|
||||||
}
|
}
|
||||||
@@ -233,7 +244,8 @@ func (a *Agent) getFingerprint() string {
|
|||||||
|
|
||||||
// if no fingerprint is found, generate one
|
// if no fingerprint is found, generate one
|
||||||
fingerprint, err := host.HostID()
|
fingerprint, err := host.HostID()
|
||||||
if err != nil || fingerprint == "" {
|
// we ignore a commonly known "product_uuid" known not to be unique
|
||||||
|
if err != nil || fingerprint == "" || fingerprint == "03000200-0400-0500-0006-000700080009" {
|
||||||
fingerprint = a.systemDetails.Hostname + a.systemDetails.CpuModel
|
fingerprint = a.systemDetails.Hostname + a.systemDetails.CpuModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ import (
|
|||||||
|
|
||||||
"github.com/henrygd/beszel"
|
"github.com/henrygd/beszel"
|
||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
|
||||||
|
|
||||||
"github.com/fxamacker/cbor/v2"
|
"github.com/fxamacker/cbor/v2"
|
||||||
"github.com/lxzan/gws"
|
"github.com/lxzan/gws"
|
||||||
@@ -259,40 +256,16 @@ func (client *WebSocketClient) sendMessage(data any) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendResponse sends a response with optional request ID for the new protocol
|
// sendResponse sends a response with optional request ID.
|
||||||
|
// For ID-based requests, we must populate legacy typed fields for backward
|
||||||
|
// compatibility with older hubs (<= 0.17) that don't read the generic Data field.
|
||||||
func (client *WebSocketClient) sendResponse(data any, requestID *uint32) error {
|
func (client *WebSocketClient) sendResponse(data any, requestID *uint32) error {
|
||||||
if requestID != nil {
|
if requestID != nil {
|
||||||
// New format with ID - use typed fields
|
response := newAgentResponse(data, requestID)
|
||||||
response := common.AgentResponse{
|
|
||||||
Id: requestID,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the appropriate typed field based on data type
|
|
||||||
switch v := data.(type) {
|
|
||||||
case *system.CombinedData:
|
|
||||||
response.SystemData = v
|
|
||||||
case *common.FingerprintResponse:
|
|
||||||
response.Fingerprint = v
|
|
||||||
case string:
|
|
||||||
response.String = &v
|
|
||||||
case map[string]smart.SmartData:
|
|
||||||
response.SmartData = v
|
|
||||||
case systemd.ServiceDetails:
|
|
||||||
response.ServiceInfo = v
|
|
||||||
// case []byte:
|
|
||||||
// response.RawBytes = v
|
|
||||||
// case string:
|
|
||||||
// response.RawBytes = []byte(v)
|
|
||||||
default:
|
|
||||||
// For any other type, convert to error
|
|
||||||
response.Error = fmt.Sprintf("unsupported response type: %T", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.sendMessage(response)
|
return client.sendMessage(response)
|
||||||
} else {
|
|
||||||
// Legacy format - send data directly
|
|
||||||
return client.sendMessage(data)
|
|
||||||
}
|
}
|
||||||
|
// Legacy format - send data directly
|
||||||
|
return client.sendMessage(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getUserAgent returns one of two User-Agent strings based on current time.
|
// getUserAgent returns one of two User-Agent strings based on current time.
|
||||||
|
|||||||
@@ -694,7 +694,8 @@ func (dm *dockerManager) getLogs(ctx context.Context, containerID string) (strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
if err := decodeDockerLogStream(resp.Body, &builder); err != nil {
|
multiplexed := resp.Header.Get("Content-Type") == "application/vnd.docker.multiplexed-stream"
|
||||||
|
if err := decodeDockerLogStream(resp.Body, &builder, multiplexed); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,7 +707,11 @@ func (dm *dockerManager) getLogs(ctx context.Context, containerID string) (strin
|
|||||||
return logs, nil
|
return logs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeDockerLogStream(reader io.Reader, builder *strings.Builder) error {
|
func decodeDockerLogStream(reader io.Reader, builder *strings.Builder, multiplexed bool) error {
|
||||||
|
if !multiplexed {
|
||||||
|
_, err := io.Copy(builder, io.LimitReader(reader, maxTotalLogSize))
|
||||||
|
return err
|
||||||
|
}
|
||||||
const headerSize = 8
|
const headerSize = 8
|
||||||
var header [headerSize]byte
|
var header [headerSize]byte
|
||||||
totalBytesRead := 0
|
totalBytesRead := 0
|
||||||
@@ -757,7 +762,6 @@ func (dm *dockerManager) GetHostInfo() (info container.HostInfo, err error) {
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
|
||||||
slog.Error("Failed to decode Docker version response", "error", err)
|
|
||||||
return info, err
|
return info, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -950,6 +950,7 @@ func TestDecodeDockerLogStream(t *testing.T) {
|
|||||||
input []byte
|
input []byte
|
||||||
expected string
|
expected string
|
||||||
expectError bool
|
expectError bool
|
||||||
|
multiplexed bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple log entry",
|
name: "simple log entry",
|
||||||
@@ -960,6 +961,7 @@ func TestDecodeDockerLogStream(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: "Hello World",
|
expected: "Hello World",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
|
multiplexed: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple frames",
|
name: "multiple frames",
|
||||||
@@ -973,6 +975,7 @@ func TestDecodeDockerLogStream(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: "HelloWorld",
|
expected: "HelloWorld",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
|
multiplexed: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "zero length frame",
|
name: "zero length frame",
|
||||||
@@ -985,12 +988,20 @@ func TestDecodeDockerLogStream(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: "Hello",
|
expected: "Hello",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
|
multiplexed: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty input",
|
name: "empty input",
|
||||||
input: []byte{},
|
input: []byte{},
|
||||||
expected: "",
|
expected: "",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
|
multiplexed: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "raw stream (not multiplexed)",
|
||||||
|
input: []byte("raw log content"),
|
||||||
|
expected: "raw log content",
|
||||||
|
multiplexed: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,7 +1009,7 @@ func TestDecodeDockerLogStream(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
reader := bytes.NewReader(tt.input)
|
reader := bytes.NewReader(tt.input)
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
err := decodeDockerLogStream(reader, &builder)
|
err := decodeDockerLogStream(reader, &builder, tt.multiplexed)
|
||||||
|
|
||||||
if tt.expectError {
|
if tt.expectError {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
@@ -1022,7 +1033,7 @@ func TestDecodeDockerLogStreamMemoryProtection(t *testing.T) {
|
|||||||
|
|
||||||
reader := bytes.NewReader(input)
|
reader := bytes.NewReader(input)
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
err := decodeDockerLogStream(reader, &builder)
|
err := decodeDockerLogStream(reader, &builder, true)
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "log frame size")
|
assert.Contains(t, err.Error(), "log frame size")
|
||||||
@@ -1056,7 +1067,7 @@ func TestDecodeDockerLogStreamMemoryProtection(t *testing.T) {
|
|||||||
|
|
||||||
reader := bytes.NewReader(input)
|
reader := bytes.NewReader(input)
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
err := decodeDockerLogStream(reader, &builder)
|
err := decodeDockerLogStream(reader, &builder, true)
|
||||||
|
|
||||||
// Should complete without error (graceful truncation)
|
// Should complete without error (graceful truncation)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
47
agent/gpu.go
47
agent/gpu.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"maps"
|
"maps"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -14,8 +15,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
|
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -44,6 +43,7 @@ type GPUManager struct {
|
|||||||
rocmSmi bool
|
rocmSmi bool
|
||||||
tegrastats bool
|
tegrastats bool
|
||||||
intelGpuStats bool
|
intelGpuStats bool
|
||||||
|
nvml bool
|
||||||
GpuDataMap map[string]*system.GPUData
|
GpuDataMap map[string]*system.GPUData
|
||||||
// lastAvgData stores the last calculated averages for each GPU
|
// lastAvgData stores the last calculated averages for each GPU
|
||||||
// Used when a collection happens before new data arrives (Count == 0)
|
// Used when a collection happens before new data arrives (Count == 0)
|
||||||
@@ -136,10 +136,10 @@ func (gm *GPUManager) getJetsonParser() func(output []byte) bool {
|
|||||||
// use closure to avoid recompiling the regex
|
// use closure to avoid recompiling the regex
|
||||||
ramPattern := regexp.MustCompile(`RAM (\d+)/(\d+)MB`)
|
ramPattern := regexp.MustCompile(`RAM (\d+)/(\d+)MB`)
|
||||||
gr3dPattern := regexp.MustCompile(`GR3D_FREQ (\d+)%`)
|
gr3dPattern := regexp.MustCompile(`GR3D_FREQ (\d+)%`)
|
||||||
tempPattern := regexp.MustCompile(`tj@(\d+\.?\d*)C`)
|
tempPattern := regexp.MustCompile(`(?:tj|GPU)@(\d+\.?\d*)C`)
|
||||||
// Orin Nano / NX do not have GPU specific power monitor
|
// Orin Nano / NX do not have GPU specific power monitor
|
||||||
// TODO: Maybe use VDD_IN for Nano / NX and add a total system power chart
|
// TODO: Maybe use VDD_IN for Nano / NX and add a total system power chart
|
||||||
powerPattern := regexp.MustCompile(`(GPU_SOC|CPU_GPU_CV) (\d+)mW`)
|
powerPattern := regexp.MustCompile(`(GPU_SOC|CPU_GPU_CV)\s+(\d+)mW|VDD_SYS_GPU\s+(\d+)/\d+`)
|
||||||
|
|
||||||
// jetson devices have only one gpu so we'll just initialize here
|
// jetson devices have only one gpu so we'll just initialize here
|
||||||
gpuData := &system.GPUData{Name: "GPU"}
|
gpuData := &system.GPUData{Name: "GPU"}
|
||||||
@@ -168,7 +168,13 @@ func (gm *GPUManager) getJetsonParser() func(output []byte) bool {
|
|||||||
// Parse power usage
|
// Parse power usage
|
||||||
powerMatches := powerPattern.FindSubmatch(output)
|
powerMatches := powerPattern.FindSubmatch(output)
|
||||||
if powerMatches != nil {
|
if powerMatches != nil {
|
||||||
power, _ := strconv.ParseFloat(string(powerMatches[2]), 64)
|
// powerMatches[2] is the "(GPU_SOC|CPU_GPU_CV) <N>mW" capture
|
||||||
|
// powerMatches[3] is the "VDD_SYS_GPU <N>/<N>" capture
|
||||||
|
powerStr := string(powerMatches[2])
|
||||||
|
if powerStr == "" {
|
||||||
|
powerStr = string(powerMatches[3])
|
||||||
|
}
|
||||||
|
power, _ := strconv.ParseFloat(powerStr, 64)
|
||||||
gpuData.Power += power / milliwattsInAWatt
|
gpuData.Power += power / milliwattsInAWatt
|
||||||
}
|
}
|
||||||
gpuData.Count++
|
gpuData.Count++
|
||||||
@@ -231,10 +237,11 @@ func (gm *GPUManager) parseAmdData(output []byte) bool {
|
|||||||
totalMemory, _ := strconv.ParseFloat(v.MemoryTotal, 64)
|
totalMemory, _ := strconv.ParseFloat(v.MemoryTotal, 64)
|
||||||
usage, _ := strconv.ParseFloat(v.Usage, 64)
|
usage, _ := strconv.ParseFloat(v.Usage, 64)
|
||||||
|
|
||||||
if _, ok := gm.GpuDataMap[v.ID]; !ok {
|
id := v.ID
|
||||||
gm.GpuDataMap[v.ID] = &system.GPUData{Name: v.Name}
|
if _, ok := gm.GpuDataMap[id]; !ok {
|
||||||
|
gm.GpuDataMap[id] = &system.GPUData{Name: v.Name}
|
||||||
}
|
}
|
||||||
gpu := gm.GpuDataMap[v.ID]
|
gpu := gm.GpuDataMap[id]
|
||||||
gpu.Temperature, _ = strconv.ParseFloat(v.Temperature, 64)
|
gpu.Temperature, _ = strconv.ParseFloat(v.Temperature, 64)
|
||||||
gpu.MemoryUsed = bytesToMegabytes(memoryUsage)
|
gpu.MemoryUsed = bytesToMegabytes(memoryUsage)
|
||||||
gpu.MemoryTotal = bytesToMegabytes(totalMemory)
|
gpu.MemoryTotal = bytesToMegabytes(totalMemory)
|
||||||
@@ -297,8 +304,13 @@ func (gm *GPUManager) calculateGPUAverage(id string, gpu *system.GPUData, cacheK
|
|||||||
currentCount := uint32(gpu.Count)
|
currentCount := uint32(gpu.Count)
|
||||||
deltaCount := gm.calculateDeltaCount(currentCount, lastSnapshot)
|
deltaCount := gm.calculateDeltaCount(currentCount, lastSnapshot)
|
||||||
|
|
||||||
// If no new data arrived, use last known average
|
// If no new data arrived
|
||||||
if deltaCount == 0 {
|
if deltaCount == 0 {
|
||||||
|
// If GPU appears suspended (instantaneous values are 0), return zero values
|
||||||
|
// Otherwise return last known average for temporary collection gaps
|
||||||
|
if gpu.Temperature == 0 && gpu.MemoryUsed == 0 {
|
||||||
|
return system.GPUData{Name: gpu.Name}
|
||||||
|
}
|
||||||
return gm.lastAvgData[id] // zero value if not found
|
return gm.lastAvgData[id] // zero value if not found
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +408,7 @@ func (gm *GPUManager) detectGPUs() error {
|
|||||||
if _, err := exec.LookPath(intelGpuStatsCmd); err == nil {
|
if _, err := exec.LookPath(intelGpuStatsCmd); err == nil {
|
||||||
gm.intelGpuStats = true
|
gm.intelGpuStats = true
|
||||||
}
|
}
|
||||||
if gm.nvidiaSmi || gm.rocmSmi || gm.tegrastats || gm.intelGpuStats {
|
if gm.nvidiaSmi || gm.rocmSmi || gm.tegrastats || gm.intelGpuStats || gm.nvml {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no GPU found - install nvidia-smi, rocm-smi, tegrastats, or intel_gpu_top")
|
return fmt.Errorf("no GPU found - install nvidia-smi, rocm-smi, tegrastats, or intel_gpu_top")
|
||||||
@@ -467,7 +479,20 @@ func NewGPUManager() (*GPUManager, error) {
|
|||||||
gm.GpuDataMap = make(map[string]*system.GPUData)
|
gm.GpuDataMap = make(map[string]*system.GPUData)
|
||||||
|
|
||||||
if gm.nvidiaSmi {
|
if gm.nvidiaSmi {
|
||||||
gm.startCollector(nvidiaSmiCmd)
|
if nvml, _ := GetEnv("NVML"); nvml == "true" {
|
||||||
|
gm.nvml = true
|
||||||
|
gm.nvidiaSmi = false
|
||||||
|
collector := &nvmlCollector{gm: &gm}
|
||||||
|
if err := collector.init(); err == nil {
|
||||||
|
go collector.start()
|
||||||
|
} else {
|
||||||
|
slog.Warn("Failed to initialize NVML, falling back to nvidia-smi", "err", err)
|
||||||
|
gm.nvidiaSmi = true
|
||||||
|
gm.startCollector(nvidiaSmiCmd)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gm.startCollector(nvidiaSmiCmd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if gm.rocmSmi {
|
if gm.rocmSmi {
|
||||||
gm.startCollector(rocmSmiCmd)
|
gm.startCollector(rocmSmiCmd)
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ func (gm *GPUManager) updateIntelFromStats(sample *intelGpuStats) bool {
|
|||||||
defer gm.Unlock()
|
defer gm.Unlock()
|
||||||
|
|
||||||
// only one gpu for now - cmd doesn't provide all by default
|
// only one gpu for now - cmd doesn't provide all by default
|
||||||
gpuData, ok := gm.GpuDataMap["0"]
|
id := "i0" // prefix with i to avoid conflicts with nvidia card ids
|
||||||
|
gpuData, ok := gm.GpuDataMap[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
gpuData = &system.GPUData{Name: "GPU", Engines: make(map[string]float64)}
|
gpuData = &system.GPUData{Name: "GPU", Engines: make(map[string]float64)}
|
||||||
gm.GpuDataMap["0"] = gpuData
|
gm.GpuDataMap[id] = gpuData
|
||||||
}
|
}
|
||||||
|
|
||||||
gpuData.Power += sample.PowerGPU
|
gpuData.Power += sample.PowerGPU
|
||||||
|
|||||||
224
agent/gpu_nvml.go
Normal file
224
agent/gpu_nvml.go
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
//go:build amd64 && (windows || (linux && glibc))
|
||||||
|
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ebitengine/purego"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NVML constants and types
|
||||||
|
const (
|
||||||
|
nvmlSuccess int = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
type nvmlDevice uintptr
|
||||||
|
|
||||||
|
type nvmlReturn int
|
||||||
|
|
||||||
|
type nvmlMemoryV1 struct {
|
||||||
|
Total uint64
|
||||||
|
Free uint64
|
||||||
|
Used uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type nvmlMemoryV2 struct {
|
||||||
|
Version uint32
|
||||||
|
Total uint64
|
||||||
|
Reserved uint64
|
||||||
|
Free uint64
|
||||||
|
Used uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type nvmlUtilization struct {
|
||||||
|
Gpu uint32
|
||||||
|
Memory uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type nvmlPciInfo struct {
|
||||||
|
BusId [16]byte
|
||||||
|
Domain uint32
|
||||||
|
Bus uint32
|
||||||
|
Device uint32
|
||||||
|
PciDeviceId uint32
|
||||||
|
PciSubSystemId uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NVML function signatures
|
||||||
|
var (
|
||||||
|
nvmlInit func() nvmlReturn
|
||||||
|
nvmlShutdown func() nvmlReturn
|
||||||
|
nvmlDeviceGetCount func(count *uint32) nvmlReturn
|
||||||
|
nvmlDeviceGetHandleByIndex func(index uint32, device *nvmlDevice) nvmlReturn
|
||||||
|
nvmlDeviceGetName func(device nvmlDevice, name *byte, length uint32) nvmlReturn
|
||||||
|
nvmlDeviceGetMemoryInfo func(device nvmlDevice, memory uintptr) nvmlReturn
|
||||||
|
nvmlDeviceGetUtilizationRates func(device nvmlDevice, utilization *nvmlUtilization) nvmlReturn
|
||||||
|
nvmlDeviceGetTemperature func(device nvmlDevice, sensorType int, temp *uint32) nvmlReturn
|
||||||
|
nvmlDeviceGetPowerUsage func(device nvmlDevice, power *uint32) nvmlReturn
|
||||||
|
nvmlDeviceGetPciInfo func(device nvmlDevice, pci *nvmlPciInfo) nvmlReturn
|
||||||
|
nvmlErrorString func(result nvmlReturn) string
|
||||||
|
)
|
||||||
|
|
||||||
|
type nvmlCollector struct {
|
||||||
|
gm *GPUManager
|
||||||
|
lib uintptr
|
||||||
|
devices []nvmlDevice
|
||||||
|
bdfs []string
|
||||||
|
isV2 bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) init() error {
|
||||||
|
slog.Debug("NVML: Initializing")
|
||||||
|
libPath := getNVMLPath()
|
||||||
|
|
||||||
|
lib, err := openLibrary(libPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load %s: %w", libPath, err)
|
||||||
|
}
|
||||||
|
c.lib = lib
|
||||||
|
|
||||||
|
purego.RegisterLibFunc(&nvmlInit, lib, "nvmlInit")
|
||||||
|
purego.RegisterLibFunc(&nvmlShutdown, lib, "nvmlShutdown")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetCount, lib, "nvmlDeviceGetCount")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetHandleByIndex, lib, "nvmlDeviceGetHandleByIndex")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetName, lib, "nvmlDeviceGetName")
|
||||||
|
// Try to get v2 memory info, fallback to v1 if not available
|
||||||
|
if hasSymbol(lib, "nvmlDeviceGetMemoryInfo_v2") {
|
||||||
|
c.isV2 = true
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetMemoryInfo, lib, "nvmlDeviceGetMemoryInfo_v2")
|
||||||
|
} else {
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetMemoryInfo, lib, "nvmlDeviceGetMemoryInfo")
|
||||||
|
}
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetUtilizationRates, lib, "nvmlDeviceGetUtilizationRates")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetTemperature, lib, "nvmlDeviceGetTemperature")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetPowerUsage, lib, "nvmlDeviceGetPowerUsage")
|
||||||
|
purego.RegisterLibFunc(&nvmlDeviceGetPciInfo, lib, "nvmlDeviceGetPciInfo")
|
||||||
|
purego.RegisterLibFunc(&nvmlErrorString, lib, "nvmlErrorString")
|
||||||
|
|
||||||
|
if ret := nvmlInit(); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
return fmt.Errorf("nvmlInit failed: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
var count uint32
|
||||||
|
if ret := nvmlDeviceGetCount(&count); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
return fmt.Errorf("nvmlDeviceGetCount failed: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := uint32(0); i < count; i++ {
|
||||||
|
var device nvmlDevice
|
||||||
|
if ret := nvmlDeviceGetHandleByIndex(i, &device); ret == nvmlReturn(nvmlSuccess) {
|
||||||
|
c.devices = append(c.devices, device)
|
||||||
|
// Get BDF for power state check
|
||||||
|
var pci nvmlPciInfo
|
||||||
|
if ret := nvmlDeviceGetPciInfo(device, &pci); ret == nvmlReturn(nvmlSuccess) {
|
||||||
|
busID := string(pci.BusId[:])
|
||||||
|
if idx := strings.Index(busID, "\x00"); idx != -1 {
|
||||||
|
busID = busID[:idx]
|
||||||
|
}
|
||||||
|
c.bdfs = append(c.bdfs, strings.ToLower(busID))
|
||||||
|
} else {
|
||||||
|
c.bdfs = append(c.bdfs, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) start() {
|
||||||
|
defer nvmlShutdown()
|
||||||
|
ticker := time.Tick(3 * time.Second)
|
||||||
|
|
||||||
|
for range ticker {
|
||||||
|
c.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) collect() {
|
||||||
|
c.gm.Lock()
|
||||||
|
defer c.gm.Unlock()
|
||||||
|
|
||||||
|
for i, device := range c.devices {
|
||||||
|
id := fmt.Sprintf("%d", i)
|
||||||
|
bdf := c.bdfs[i]
|
||||||
|
|
||||||
|
// Update GPUDataMap
|
||||||
|
if _, ok := c.gm.GpuDataMap[id]; !ok {
|
||||||
|
var nameBuf [64]byte
|
||||||
|
if ret := nvmlDeviceGetName(device, &nameBuf[0], 64); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := string(nameBuf[:strings.Index(string(nameBuf[:]), "\x00")])
|
||||||
|
name = strings.TrimPrefix(name, "NVIDIA ")
|
||||||
|
c.gm.GpuDataMap[id] = &system.GPUData{Name: strings.TrimSuffix(name, " Laptop GPU")}
|
||||||
|
}
|
||||||
|
gpu := c.gm.GpuDataMap[id]
|
||||||
|
|
||||||
|
if bdf != "" && !c.isGPUActive(bdf) {
|
||||||
|
slog.Debug("NVML: GPU is suspended, skipping", "bdf", bdf)
|
||||||
|
gpu.Temperature = 0
|
||||||
|
gpu.MemoryUsed = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utilization
|
||||||
|
var utilization nvmlUtilization
|
||||||
|
if ret := nvmlDeviceGetUtilizationRates(device, &utilization); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
slog.Debug("NVML: Utilization failed (GPU likely suspended)", "bdf", bdf, "ret", ret)
|
||||||
|
gpu.Temperature = 0
|
||||||
|
gpu.MemoryUsed = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Debug("NVML: Collecting data for GPU", "bdf", bdf)
|
||||||
|
|
||||||
|
// Temperature
|
||||||
|
var temp uint32
|
||||||
|
nvmlDeviceGetTemperature(device, 0, &temp) // 0 is NVML_TEMPERATURE_GPU
|
||||||
|
|
||||||
|
// Memory: only poll if GPU is active to avoid leaving D3cold state (#1522)
|
||||||
|
if utilization.Gpu > 0 {
|
||||||
|
var usedMem, totalMem uint64
|
||||||
|
if c.isV2 {
|
||||||
|
var memory nvmlMemoryV2
|
||||||
|
memory.Version = 0x02000028 // (2 << 24) | 40 bytes
|
||||||
|
if ret := nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory))); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
slog.Debug("NVML: MemoryInfo_v2 failed", "bdf", bdf, "ret", ret)
|
||||||
|
} else {
|
||||||
|
usedMem = memory.Used
|
||||||
|
totalMem = memory.Total
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var memory nvmlMemoryV1
|
||||||
|
if ret := nvmlDeviceGetMemoryInfo(device, uintptr(unsafe.Pointer(&memory))); ret != nvmlReturn(nvmlSuccess) {
|
||||||
|
slog.Debug("NVML: MemoryInfo failed", "bdf", bdf, "ret", ret)
|
||||||
|
} else {
|
||||||
|
usedMem = memory.Used
|
||||||
|
totalMem = memory.Total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if totalMem > 0 {
|
||||||
|
gpu.MemoryUsed = float64(usedMem) / 1024 / 1024 / mebibytesInAMegabyte
|
||||||
|
gpu.MemoryTotal = float64(totalMem) / 1024 / 1024 / mebibytesInAMegabyte
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slog.Debug("NVML: Skipping memory info (utilization=0)", "bdf", bdf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power
|
||||||
|
var power uint32
|
||||||
|
nvmlDeviceGetPowerUsage(device, &power)
|
||||||
|
|
||||||
|
gpu.Temperature = float64(temp)
|
||||||
|
gpu.Usage += float64(utilization.Gpu)
|
||||||
|
gpu.Power += float64(power) / 1000.0
|
||||||
|
gpu.Count++
|
||||||
|
slog.Debug("NVML: Collected data", "gpu", gpu)
|
||||||
|
}
|
||||||
|
}
|
||||||
57
agent/gpu_nvml_linux.go
Normal file
57
agent/gpu_nvml_linux.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//go:build glibc && linux && amd64
|
||||||
|
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ebitengine/purego"
|
||||||
|
)
|
||||||
|
|
||||||
|
func openLibrary(name string) (uintptr, error) {
|
||||||
|
return purego.Dlopen(name, purego.RTLD_NOW|purego.RTLD_GLOBAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNVMLPath() string {
|
||||||
|
return "libnvidia-ml.so.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasSymbol(lib uintptr, symbol string) bool {
|
||||||
|
_, err := purego.Dlsym(lib, symbol)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) isGPUActive(bdf string) bool {
|
||||||
|
// runtime_status
|
||||||
|
statusPath := filepath.Join("/sys/bus/pci/devices", bdf, "power/runtime_status")
|
||||||
|
status, err := os.ReadFile(statusPath)
|
||||||
|
if err != nil {
|
||||||
|
slog.Debug("NVML: Can't read runtime_status", "bdf", bdf, "err", err)
|
||||||
|
return true // Assume active if we can't read status
|
||||||
|
}
|
||||||
|
statusStr := strings.TrimSpace(string(status))
|
||||||
|
if statusStr != "active" && statusStr != "resuming" {
|
||||||
|
slog.Debug("NVML: GPU not active", "bdf", bdf, "status", statusStr)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// power_state (D0 check)
|
||||||
|
// Find any drm card device power_state
|
||||||
|
pstatePathPattern := filepath.Join("/sys/bus/pci/devices", bdf, "drm/card*/device/power_state")
|
||||||
|
matches, _ := filepath.Glob(pstatePathPattern)
|
||||||
|
if len(matches) > 0 {
|
||||||
|
pstate, err := os.ReadFile(matches[0])
|
||||||
|
if err == nil {
|
||||||
|
pstateStr := strings.TrimSpace(string(pstate))
|
||||||
|
if pstateStr != "D0" {
|
||||||
|
slog.Debug("NVML: GPU not in D0 state", "bdf", bdf, "pstate", pstateStr)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
33
agent/gpu_nvml_unsupported.go
Normal file
33
agent/gpu_nvml_unsupported.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//go:build (!linux && !windows) || !amd64 || (linux && !glibc)
|
||||||
|
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type nvmlCollector struct {
|
||||||
|
gm *GPUManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) init() error {
|
||||||
|
return fmt.Errorf("nvml not supported on this platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) start() {}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) collect() {}
|
||||||
|
|
||||||
|
func openLibrary(name string) (uintptr, error) {
|
||||||
|
return 0, fmt.Errorf("nvml not supported on this platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNVMLPath() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasSymbol(lib uintptr, symbol string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) isGPUActive(bdf string) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
25
agent/gpu_nvml_windows.go
Normal file
25
agent/gpu_nvml_windows.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//go:build windows && amd64
|
||||||
|
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
func openLibrary(name string) (uintptr, error) {
|
||||||
|
handle, err := windows.LoadLibrary(name)
|
||||||
|
return uintptr(handle), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNVMLPath() string {
|
||||||
|
return "nvml.dll"
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasSymbol(lib uintptr, symbol string) bool {
|
||||||
|
_, err := windows.GetProcAddress(windows.Handle(lib), symbol)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nvmlCollector) isGPUActive(bdf string) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -307,6 +307,19 @@ func TestParseJetsonData(t *testing.T) {
|
|||||||
Count: 1,
|
Count: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "orin-style output with GPU@ temp and VDD_SYS_GPU power",
|
||||||
|
input: "RAM 3276/7859MB (lfb 5x4MB) SWAP 1626/12122MB (cached 181MB) CPU [44%@1421,49%@2031,67%@2034,17%@1420,25%@1419,8%@1420] EMC_FREQ 1%@1866 GR3D_FREQ 0%@114 APE 150 MTS fg 1% bg 1% PLL@42.5C MCPU@42.5C PMIC@50C Tboard@38C GPU@39.5C BCPU@42.5C thermal@41.3C Tdiode@39.25C VDD_SYS_GPU 182/182 VDD_SYS_SOC 730/730 VDD_4V0_WIFI 0/0 VDD_IN 5297/5297 VDD_SYS_CPU 1917/1917 VDD_SYS_DDR 1241/1241",
|
||||||
|
wantMetrics: &system.GPUData{
|
||||||
|
Name: "GPU",
|
||||||
|
MemoryUsed: 3276.0,
|
||||||
|
MemoryTotal: 7859.0,
|
||||||
|
Usage: 0.0,
|
||||||
|
Power: 0.182, // 182mW -> 0.182W
|
||||||
|
Temperature: 39.5,
|
||||||
|
Count: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -825,7 +838,7 @@ func TestInitializeSnapshots(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalculateGPUAverage(t *testing.T) {
|
func TestCalculateGPUAverage(t *testing.T) {
|
||||||
t.Run("returns zero value when deltaCount is zero", func(t *testing.T) {
|
t.Run("returns cached average when deltaCount is zero", func(t *testing.T) {
|
||||||
gm := &GPUManager{
|
gm := &GPUManager{
|
||||||
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
|
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
|
||||||
5000: {
|
5000: {
|
||||||
@@ -838,9 +851,10 @@ func TestCalculateGPUAverage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpu := &system.GPUData{
|
gpu := &system.GPUData{
|
||||||
Count: 10.0, // Same as snapshot, so delta = 0
|
Count: 10.0, // Same as snapshot, so delta = 0
|
||||||
Usage: 100.0,
|
Usage: 100.0,
|
||||||
Power: 200.0,
|
Power: 200.0,
|
||||||
|
Temperature: 50.0, // Non-zero to avoid "suspended" check
|
||||||
}
|
}
|
||||||
|
|
||||||
result := gm.calculateGPUAverage("0", gpu, 5000)
|
result := gm.calculateGPUAverage("0", gpu, 5000)
|
||||||
@@ -849,6 +863,31 @@ func TestCalculateGPUAverage(t *testing.T) {
|
|||||||
assert.Equal(t, 100.0, result.Power, "Should return cached average")
|
assert.Equal(t, 100.0, result.Power, "Should return cached average")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("returns zero value when GPU is suspended", func(t *testing.T) {
|
||||||
|
gm := &GPUManager{
|
||||||
|
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
|
||||||
|
5000: {
|
||||||
|
"0": {count: 10, usage: 100, power: 200},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lastAvgData: map[string]system.GPUData{
|
||||||
|
"0": {Usage: 50.0, Power: 100.0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu := &system.GPUData{
|
||||||
|
Name: "Test GPU",
|
||||||
|
Count: 10.0,
|
||||||
|
Temperature: 0,
|
||||||
|
MemoryUsed: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := gm.calculateGPUAverage("0", gpu, 5000)
|
||||||
|
|
||||||
|
assert.Equal(t, 0.0, result.Usage, "Should return zero usage")
|
||||||
|
assert.Equal(t, 0.0, result.Power, "Should return zero power")
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("calculates average for standard GPU", func(t *testing.T) {
|
t.Run("calculates average for standard GPU", func(t *testing.T) {
|
||||||
gm := &GPUManager{
|
gm := &GPUManager{
|
||||||
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
|
lastSnapshots: map[uint16]map[string]*gpuSnapshot{
|
||||||
@@ -1346,7 +1385,7 @@ func TestIntelUpdateFromStats(t *testing.T) {
|
|||||||
ok := gm.updateIntelFromStats(&sample1)
|
ok := gm.updateIntelFromStats(&sample1)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
gpu := gm.GpuDataMap["0"]
|
gpu := gm.GpuDataMap["i0"]
|
||||||
require.NotNil(t, gpu)
|
require.NotNil(t, gpu)
|
||||||
assert.Equal(t, "GPU", gpu.Name)
|
assert.Equal(t, "GPU", gpu.Name)
|
||||||
assert.EqualValues(t, 10.5, gpu.Power)
|
assert.EqualValues(t, 10.5, gpu.Power)
|
||||||
@@ -1368,7 +1407,7 @@ func TestIntelUpdateFromStats(t *testing.T) {
|
|||||||
ok = gm.updateIntelFromStats(&sample2)
|
ok = gm.updateIntelFromStats(&sample2)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
gpu = gm.GpuDataMap["0"]
|
gpu = gm.GpuDataMap["i0"]
|
||||||
require.NotNil(t, gpu)
|
require.NotNil(t, gpu)
|
||||||
assert.EqualValues(t, 10.5, gpu.Power)
|
assert.EqualValues(t, 10.5, gpu.Power)
|
||||||
assert.EqualValues(t, 30.0, gpu.Engines["Render/3D"]) // 20 + 10
|
assert.EqualValues(t, 30.0, gpu.Engines["Render/3D"]) // 20 + 10
|
||||||
@@ -1407,7 +1446,7 @@ echo "298 295 278 51 2.20 3.12 1675 942 5.75 1 2 9.50
|
|||||||
t.Fatalf("collectIntelStats error: %v", err)
|
t.Fatalf("collectIntelStats error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu := gm.GpuDataMap["0"]
|
gpu := gm.GpuDataMap["i0"]
|
||||||
require.NotNil(t, gpu)
|
require.NotNil(t, gpu)
|
||||||
// Power should be sum of samples 2-4 (first is skipped): 2.0 + 1.8 + 2.2 = 6.0
|
// Power should be sum of samples 2-4 (first is skipped): 2.0 + 1.8 + 2.2 = 6.0
|
||||||
assert.EqualValues(t, 6.0, gpu.Power)
|
assert.EqualValues(t, 6.0, gpu.Power)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
|
|
||||||
"golang.org/x/exp/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerContext provides context for request handlers
|
// HandlerContext provides context for request handlers
|
||||||
|
|||||||
31
agent/response.go
Normal file
31
agent/response.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
"github.com/henrygd/beszel/internal/common"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/systemd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newAgentResponse creates an AgentResponse using legacy typed fields.
|
||||||
|
// This maintains backward compatibility with <= 0.17 hubs that expect specific fields.
|
||||||
|
func newAgentResponse(data any, requestID *uint32) common.AgentResponse {
|
||||||
|
response := common.AgentResponse{Id: requestID}
|
||||||
|
switch v := data.(type) {
|
||||||
|
case *system.CombinedData:
|
||||||
|
response.SystemData = v
|
||||||
|
case *common.FingerprintResponse:
|
||||||
|
response.Fingerprint = v
|
||||||
|
case string:
|
||||||
|
response.String = &v
|
||||||
|
case map[string]smart.SmartData:
|
||||||
|
response.SmartData = v
|
||||||
|
case systemd.ServiceDetails:
|
||||||
|
response.ServiceInfo = v
|
||||||
|
default:
|
||||||
|
// For unknown types, use the generic Data field
|
||||||
|
response.Data, _ = cbor.Marshal(data)
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
@@ -13,9 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/henrygd/beszel"
|
"github.com/henrygd/beszel"
|
||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
|
||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
"github.com/fxamacker/cbor/v2"
|
"github.com/fxamacker/cbor/v2"
|
||||||
@@ -165,20 +163,9 @@ func (a *Agent) handleSSHRequest(w io.Writer, req *common.HubRequest[cbor.RawMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// responder that writes AgentResponse to stdout
|
// responder that writes AgentResponse to stdout
|
||||||
|
// Uses legacy typed fields for backward compatibility with <= 0.17
|
||||||
sshResponder := func(data any, requestID *uint32) error {
|
sshResponder := func(data any, requestID *uint32) error {
|
||||||
response := common.AgentResponse{Id: requestID}
|
response := newAgentResponse(data, requestID)
|
||||||
switch v := data.(type) {
|
|
||||||
case *system.CombinedData:
|
|
||||||
response.SystemData = v
|
|
||||||
case string:
|
|
||||||
response.String = &v
|
|
||||||
case map[string]smart.SmartData:
|
|
||||||
response.SmartData = v
|
|
||||||
case systemd.ServiceDetails:
|
|
||||||
response.ServiceInfo = v
|
|
||||||
default:
|
|
||||||
response.Error = fmt.Sprintf("unsupported response type: %T", data)
|
|
||||||
}
|
|
||||||
return cbor.NewEncoder(w).Encode(response)
|
return cbor.NewEncoder(w).Encode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -550,6 +550,9 @@ func createTestCombinedData() *system.CombinedData {
|
|||||||
DiskUsed: 549755813888, // 512GB
|
DiskUsed: 549755813888, // 512GB
|
||||||
DiskPct: 50.0,
|
DiskPct: 50.0,
|
||||||
},
|
},
|
||||||
|
Details: &system.Details{
|
||||||
|
Hostname: "test-host",
|
||||||
|
},
|
||||||
Info: system.Info{
|
Info: system.Info{
|
||||||
Uptime: 3600,
|
Uptime: 3600,
|
||||||
AgentVersion: "0.12.0",
|
AgentVersion: "0.12.0",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
|
|
||||||
"golang.org/x/exp/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SmartManager manages data collection for SMART devices
|
// SmartManager manages data collection for SMART devices
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type prevDisk struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sets initial / non-changing values about the host system
|
// Sets initial / non-changing values about the host system
|
||||||
func (a *Agent) refreshStaticInfo() {
|
func (a *Agent) refreshSystemDetails() {
|
||||||
a.systemInfo.AgentVersion = beszel.Version
|
a.systemInfo.AgentVersion = beszel.Version
|
||||||
|
|
||||||
// get host info from Docker if available
|
// get host info from Docker if available
|
||||||
@@ -246,7 +246,6 @@ func (a *Agent) getSystemStats(cacheTimeMs uint16) system.Stats {
|
|||||||
a.systemInfo.Uptime, _ = host.Uptime()
|
a.systemInfo.Uptime, _ = host.Uptime()
|
||||||
a.systemInfo.BandwidthBytes = systemStats.Bandwidth[0] + systemStats.Bandwidth[1]
|
a.systemInfo.BandwidthBytes = systemStats.Bandwidth[0] + systemStats.Bandwidth[1]
|
||||||
a.systemInfo.Threads = a.systemDetails.Threads
|
a.systemInfo.Threads = a.systemDetails.Threads
|
||||||
slog.Debug("sysinfo", "data", a.systemInfo)
|
|
||||||
|
|
||||||
return systemStats
|
return systemStats
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"maps"
|
"maps"
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -28,11 +29,36 @@ type systemdManager struct {
|
|||||||
patterns []string
|
patterns []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isSystemdAvailable checks if systemd is used on the system to avoid unnecessary connection attempts (#1548)
|
||||||
|
func isSystemdAvailable() bool {
|
||||||
|
paths := []string{
|
||||||
|
"/run/systemd/system",
|
||||||
|
"/run/dbus/system_bus_socket",
|
||||||
|
"/var/run/dbus/system_bus_socket",
|
||||||
|
}
|
||||||
|
for _, path := range paths {
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if data, err := os.ReadFile("/proc/1/comm"); err == nil {
|
||||||
|
return strings.TrimSpace(string(data)) == "systemd"
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// newSystemdManager creates a new systemdManager.
|
// newSystemdManager creates a new systemdManager.
|
||||||
func newSystemdManager() (*systemdManager, error) {
|
func newSystemdManager() (*systemdManager, error) {
|
||||||
if skipSystemd, _ := GetEnv("SKIP_SYSTEMD"); skipSystemd == "true" {
|
if skipSystemd, _ := GetEnv("SKIP_SYSTEMD"); skipSystemd == "true" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if systemd is available on the system before attempting connection
|
||||||
|
if !isSystemdAvailable() {
|
||||||
|
slog.Debug("Systemd not available")
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
conn, err := dbus.NewSystemConnectionContext(context.Background())
|
conn, err := dbus.NewSystemConnectionContext(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Debug("Error connecting to systemd", "err", err, "ref", "https://beszel.dev/guide/systemd")
|
slog.Debug("Error connecting to systemd", "err", err, "ref", "https://beszel.dev/guide/systemd")
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ func TestSystemdManagerGetServiceStats(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test with refresh = true
|
// Test with refresh = true
|
||||||
result := manager.getServiceStats(true)
|
result := manager.getServiceStats("any-service", true)
|
||||||
assert.Nil(t, result)
|
assert.Nil(t, result)
|
||||||
|
|
||||||
// Test with refresh = false
|
// Test with refresh = false
|
||||||
result = manager.getServiceStats(false)
|
result = manager.getServiceStats("any-service", false)
|
||||||
assert.Nil(t, result)
|
assert.Nil(t, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package agent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -48,6 +49,35 @@ func TestUnescapeServiceNameInvalid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsSystemdAvailable(t *testing.T) {
|
||||||
|
// Note: This test's result will vary based on the actual system running the tests
|
||||||
|
// On systems with systemd, it should return true
|
||||||
|
// On systems without systemd, it should return false
|
||||||
|
result := isSystemdAvailable()
|
||||||
|
|
||||||
|
// Check if either the /run/systemd/system directory exists or PID 1 is systemd
|
||||||
|
runSystemdExists := false
|
||||||
|
if _, err := os.Stat("/run/systemd/system"); err == nil {
|
||||||
|
runSystemdExists = true
|
||||||
|
}
|
||||||
|
|
||||||
|
pid1IsSystemd := false
|
||||||
|
if data, err := os.ReadFile("/proc/1/comm"); err == nil {
|
||||||
|
pid1IsSystemd = strings.TrimSpace(string(data)) == "systemd"
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := runSystemdExists || pid1IsSystemd
|
||||||
|
|
||||||
|
assert.Equal(t, expected, result, "isSystemdAvailable should correctly detect systemd presence")
|
||||||
|
|
||||||
|
// Log the result for informational purposes
|
||||||
|
if result {
|
||||||
|
t.Log("Systemd is available on this system")
|
||||||
|
} else {
|
||||||
|
t.Log("Systemd is not available on this system")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetServicePatterns(t *testing.T) {
|
func TestGetServicePatterns(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import "github.com/blang/semver"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the current version of the application.
|
// Version is the current version of the application.
|
||||||
Version = "0.18.0-beta.1"
|
Version = "0.18.2"
|
||||||
// AppName is the name of the application.
|
// AppName is the name of the application.
|
||||||
AppName = "beszel"
|
AppName = "beszel"
|
||||||
)
|
)
|
||||||
|
|||||||
36
go.mod
36
go.mod
@@ -6,20 +6,22 @@ require (
|
|||||||
github.com/blang/semver v3.5.1+incompatible
|
github.com/blang/semver v3.5.1+incompatible
|
||||||
github.com/coreos/go-systemd/v22 v22.6.0
|
github.com/coreos/go-systemd/v22 v22.6.0
|
||||||
github.com/distatus/battery v0.11.0
|
github.com/distatus/battery v0.11.0
|
||||||
|
github.com/ebitengine/purego v0.9.1
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0
|
github.com/fxamacker/cbor/v2 v2.9.0
|
||||||
github.com/gliderlabs/ssh v0.3.8
|
github.com/gliderlabs/ssh v0.3.8
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/lxzan/gws v1.8.9
|
github.com/lxzan/gws v1.8.9
|
||||||
github.com/nicholas-fedor/shoutrrr v0.12.1
|
github.com/nicholas-fedor/shoutrrr v0.13.1
|
||||||
github.com/pocketbase/dbx v1.11.0
|
github.com/pocketbase/dbx v1.11.0
|
||||||
github.com/pocketbase/pocketbase v0.34.0
|
github.com/pocketbase/pocketbase v0.35.1
|
||||||
github.com/shirou/gopsutil/v4 v4.25.10
|
github.com/shirou/gopsutil/v4 v4.25.12
|
||||||
github.com/spf13/cast v1.10.0
|
github.com/spf13/cast v1.10.0
|
||||||
github.com/spf13/cobra v1.10.1
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/spf13/pflag v1.0.10
|
github.com/spf13/pflag v1.0.10
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
golang.org/x/crypto v0.45.0
|
golang.org/x/crypto v0.46.0
|
||||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39
|
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93
|
||||||
|
golang.org/x/sys v0.40.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,17 +33,16 @@ require (
|
|||||||
github.com/dolthub/maphash v0.1.0 // indirect
|
github.com/dolthub/maphash v0.1.0 // indirect
|
||||||
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
|
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/ebitengine/purego v0.9.1 // indirect
|
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||||
github.com/ganigeorgiev/fexpr v0.5.0 // indirect
|
github.com/ganigeorgiev/fexpr v0.5.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.9.1 // indirect
|
github.com/go-sql-driver/mysql v1.9.1 // indirect
|
||||||
github.com/godbus/dbus/v5 v5.2.0 // indirect
|
github.com/godbus/dbus/v5 v5.2.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/klauspost/compress v1.18.1 // indirect
|
github.com/klauspost/compress v1.18.2 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
|
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
@@ -53,16 +54,15 @@ require (
|
|||||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
golang.org/x/image v0.33.0 // indirect
|
golang.org/x/image v0.34.0 // indirect
|
||||||
golang.org/x/net v0.47.0 // indirect
|
golang.org/x/net v0.48.0 // indirect
|
||||||
golang.org/x/oauth2 v0.33.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sync v0.18.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.38.0 // indirect
|
golang.org/x/term v0.39.0 // indirect
|
||||||
golang.org/x/term v0.37.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
|
||||||
howett.net/plist v1.0.1 // indirect
|
howett.net/plist v1.0.1 // indirect
|
||||||
modernc.org/libc v1.66.10 // indirect
|
modernc.org/libc v1.66.10 // indirect
|
||||||
modernc.org/mathutil v1.7.1 // indirect
|
modernc.org/mathutil v1.7.1 // indirect
|
||||||
modernc.org/memory v1.11.0 // indirect
|
modernc.org/memory v1.11.0 // indirect
|
||||||
modernc.org/sqlite v1.40.1 // indirect
|
modernc.org/sqlite v1.43.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
88
go.sum
88
go.sum
@@ -33,8 +33,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
|||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
|
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
|
github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
|
||||||
github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
|
github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
|
||||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||||
@@ -51,8 +51,8 @@ github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtS
|
|||||||
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8=
|
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
||||||
github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
|
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -69,8 +69,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
|
|||||||
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
|
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
|
||||||
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
|
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
|
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
||||||
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
|
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -85,19 +85,19 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
|||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||||
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||||
github.com/nicholas-fedor/shoutrrr v0.12.1 h1:8NjY+I3K7cGHy89ncnaPGUA0ex44XbYK3SAFJX9YMI8=
|
github.com/nicholas-fedor/shoutrrr v0.13.1 h1:llEoHNbnMM4GfQ9+2Ns3n6ssvNfi3NPWluM0AQiicoY=
|
||||||
github.com/nicholas-fedor/shoutrrr v0.12.1/go.mod h1:64qWuPpvTUv9ZppEoR6OdroiFmgf9w11YSaR0h9KZGg=
|
github.com/nicholas-fedor/shoutrrr v0.13.1/go.mod h1:kU4cFJpEAtTzl3iV0l+XUXmM90OlC5T01b7roM4/pYM=
|
||||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
github.com/onsi/ginkgo/v2 v2.27.3 h1:ICsZJ8JoYafeXFFlFAG75a7CxMsJHwgKwtO+82SE9L8=
|
||||||
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
github.com/onsi/ginkgo/v2 v2.27.3/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
||||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM=
|
||||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
|
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
|
||||||
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
|
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
|
||||||
github.com/pocketbase/pocketbase v0.34.0 h1:5W80PrGvkRYIMAIK90F7w031/hXgZVz1KSuCJqSpgJo=
|
github.com/pocketbase/pocketbase v0.35.1 h1:Cd5ivUThTw29myY/tYa2cb0elkScBMseG6fExZsIQB8=
|
||||||
github.com/pocketbase/pocketbase v0.34.0/go.mod h1:K/9z/Zb9PR9yW2Qyoc73jHV/EKT8cMTk9bQWyrzYlvI=
|
github.com/pocketbase/pocketbase v0.35.1/go.mod h1:yQnh1o1Aq6wVuqcmZbRbDmIhc31AME/F5pnPR0Bdtmg=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
@@ -105,12 +105,12 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
|
|||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
|
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
|
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
|
||||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
@@ -129,38 +129,38 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ
|
|||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY=
|
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
|
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
|
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
|
||||||
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
|
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
|
||||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
||||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||||
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
||||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
@@ -187,8 +187,8 @@ modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
|||||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||||
modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A=
|
modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A=
|
||||||
modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I=
|
modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I=
|
||||||
modernc.org/libc v1.67.1 h1:bFaqOaa5/zbWYJo8aW0tXPX21hXsngG2M7mckCnFSVk=
|
modernc.org/libc v1.67.4 h1:zZGmCMUVPORtKv95c2ReQN5VDjvkoRm9GWPTEPuvlWg=
|
||||||
modernc.org/libc v1.67.1/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
|
modernc.org/libc v1.67.4/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
|
||||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||||
@@ -197,8 +197,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
|||||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||||
modernc.org/sqlite v1.40.1 h1:VfuXcxcUWWKRBuP8+BR9L7VnmusMgBNNnBYGEe9w/iY=
|
modernc.org/sqlite v1.43.0 h1:8YqiFx3G1VhHTXO2Q00bl1Wz9KhS9Q5okwfp9Y97VnA=
|
||||||
modernc.org/sqlite v1.40.1/go.mod h1:9fjQZ0mB1LLP0GYrp39oOJXx/I2sxEnZtzCmEQIKvGE=
|
modernc.org/sqlite v1.43.0/go.mod h1:+VkC6v3pLOAE0A0uVucQEcbVW0I5nHCeDaBf+DpsQT8=
|
||||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fxamacker/cbor/v2"
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
"github.com/henrygd/beszel/internal/entities/systemd"
|
||||||
@@ -34,14 +35,14 @@ type HubRequest[T any] struct {
|
|||||||
// AgentResponse defines the structure for responses sent from agent to hub.
|
// AgentResponse defines the structure for responses sent from agent to hub.
|
||||||
type AgentResponse struct {
|
type AgentResponse struct {
|
||||||
Id *uint32 `cbor:"0,keyasint,omitempty"`
|
Id *uint32 `cbor:"0,keyasint,omitempty"`
|
||||||
SystemData *system.CombinedData `cbor:"1,keyasint,omitempty,omitzero"`
|
SystemData *system.CombinedData `cbor:"1,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
|
||||||
Fingerprint *FingerprintResponse `cbor:"2,keyasint,omitempty,omitzero"`
|
Fingerprint *FingerprintResponse `cbor:"2,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
|
||||||
Error string `cbor:"3,keyasint,omitempty,omitzero"`
|
Error string `cbor:"3,keyasint,omitempty,omitzero"`
|
||||||
String *string `cbor:"4,keyasint,omitempty,omitzero"`
|
String *string `cbor:"4,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
|
||||||
SmartData map[string]smart.SmartData `cbor:"5,keyasint,omitempty,omitzero"`
|
SmartData map[string]smart.SmartData `cbor:"5,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
|
||||||
ServiceInfo systemd.ServiceDetails `cbor:"6,keyasint,omitempty,omitzero"`
|
ServiceInfo systemd.ServiceDetails `cbor:"6,keyasint,omitempty,omitzero"` // Legacy (<= 0.17)
|
||||||
// Logs *LogsPayload `cbor:"4,keyasint,omitempty,omitzero"`
|
// Data is the generic response payload for new endpoints (0.18+)
|
||||||
// RawBytes []byte `cbor:"4,keyasint,omitempty,omitzero"`
|
Data cbor.RawMessage `cbor:"7,keyasint,omitempty,omitzero"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FingerprintRequest struct {
|
type FingerprintRequest struct {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ RUN rm -rf /tmp/*
|
|||||||
# --------------------------
|
# --------------------------
|
||||||
# Final image: default scratch-based agent
|
# Final image: default scratch-based agent
|
||||||
# --------------------------
|
# --------------------------
|
||||||
FROM alpine:3.22
|
FROM alpine:3.23
|
||||||
COPY --from=builder /agent /agent
|
COPY --from=builder /agent /agent
|
||||||
|
|
||||||
RUN apk add --no-cache smartmontools
|
RUN apk add --no-cache smartmontools
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-
|
|||||||
# Final image
|
# Final image
|
||||||
# Note: must cap_add: [CAP_PERFMON] and mount /dev/dri/ as volume
|
# Note: must cap_add: [CAP_PERFMON] and mount /dev/dri/ as volume
|
||||||
# --------------------------
|
# --------------------------
|
||||||
FROM alpine:3.22
|
FROM alpine:3.23
|
||||||
|
|
||||||
COPY --from=builder /agent /agent
|
COPY --from=builder /agent /agent
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM --platform=$BUILDPLATFORM golang:alpine AS builder
|
FROM --platform=$BUILDPLATFORM golang:bookworm AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ COPY . ./
|
|||||||
|
|
||||||
# Build
|
# Build
|
||||||
ARG TARGETOS TARGETARCH
|
ARG TARGETOS TARGETARCH
|
||||||
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-w -s" -o /agent ./internal/cmd/agent
|
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -tags glibc -ldflags "-w -s" -o /agent ./internal/cmd/agent
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
# Smartmontools builder stage
|
# Smartmontools builder stage
|
||||||
|
|||||||
@@ -34,15 +34,12 @@ type ApiStats struct {
|
|||||||
MemoryStats MemoryStats `json:"memory_stats"`
|
MemoryStats MemoryStats `json:"memory_stats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docker system info from /info
|
// Docker system info from /info API endpoint
|
||||||
type HostInfo struct {
|
type HostInfo struct {
|
||||||
OperatingSystem string `json:"OperatingSystem"`
|
OperatingSystem string `json:"OperatingSystem"`
|
||||||
KernelVersion string `json:"KernelVersion"`
|
KernelVersion string `json:"KernelVersion"`
|
||||||
NCPU int `json:"NCPU"`
|
NCPU int `json:"NCPU"`
|
||||||
MemTotal uint64 `json:"MemTotal"`
|
MemTotal uint64 `json:"MemTotal"`
|
||||||
// OSVersion string `json:"OSVersion"`
|
|
||||||
// OSType string `json:"OSType"`
|
|
||||||
// Architecture string `json:"Architecture"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ApiStats) CalculateCpuPercentLinux(prevCpuContainer uint64, prevCpuSystem uint64) float64 {
|
func (s *ApiStats) CalculateCpuPercentLinux(prevCpuContainer uint64, prevCpuSystem uint64) float64 {
|
||||||
|
|||||||
@@ -125,22 +125,22 @@ const (
|
|||||||
|
|
||||||
// Core system data that is needed in All Systems table
|
// Core system data that is needed in All Systems table
|
||||||
type Info struct {
|
type Info struct {
|
||||||
Hostname string `json:"h,omitempty" cbor:"0,keyasint,omitempty"` // deprecated - moved to Details struct
|
Hostname string `json:"h,omitempty" cbor:"0,keyasint,omitempty"` // deprecated - moved to Details struct
|
||||||
KernelVersion string `json:"k,omitempty" cbor:"1,keyasint,omitempty"` // deprecated - moved to Details struct
|
KernelVersion string `json:"k,omitempty" cbor:"1,keyasint,omitempty"` // deprecated - moved to Details struct
|
||||||
Cores int `json:"c,omitzero" cbor:"2,keyasint,omitzero"` // deprecated - moved to Details struct
|
Cores int `json:"c,omitzero" cbor:"2,keyasint,omitzero"` // deprecated - moved to Details struct
|
||||||
CpuModel string `json:"m,omitempty" cbor:"4,keyasint,omitempty"` // deprecated - moved to Details struct
|
|
||||||
Podman bool `json:"p,omitempty" cbor:"11,keyasint,omitempty"` // deprecated - moved to Details struct
|
|
||||||
Os Os `json:"os,omitempty" cbor:"14,keyasint,omitempty"` // deprecated - moved to Details struct
|
|
||||||
// Threads is needed in Info struct to calculate load average thresholds
|
// Threads is needed in Info struct to calculate load average thresholds
|
||||||
Threads int `json:"t,omitempty" cbor:"3,keyasint,omitempty"`
|
Threads int `json:"t,omitempty" cbor:"3,keyasint,omitempty"`
|
||||||
|
CpuModel string `json:"m,omitempty" cbor:"4,keyasint,omitempty"` // deprecated - moved to Details struct
|
||||||
Uptime uint64 `json:"u" cbor:"5,keyasint"`
|
Uptime uint64 `json:"u" cbor:"5,keyasint"`
|
||||||
Cpu float64 `json:"cpu" cbor:"6,keyasint"`
|
Cpu float64 `json:"cpu" cbor:"6,keyasint"`
|
||||||
MemPct float64 `json:"mp" cbor:"7,keyasint"`
|
MemPct float64 `json:"mp" cbor:"7,keyasint"`
|
||||||
DiskPct float64 `json:"dp" cbor:"8,keyasint"`
|
DiskPct float64 `json:"dp" cbor:"8,keyasint"`
|
||||||
Bandwidth float64 `json:"b" cbor:"9,keyasint"`
|
Bandwidth float64 `json:"b" cbor:"9,keyasint"`
|
||||||
AgentVersion string `json:"v" cbor:"10,keyasint"`
|
AgentVersion string `json:"v" cbor:"10,keyasint"`
|
||||||
|
Podman bool `json:"p,omitempty" cbor:"11,keyasint,omitempty"` // deprecated - moved to Details struct
|
||||||
GpuPct float64 `json:"g,omitempty" cbor:"12,keyasint,omitempty"`
|
GpuPct float64 `json:"g,omitempty" cbor:"12,keyasint,omitempty"`
|
||||||
DashboardTemp float64 `json:"dt,omitempty" cbor:"13,keyasint,omitempty"`
|
DashboardTemp float64 `json:"dt,omitempty" cbor:"13,keyasint,omitempty"`
|
||||||
|
Os Os `json:"os,omitempty" cbor:"14,keyasint,omitempty"` // deprecated - moved to Details struct
|
||||||
LoadAvg1 float64 `json:"l1,omitempty" cbor:"15,keyasint,omitempty"` // deprecated - use `la` array instead
|
LoadAvg1 float64 `json:"l1,omitempty" cbor:"15,keyasint,omitempty"` // deprecated - use `la` array instead
|
||||||
LoadAvg5 float64 `json:"l5,omitempty" cbor:"16,keyasint,omitempty"` // deprecated - use `la` array instead
|
LoadAvg5 float64 `json:"l5,omitempty" cbor:"16,keyasint,omitempty"` // deprecated - use `la` array instead
|
||||||
LoadAvg15 float64 `json:"l15,omitempty" cbor:"17,keyasint,omitempty"` // deprecated - use `la` array instead
|
LoadAvg15 float64 `json:"l15,omitempty" cbor:"17,keyasint,omitempty"` // deprecated - use `la` array instead
|
||||||
@@ -155,16 +155,17 @@ type Info struct {
|
|||||||
|
|
||||||
// Data that does not change during process lifetime and is not needed in All Systems table
|
// Data that does not change during process lifetime and is not needed in All Systems table
|
||||||
type Details struct {
|
type Details struct {
|
||||||
Hostname string `cbor:"0,keyasint"`
|
Hostname string `cbor:"0,keyasint"`
|
||||||
Kernel string `cbor:"1,keyasint,omitempty"`
|
Kernel string `cbor:"1,keyasint,omitempty"`
|
||||||
Cores int `cbor:"2,keyasint"`
|
Cores int `cbor:"2,keyasint"`
|
||||||
Threads int `cbor:"3,keyasint"`
|
Threads int `cbor:"3,keyasint"`
|
||||||
CpuModel string `cbor:"4,keyasint"`
|
CpuModel string `cbor:"4,keyasint"`
|
||||||
Os Os `cbor:"5,keyasint"`
|
Os Os `cbor:"5,keyasint"`
|
||||||
OsName string `cbor:"6,keyasint"`
|
OsName string `cbor:"6,keyasint"`
|
||||||
Arch string `cbor:"7,keyasint"`
|
Arch string `cbor:"7,keyasint"`
|
||||||
Podman bool `cbor:"8,keyasint,omitempty"`
|
Podman bool `cbor:"8,keyasint,omitempty"`
|
||||||
MemoryTotal uint64 `cbor:"9,keyasint"`
|
MemoryTotal uint64 `cbor:"9,keyasint"`
|
||||||
|
SmartInterval time.Duration `cbor:"10,keyasint,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final data structure to return to the hub
|
// Final data structure to return to the hub
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -345,5 +346,32 @@ func archiveSuffix(binaryName, goos, goarch string) string {
|
|||||||
if goos == "windows" {
|
if goos == "windows" {
|
||||||
return fmt.Sprintf("%s_%s_%s.zip", binaryName, goos, goarch)
|
return fmt.Sprintf("%s_%s_%s.zip", binaryName, goos, goarch)
|
||||||
}
|
}
|
||||||
|
// Use glibc build for agent on glibc systems (includes NVML support via purego)
|
||||||
|
if binaryName == "beszel-agent" && goos == "linux" && goarch == "amd64" && isGlibc() {
|
||||||
|
return fmt.Sprintf("%s_%s_%s_glibc.tar.gz", binaryName, goos, goarch)
|
||||||
|
}
|
||||||
return fmt.Sprintf("%s_%s_%s.tar.gz", binaryName, goos, goarch)
|
return fmt.Sprintf("%s_%s_%s.tar.gz", binaryName, goos, goarch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isGlibc() bool {
|
||||||
|
for _, path := range []string{
|
||||||
|
"/lib64/ld-linux-x86-64.so.2", // common on many distros
|
||||||
|
"/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", // Debian/Ubuntu
|
||||||
|
"/lib/ld-linux-x86-64.so.2", // alternate
|
||||||
|
} {
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback to ldd output when present (musl ldd reports musl, glibc reports GNU libc/glibc).
|
||||||
|
if lddPath, err := exec.LookPath("ldd"); err == nil {
|
||||||
|
out, err := exec.Command(lddPath, "--version").CombinedOutput()
|
||||||
|
if err == nil {
|
||||||
|
s := strings.ToLower(string(out))
|
||||||
|
if strings.Contains(s, "gnu libc") || strings.Contains(s, "glibc") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ func (acr *agentConnectRequest) agentConnect() (err error) {
|
|||||||
|
|
||||||
// Check if token is an active universal token
|
// Check if token is an active universal token
|
||||||
acr.userId, acr.isUniversalToken = universalTokenMap.GetMap().GetOk(acr.token)
|
acr.userId, acr.isUniversalToken = universalTokenMap.GetMap().GetOk(acr.token)
|
||||||
|
if !acr.isUniversalToken {
|
||||||
|
// Fallback: check for a permanent universal token stored in the DB
|
||||||
|
if rec, err := acr.hub.FindFirstRecordByFilter("universal_tokens", "token = {:token}", dbx.Params{"token": acr.token}); err == nil {
|
||||||
|
if userID := rec.GetString("user"); userID != "" {
|
||||||
|
acr.userId = userID
|
||||||
|
acr.isUniversalToken = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find matching fingerprint records for this token
|
// Find matching fingerprint records for this token
|
||||||
fpRecords := getFingerprintRecordsByToken(acr.token, acr.hub)
|
fpRecords := getFingerprintRecordsByToken(acr.token, acr.hub)
|
||||||
|
|||||||
@@ -1169,6 +1169,106 @@ func TestMultipleSystemsWithSameUniversalToken(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPermanentUniversalTokenFromDB verifies that a universal token persisted in the DB
|
||||||
|
// (universal_tokens collection) is accepted for agent self-registration even if it is not
|
||||||
|
// present in the in-memory universalTokenMap.
|
||||||
|
func TestPermanentUniversalTokenFromDB(t *testing.T) {
|
||||||
|
// Create hub and test app
|
||||||
|
hub, testApp, err := createTestHub(t)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer testApp.Cleanup()
|
||||||
|
|
||||||
|
// Get the hub's SSH key
|
||||||
|
hubSigner, err := hub.GetSSHKey("")
|
||||||
|
require.NoError(t, err)
|
||||||
|
goodPubKey := hubSigner.PublicKey()
|
||||||
|
|
||||||
|
// Create test user
|
||||||
|
userRecord, err := createTestUser(testApp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Create a permanent universal token record in the DB (do NOT add it to universalTokenMap)
|
||||||
|
universalToken := "db-universal-token-123"
|
||||||
|
_, err = createTestRecord(testApp, "universal_tokens", map[string]any{
|
||||||
|
"user": userRecord.Id,
|
||||||
|
"token": universalToken,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Create HTTP server with the actual API route
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path == "/api/beszel/agent-connect" {
|
||||||
|
acr := &agentConnectRequest{
|
||||||
|
hub: hub,
|
||||||
|
req: r,
|
||||||
|
res: w,
|
||||||
|
}
|
||||||
|
acr.agentConnect()
|
||||||
|
} else {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
// Create and configure agent
|
||||||
|
agentDataDir := t.TempDir()
|
||||||
|
err = os.WriteFile(filepath.Join(agentDataDir, "fingerprint"), []byte("db-token-system-fingerprint"), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testAgent, err := agent.NewAgent(agentDataDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Set up environment variables for the agent
|
||||||
|
os.Setenv("BESZEL_AGENT_HUB_URL", ts.URL)
|
||||||
|
os.Setenv("BESZEL_AGENT_TOKEN", universalToken)
|
||||||
|
defer func() {
|
||||||
|
os.Unsetenv("BESZEL_AGENT_HUB_URL")
|
||||||
|
os.Unsetenv("BESZEL_AGENT_TOKEN")
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Start agent in background
|
||||||
|
done := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
serverOptions := agent.ServerOptions{
|
||||||
|
Network: "tcp",
|
||||||
|
Addr: "127.0.0.1:46050",
|
||||||
|
Keys: []ssh.PublicKey{goodPubKey},
|
||||||
|
}
|
||||||
|
done <- testAgent.Start(serverOptions)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for connection result
|
||||||
|
maxWait := 2 * time.Second
|
||||||
|
time.Sleep(20 * time.Millisecond)
|
||||||
|
checkInterval := 20 * time.Millisecond
|
||||||
|
timeout := time.After(maxWait)
|
||||||
|
ticker := time.Tick(checkInterval)
|
||||||
|
|
||||||
|
connectionManager := testAgent.GetConnectionManager()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-timeout:
|
||||||
|
t.Fatalf("Expected connection to succeed but timed out - agent state: %d", connectionManager.State)
|
||||||
|
case <-ticker:
|
||||||
|
if connectionManager.State == agent.WebSocketConnected {
|
||||||
|
// Success
|
||||||
|
goto verify
|
||||||
|
}
|
||||||
|
case err := <-done:
|
||||||
|
// If Start returns early, treat it as failure
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Agent failed to start/connect: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify:
|
||||||
|
// Verify that a system was created for the user (self-registration path)
|
||||||
|
systemsAfter, err := testApp.FindRecordsByFilter("systems", "users ~ {:userId}", "", -1, 0, map[string]any{"userId": userRecord.Id})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, systemsAfter, "Expected a system to be created for DB-backed universal token")
|
||||||
|
}
|
||||||
|
|
||||||
// TestFindOrCreateSystemForToken tests the findOrCreateSystemForToken function
|
// TestFindOrCreateSystemForToken tests the findOrCreateSystemForToken function
|
||||||
func TestFindOrCreateSystemForToken(t *testing.T) {
|
func TestFindOrCreateSystemForToken(t *testing.T) {
|
||||||
hub, testApp, err := createTestHub(t)
|
hub, testApp, err := createTestHub(t)
|
||||||
|
|||||||
@@ -415,7 +415,11 @@ func TestExpiryMap_RemoveValue_WithExpiration(t *testing.T) {
|
|||||||
// Wait for first value to expire
|
// Wait for first value to expire
|
||||||
time.Sleep(time.Millisecond * 20)
|
time.Sleep(time.Millisecond * 20)
|
||||||
|
|
||||||
// Try to remove the expired value - should remove one of the "value1" entries
|
// Trigger lazy cleanup of the expired key
|
||||||
|
_, ok := em.GetOk("key1")
|
||||||
|
assert.False(t, ok)
|
||||||
|
|
||||||
|
// Try to remove the remaining "value1" entry (key3)
|
||||||
removedValue, ok := em.RemovebyValue("value1")
|
removedValue, ok := em.RemovebyValue("value1")
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
assert.Equal(t, "value1", removedValue)
|
assert.Equal(t, "value1", removedValue)
|
||||||
@@ -423,14 +427,9 @@ func TestExpiryMap_RemoveValue_WithExpiration(t *testing.T) {
|
|||||||
// Should still have key2 (different value)
|
// Should still have key2 (different value)
|
||||||
assert.True(t, em.Has("key2"))
|
assert.True(t, em.Has("key2"))
|
||||||
|
|
||||||
// Should have removed one of the "value1" entries (either key1 or key3)
|
// key1 should be gone due to expiration and key3 should be removed by value.
|
||||||
// But we can't predict which one due to map iteration order
|
assert.False(t, em.Has("key1"))
|
||||||
key1Exists := em.Has("key1")
|
assert.False(t, em.Has("key3"))
|
||||||
key3Exists := em.Has("key3")
|
|
||||||
|
|
||||||
// Exactly one of key1 or key3 should be gone
|
|
||||||
assert.False(t, key1Exists && key3Exists) // Both shouldn't exist
|
|
||||||
assert.True(t, key1Exists || key3Exists) // At least one should still exist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExpiryMap_ValueOperations_Integration(t *testing.T) {
|
func TestExpiryMap_ValueOperations_Integration(t *testing.T) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/henrygd/beszel/internal/users"
|
"github.com/henrygd/beszel/internal/users"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
"github.com/pocketbase/pocketbase"
|
"github.com/pocketbase/pocketbase"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
@@ -288,24 +289,90 @@ func (h *Hub) getUniversalToken(e *core.RequestEvent) error {
|
|||||||
userID := e.Auth.Id
|
userID := e.Auth.Id
|
||||||
query := e.Request.URL.Query()
|
query := e.Request.URL.Query()
|
||||||
token := query.Get("token")
|
token := query.Get("token")
|
||||||
|
enable := query.Get("enable")
|
||||||
|
permanent := query.Get("permanent")
|
||||||
|
|
||||||
|
// helper for deleting any existing permanent token record for this user
|
||||||
|
deletePermanent := func() error {
|
||||||
|
rec, err := h.FindFirstRecordByFilter("universal_tokens", "user = {:user}", dbx.Params{"user": userID})
|
||||||
|
if err != nil {
|
||||||
|
return nil // no record
|
||||||
|
}
|
||||||
|
return h.Delete(rec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper for upserting a permanent token record for this user
|
||||||
|
upsertPermanent := func(token string) error {
|
||||||
|
rec, err := h.FindFirstRecordByFilter("universal_tokens", "user = {:user}", dbx.Params{"user": userID})
|
||||||
|
if err == nil {
|
||||||
|
rec.Set("token", token)
|
||||||
|
return h.Save(rec)
|
||||||
|
}
|
||||||
|
|
||||||
|
col, err := h.FindCachedCollectionByNameOrId("universal_tokens")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newRec := core.NewRecord(col)
|
||||||
|
newRec.Set("user", userID)
|
||||||
|
newRec.Set("token", token)
|
||||||
|
return h.Save(newRec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable universal tokens (both ephemeral and permanent)
|
||||||
|
if enable == "0" {
|
||||||
|
tokenMap.RemovebyValue(userID)
|
||||||
|
_ = deletePermanent()
|
||||||
|
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": false, "permanent": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable universal token (ephemeral or permanent)
|
||||||
|
if enable == "1" {
|
||||||
|
if token == "" {
|
||||||
|
token = uuid.New().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if permanent == "1" {
|
||||||
|
// make token permanent (persist across restarts)
|
||||||
|
tokenMap.RemovebyValue(userID)
|
||||||
|
if err := upsertPermanent(token); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": true, "permanent": true})
|
||||||
|
}
|
||||||
|
|
||||||
|
// default: ephemeral mode (1 hour)
|
||||||
|
_ = deletePermanent()
|
||||||
|
tokenMap.Set(token, userID, time.Hour)
|
||||||
|
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": true, "permanent": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read current state
|
||||||
|
// Prefer permanent token if it exists.
|
||||||
|
if rec, err := h.FindFirstRecordByFilter("universal_tokens", "user = {:user}", dbx.Params{"user": userID}); err == nil {
|
||||||
|
dbToken := rec.GetString("token")
|
||||||
|
// If no token was provided, or the caller is asking about their permanent token, return it.
|
||||||
|
if token == "" || token == dbToken {
|
||||||
|
return e.JSON(http.StatusOK, map[string]any{"token": dbToken, "active": true, "permanent": true})
|
||||||
|
}
|
||||||
|
// Token doesn't match their permanent token (avoid leaking other info)
|
||||||
|
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": false, "permanent": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
// No permanent token; fall back to ephemeral token map.
|
||||||
if token == "" {
|
if token == "" {
|
||||||
// return existing token if it exists
|
// return existing token if it exists
|
||||||
if token, _, ok := tokenMap.GetByValue(userID); ok {
|
if token, _, ok := tokenMap.GetByValue(userID); ok {
|
||||||
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": true})
|
return e.JSON(http.StatusOK, map[string]any{"token": token, "active": true, "permanent": false})
|
||||||
}
|
}
|
||||||
// if no token is provided, generate a new one
|
// if no token is provided, generate a new one
|
||||||
token = uuid.New().String()
|
token = uuid.New().String()
|
||||||
}
|
}
|
||||||
response := map[string]any{"token": token}
|
|
||||||
|
|
||||||
switch query.Get("enable") {
|
// Token is considered active only if it belongs to the current user.
|
||||||
case "1":
|
activeUser, ok := tokenMap.GetOk(token)
|
||||||
tokenMap.Set(token, userID, time.Hour)
|
active := ok && activeUser == userID
|
||||||
case "0":
|
response := map[string]any{"token": token, "active": active, "permanent": false}
|
||||||
tokenMap.RemovebyValue(userID)
|
|
||||||
}
|
|
||||||
_, response["active"] = tokenMap.GetOk(token)
|
|
||||||
return e.JSON(http.StatusOK, response)
|
return e.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -378,7 +378,18 @@ func TestApiRoutesAuthentication(t *testing.T) {
|
|||||||
"Authorization": userToken,
|
"Authorization": userToken,
|
||||||
},
|
},
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
ExpectedContent: []string{"active", "token"},
|
ExpectedContent: []string{"active", "token", "permanent"},
|
||||||
|
TestAppFactory: testAppFactory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "GET /universal-token - enable permanent should succeed",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
URL: "/api/beszel/universal-token?enable=1&permanent=1&token=permanent-token-123",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Authorization": userToken,
|
||||||
|
},
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
ExpectedContent: []string{"\"permanent\":true", "permanent-token-123"},
|
||||||
TestAppFactory: testAppFactory,
|
TestAppFactory: testAppFactory,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
|
"github.com/henrygd/beszel/internal/hub/transport"
|
||||||
"github.com/henrygd/beszel/internal/hub/ws"
|
"github.com/henrygd/beszel/internal/hub/ws"
|
||||||
|
|
||||||
"github.com/henrygd/beszel/internal/entities/container"
|
"github.com/henrygd/beszel/internal/entities/container"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
"github.com/henrygd/beszel/internal/entities/systemd"
|
||||||
|
|
||||||
@@ -23,27 +25,30 @@ import (
|
|||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
"github.com/fxamacker/cbor/v2"
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
"github.com/lxzan/gws"
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
Id string `db:"id"`
|
Id string `db:"id"`
|
||||||
Host string `db:"host"`
|
Host string `db:"host"`
|
||||||
Port string `db:"port"`
|
Port string `db:"port"`
|
||||||
Status string `db:"status"`
|
Status string `db:"status"`
|
||||||
manager *SystemManager // Manager that this system belongs to
|
manager *SystemManager // Manager that this system belongs to
|
||||||
client *ssh.Client // SSH client for fetching data
|
client *ssh.Client // SSH client for fetching data
|
||||||
data *system.CombinedData // system data from agent
|
sshTransport *transport.SSHTransport // SSH transport for requests
|
||||||
ctx context.Context // Context for stopping the updater
|
data *system.CombinedData // system data from agent
|
||||||
cancel context.CancelFunc // Stops and removes system from updater
|
ctx context.Context // Context for stopping the updater
|
||||||
WsConn *ws.WsConn // Handler for agent WebSocket connection
|
cancel context.CancelFunc // Stops and removes system from updater
|
||||||
agentVersion semver.Version // Agent version
|
WsConn *ws.WsConn // Handler for agent WebSocket connection
|
||||||
updateTicker *time.Ticker // Ticker for updating the system
|
agentVersion semver.Version // Agent version
|
||||||
detailsFetched atomic.Bool // True if static system details have been fetched and saved
|
updateTicker *time.Ticker // Ticker for updating the system
|
||||||
smartFetched atomic.Bool // True if SMART devices have been fetched and saved
|
detailsFetched atomic.Bool // True if static system details have been fetched and saved
|
||||||
smartFetching atomic.Bool // True if SMART devices are currently being fetched
|
smartFetching atomic.Bool // True if SMART devices are currently being fetched
|
||||||
|
smartInterval time.Duration // Interval for periodic SMART data updates
|
||||||
|
lastSmartFetch atomic.Int64 // Unix milliseconds of last SMART data fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SystemManager) NewSystem(systemId string) *System {
|
func (sm *SystemManager) NewSystem(systemId string) *System {
|
||||||
@@ -123,10 +128,30 @@ func (sys *System) update() error {
|
|||||||
if !sys.detailsFetched.Load() {
|
if !sys.detailsFetched.Load() {
|
||||||
options.IncludeDetails = true
|
options.IncludeDetails = true
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := sys.fetchDataFromAgent(options)
|
data, err := sys.fetchDataFromAgent(options)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
_, err = sys.createRecords(data)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create system records
|
||||||
|
_, err = sys.createRecords(data)
|
||||||
|
|
||||||
|
// Fetch and save SMART devices when system first comes online or at intervals
|
||||||
|
if backgroundSmartFetchEnabled() {
|
||||||
|
if sys.smartInterval <= 0 {
|
||||||
|
sys.smartInterval = time.Hour
|
||||||
|
}
|
||||||
|
lastFetch := sys.lastSmartFetch.Load()
|
||||||
|
if time.Since(time.UnixMilli(lastFetch)) >= sys.smartInterval && sys.smartFetching.CompareAndSwap(false, true) {
|
||||||
|
go func() {
|
||||||
|
defer sys.smartFetching.Store(false)
|
||||||
|
sys.lastSmartFetch.Store(time.Now().UnixMilli())
|
||||||
|
_ = sys.FetchAndSaveSmartDevices()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +222,10 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sys.detailsFetched.Store(true)
|
sys.detailsFetched.Store(true)
|
||||||
|
// update smart interval if it's set on the agent side
|
||||||
|
if data.Details.SmartInterval > 0 {
|
||||||
|
sys.smartInterval = data.Details.SmartInterval
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
|
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
|
||||||
@@ -208,18 +237,6 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// Fetch and save SMART devices when system first comes online
|
|
||||||
if err == nil {
|
|
||||||
if !sys.smartFetched.Load() && sys.smartFetching.CompareAndSwap(false, true) {
|
|
||||||
go func() {
|
|
||||||
defer sys.smartFetching.Store(false)
|
|
||||||
if err := sys.FetchAndSaveSmartDevices(); err == nil {
|
|
||||||
sys.smartFetched.Store(true)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return systemRecord, err
|
return systemRecord, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,8 +363,78 @@ func (sys *System) getContext() (context.Context, context.CancelFunc) {
|
|||||||
return sys.ctx, sys.cancel
|
return sys.ctx, sys.cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchDataFromAgent attempts to fetch data from the agent,
|
// request sends a request to the agent, trying WebSocket first, then SSH.
|
||||||
// prioritizing WebSocket if available.
|
// This is the unified request method that uses the transport abstraction.
|
||||||
|
func (sys *System) request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
|
||||||
|
// Try WebSocket first
|
||||||
|
if sys.WsConn != nil && sys.WsConn.IsConnected() {
|
||||||
|
wsTransport := transport.NewWebSocketTransport(sys.WsConn)
|
||||||
|
if err := wsTransport.Request(ctx, action, req, dest); err == nil {
|
||||||
|
return nil
|
||||||
|
} else if !shouldFallbackToSSH(err) {
|
||||||
|
return err
|
||||||
|
} else if shouldCloseWebSocket(err) {
|
||||||
|
sys.closeWebSocketConnection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to SSH if WebSocket fails
|
||||||
|
if err := sys.ensureSSHTransport(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := sys.sshTransport.RequestWithRetry(ctx, action, req, dest, 1)
|
||||||
|
// Keep legacy SSH client/version fields in sync for other code paths.
|
||||||
|
if sys.sshTransport != nil {
|
||||||
|
sys.client = sys.sshTransport.GetClient()
|
||||||
|
sys.agentVersion = sys.sshTransport.GetAgentVersion()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldFallbackToSSH(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if errors.Is(err, gws.ErrConnClosed) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return errors.Is(err, transport.ErrWebSocketNotConnected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldCloseWebSocket(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return errors.Is(err, gws.ErrConnClosed) || errors.Is(err, transport.ErrWebSocketNotConnected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensureSSHTransport ensures the SSH transport is initialized and connected.
|
||||||
|
func (sys *System) ensureSSHTransport() error {
|
||||||
|
if sys.sshTransport == nil {
|
||||||
|
if sys.manager.sshConfig == nil {
|
||||||
|
if err := sys.manager.createSSHClientConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sys.sshTransport = transport.NewSSHTransport(transport.SSHTransportConfig{
|
||||||
|
Host: sys.Host,
|
||||||
|
Port: sys.Port,
|
||||||
|
Config: sys.manager.sshConfig,
|
||||||
|
Timeout: 4 * time.Second,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Sync client state with transport
|
||||||
|
if sys.client != nil {
|
||||||
|
sys.sshTransport.SetClient(sys.client)
|
||||||
|
sys.sshTransport.SetAgentVersion(sys.agentVersion)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetchDataFromAgent attempts to fetch data from the agent, prioritizing WebSocket if available.
|
||||||
func (sys *System) fetchDataFromAgent(options common.DataRequestOptions) (*system.CombinedData, error) {
|
func (sys *System) fetchDataFromAgent(options common.DataRequestOptions) (*system.CombinedData, error) {
|
||||||
if sys.data == nil {
|
if sys.data == nil {
|
||||||
sys.data = &system.CombinedData{}
|
sys.data = &system.CombinedData{}
|
||||||
@@ -373,114 +460,47 @@ func (sys *System) fetchDataViaWebSocket(options common.DataRequestOptions) (*sy
|
|||||||
if sys.WsConn == nil || !sys.WsConn.IsConnected() {
|
if sys.WsConn == nil || !sys.WsConn.IsConnected() {
|
||||||
return nil, errors.New("no websocket connection")
|
return nil, errors.New("no websocket connection")
|
||||||
}
|
}
|
||||||
err := sys.WsConn.RequestSystemData(context.Background(), sys.data, options)
|
wsTransport := transport.NewWebSocketTransport(sys.WsConn)
|
||||||
|
err := wsTransport.Request(context.Background(), common.GetData, options, sys.data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return sys.data, nil
|
return sys.data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchStringFromAgentViaSSH is a generic function to fetch strings via SSH
|
|
||||||
func (sys *System) fetchStringFromAgentViaSSH(action common.WebSocketAction, requestData any, errorMsg string) (string, error) {
|
|
||||||
var result string
|
|
||||||
err := sys.runSSHOperation(4*time.Second, 1, func(session *ssh.Session) (bool, error) {
|
|
||||||
stdout, err := session.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
stdin, stdinErr := session.StdinPipe()
|
|
||||||
if stdinErr != nil {
|
|
||||||
return false, stdinErr
|
|
||||||
}
|
|
||||||
if err := session.Shell(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
reqDataBytes, _ := cbor.Marshal(requestData)
|
|
||||||
req := common.HubRequest[cbor.RawMessage]{Action: action, Data: reqDataBytes}
|
|
||||||
_ = cbor.NewEncoder(stdin).Encode(req)
|
|
||||||
_ = stdin.Close()
|
|
||||||
var resp common.AgentResponse
|
|
||||||
err = cbor.NewDecoder(stdout).Decode(&resp)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if resp.String == nil {
|
|
||||||
return false, errors.New(errorMsg)
|
|
||||||
}
|
|
||||||
result = *resp.String
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchContainerInfoFromAgent fetches container info from the agent
|
// FetchContainerInfoFromAgent fetches container info from the agent
|
||||||
func (sys *System) FetchContainerInfoFromAgent(containerID string) (string, error) {
|
func (sys *System) FetchContainerInfoFromAgent(containerID string) (string, error) {
|
||||||
// fetch via websocket
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
if sys.WsConn != nil && sys.WsConn.IsConnected() {
|
defer cancel()
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
var result string
|
||||||
defer cancel()
|
err := sys.request(ctx, common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, &result)
|
||||||
return sys.WsConn.RequestContainerInfo(ctx, containerID)
|
return result, err
|
||||||
}
|
|
||||||
// fetch via SSH
|
|
||||||
return sys.fetchStringFromAgentViaSSH(common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, "no info in response")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchContainerLogsFromAgent fetches container logs from the agent
|
// FetchContainerLogsFromAgent fetches container logs from the agent
|
||||||
func (sys *System) FetchContainerLogsFromAgent(containerID string) (string, error) {
|
func (sys *System) FetchContainerLogsFromAgent(containerID string) (string, error) {
|
||||||
// fetch via websocket
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
if sys.WsConn != nil && sys.WsConn.IsConnected() {
|
defer cancel()
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
var result string
|
||||||
defer cancel()
|
err := sys.request(ctx, common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, &result)
|
||||||
return sys.WsConn.RequestContainerLogs(ctx, containerID)
|
return result, err
|
||||||
}
|
|
||||||
// fetch via SSH
|
|
||||||
return sys.fetchStringFromAgentViaSSH(common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, "no logs in response")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchSystemdInfoFromAgent fetches detailed systemd service information from the agent
|
// FetchSystemdInfoFromAgent fetches detailed systemd service information from the agent
|
||||||
func (sys *System) FetchSystemdInfoFromAgent(serviceName string) (systemd.ServiceDetails, error) {
|
func (sys *System) FetchSystemdInfoFromAgent(serviceName string) (systemd.ServiceDetails, error) {
|
||||||
// fetch via websocket
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
if sys.WsConn != nil && sys.WsConn.IsConnected() {
|
defer cancel()
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
return sys.WsConn.RequestSystemdInfo(ctx, serviceName)
|
|
||||||
}
|
|
||||||
|
|
||||||
var result systemd.ServiceDetails
|
var result systemd.ServiceDetails
|
||||||
err := sys.runSSHOperation(5*time.Second, 1, func(session *ssh.Session) (bool, error) {
|
err := sys.request(ctx, common.GetSystemdInfo, common.SystemdInfoRequest{ServiceName: serviceName}, &result)
|
||||||
stdout, err := session.StdoutPipe()
|
return result, err
|
||||||
if err != nil {
|
}
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
stdin, stdinErr := session.StdinPipe()
|
|
||||||
if stdinErr != nil {
|
|
||||||
return false, stdinErr
|
|
||||||
}
|
|
||||||
if err := session.Shell(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
reqDataBytes, _ := cbor.Marshal(common.SystemdInfoRequest{ServiceName: serviceName})
|
|
||||||
req := common.HubRequest[cbor.RawMessage]{Action: common.GetSystemdInfo, Data: reqDataBytes}
|
|
||||||
if err := cbor.NewEncoder(stdin).Encode(req); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
_ = stdin.Close()
|
|
||||||
|
|
||||||
var resp common.AgentResponse
|
|
||||||
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if resp.ServiceInfo == nil {
|
|
||||||
if resp.Error != "" {
|
|
||||||
return false, errors.New(resp.Error)
|
|
||||||
}
|
|
||||||
return false, errors.New("no systemd info in response")
|
|
||||||
}
|
|
||||||
result = resp.ServiceInfo
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// FetchSmartDataFromAgent fetches SMART data from the agent
|
||||||
|
func (sys *System) FetchSmartDataFromAgent() (map[string]smart.SmartData, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
var result map[string]smart.SmartData
|
||||||
|
err := sys.request(ctx, common.GetSmartData, nil, &result)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,8 +529,7 @@ func (sys *System) fetchDataViaSSH(options common.DataRequestOptions) (*system.C
|
|||||||
*sys.data = system.CombinedData{}
|
*sys.data = system.CombinedData{}
|
||||||
|
|
||||||
if sys.agentVersion.GTE(beszel.MinVersionAgentResponse) && stdinErr == nil {
|
if sys.agentVersion.GTE(beszel.MinVersionAgentResponse) && stdinErr == nil {
|
||||||
reqDataBytes, _ := cbor.Marshal(options)
|
req := common.HubRequest[any]{Action: common.GetData, Data: options}
|
||||||
req := common.HubRequest[cbor.RawMessage]{Action: common.GetData, Data: reqDataBytes}
|
|
||||||
_ = cbor.NewEncoder(stdin).Encode(req)
|
_ = cbor.NewEncoder(stdin).Encode(req)
|
||||||
_ = stdin.Close()
|
_ = stdin.Close()
|
||||||
|
|
||||||
@@ -646,6 +665,9 @@ func (sys *System) createSessionWithTimeout(timeout time.Duration) (*ssh.Session
|
|||||||
|
|
||||||
// closeSSHConnection closes the SSH connection but keeps the system in the manager
|
// closeSSHConnection closes the SSH connection but keeps the system in the manager
|
||||||
func (sys *System) closeSSHConnection() {
|
func (sys *System) closeSSHConnection() {
|
||||||
|
if sys.sshTransport != nil {
|
||||||
|
sys.sshTransport.Close()
|
||||||
|
}
|
||||||
if sys.client != nil {
|
if sys.client != nil {
|
||||||
sys.client.Close()
|
sys.client.Close()
|
||||||
sys.client = nil
|
sys.client = nil
|
||||||
|
|||||||
@@ -1,54 +1,14 @@
|
|||||||
package systems
|
package systems
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/fxamacker/cbor/v2"
|
|
||||||
"github.com/henrygd/beszel/internal/common"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FetchSmartDataFromAgent fetches SMART data from the agent
|
|
||||||
func (sys *System) FetchSmartDataFromAgent() (map[string]smart.SmartData, error) {
|
|
||||||
// fetch via websocket
|
|
||||||
if sys.WsConn != nil && sys.WsConn.IsConnected() {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
return sys.WsConn.RequestSmartData(ctx)
|
|
||||||
}
|
|
||||||
// fetch via SSH
|
|
||||||
var result map[string]smart.SmartData
|
|
||||||
err := sys.runSSHOperation(5*time.Second, 1, func(session *ssh.Session) (bool, error) {
|
|
||||||
stdout, err := session.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
stdin, stdinErr := session.StdinPipe()
|
|
||||||
if stdinErr != nil {
|
|
||||||
return false, stdinErr
|
|
||||||
}
|
|
||||||
if err := session.Shell(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
req := common.HubRequest[any]{Action: common.GetSmartData}
|
|
||||||
_ = cbor.NewEncoder(stdin).Encode(req)
|
|
||||||
_ = stdin.Close()
|
|
||||||
var resp common.AgentResponse
|
|
||||||
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
result = resp.SmartData
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchAndSaveSmartDevices fetches SMART data from the agent and saves it to the database
|
// FetchAndSaveSmartDevices fetches SMART data from the agent and saves it to the database
|
||||||
func (sys *System) FetchAndSaveSmartDevices() error {
|
func (sys *System) FetchAndSaveSmartDevices() error {
|
||||||
smartData, err := sys.FetchSmartDataFromAgent()
|
smartData, err := sys.FetchSmartDataFromAgent()
|
||||||
|
|||||||
10
internal/hub/systems/systems_production.go
Normal file
10
internal/hub/systems/systems_production.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//go:build !testing
|
||||||
|
// +build !testing
|
||||||
|
|
||||||
|
package systems
|
||||||
|
|
||||||
|
// Background SMART fetching is enabled in production but disabled for tests (systems_test_helpers.go).
|
||||||
|
//
|
||||||
|
// The hub integration tests create/replace systems and clean up the test apps quickly.
|
||||||
|
// Background SMART fetching can outlive teardown and crash in PocketBase internals (nil DB).
|
||||||
|
func backgroundSmartFetchEnabled() bool { return true }
|
||||||
@@ -10,6 +10,13 @@ import (
|
|||||||
entities "github.com/henrygd/beszel/internal/entities/system"
|
entities "github.com/henrygd/beszel/internal/entities/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The hub integration tests create/replace systems and cleanup the test apps quickly.
|
||||||
|
// Background SMART fetching can outlive teardown and crash in PocketBase internals (nil DB).
|
||||||
|
//
|
||||||
|
// We keep the explicit SMART refresh endpoint / method available, but disable
|
||||||
|
// the automatic background fetch during tests.
|
||||||
|
func backgroundSmartFetchEnabled() bool { return false }
|
||||||
|
|
||||||
// TESTING ONLY: GetSystemCount returns the number of systems in the store
|
// TESTING ONLY: GetSystemCount returns the number of systems in the store
|
||||||
func (sm *SystemManager) GetSystemCount() int {
|
func (sm *SystemManager) GetSystemCount() int {
|
||||||
return sm.systems.Length()
|
return sm.systems.Length()
|
||||||
|
|||||||
227
internal/hub/transport/ssh.go
Normal file
227
internal/hub/transport/ssh.go
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/blang/semver"
|
||||||
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
"github.com/henrygd/beszel/internal/common"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SSHTransport implements Transport over SSH connections.
|
||||||
|
type SSHTransport struct {
|
||||||
|
client *ssh.Client
|
||||||
|
config *ssh.ClientConfig
|
||||||
|
host string
|
||||||
|
port string
|
||||||
|
agentVersion semver.Version
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSHTransportConfig holds configuration for creating an SSH transport.
|
||||||
|
type SSHTransportConfig struct {
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
Config *ssh.ClientConfig
|
||||||
|
AgentVersion semver.Version
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSSHTransport creates a new SSH transport with the given configuration.
|
||||||
|
func NewSSHTransport(cfg SSHTransportConfig) *SSHTransport {
|
||||||
|
timeout := cfg.Timeout
|
||||||
|
if timeout == 0 {
|
||||||
|
timeout = 4 * time.Second
|
||||||
|
}
|
||||||
|
return &SSHTransport{
|
||||||
|
config: cfg.Config,
|
||||||
|
host: cfg.Host,
|
||||||
|
port: cfg.Port,
|
||||||
|
agentVersion: cfg.AgentVersion,
|
||||||
|
timeout: timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClient sets the SSH client for reuse across requests.
|
||||||
|
func (t *SSHTransport) SetClient(client *ssh.Client) {
|
||||||
|
t.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAgentVersion sets the agent version (extracted from SSH handshake).
|
||||||
|
func (t *SSHTransport) SetAgentVersion(version semver.Version) {
|
||||||
|
t.agentVersion = version
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClient returns the current SSH client (for connection management).
|
||||||
|
func (t *SSHTransport) GetClient() *ssh.Client {
|
||||||
|
return t.client
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAgentVersion returns the agent version.
|
||||||
|
func (t *SSHTransport) GetAgentVersion() semver.Version {
|
||||||
|
return t.agentVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request sends a request to the agent via SSH and unmarshals the response.
|
||||||
|
func (t *SSHTransport) Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
|
||||||
|
if t.client == nil {
|
||||||
|
if err := t.connect(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := t.createSessionWithTimeout(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
stdout, err := session.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stdin, err := session.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := session.Shell(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request
|
||||||
|
hubReq := common.HubRequest[any]{Action: action, Data: req}
|
||||||
|
if err := cbor.NewEncoder(stdin).Encode(hubReq); err != nil {
|
||||||
|
return fmt.Errorf("failed to encode request: %w", err)
|
||||||
|
}
|
||||||
|
stdin.Close()
|
||||||
|
|
||||||
|
// Read response
|
||||||
|
var resp common.AgentResponse
|
||||||
|
if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
|
||||||
|
return fmt.Errorf("failed to decode response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Error != "" {
|
||||||
|
return errors.New(resp.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := session.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnmarshalResponse(resp, action, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConnected returns true if the SSH connection is active.
|
||||||
|
func (t *SSHTransport) IsConnected() bool {
|
||||||
|
return t.client != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close terminates the SSH connection.
|
||||||
|
func (t *SSHTransport) Close() {
|
||||||
|
if t.client != nil {
|
||||||
|
t.client.Close()
|
||||||
|
t.client = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect establishes a new SSH connection.
|
||||||
|
func (t *SSHTransport) connect() error {
|
||||||
|
if t.config == nil {
|
||||||
|
return errors.New("SSH config not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
network := "tcp"
|
||||||
|
host := t.host
|
||||||
|
if strings.HasPrefix(host, "/") {
|
||||||
|
network = "unix"
|
||||||
|
} else {
|
||||||
|
host = net.JoinHostPort(host, t.port)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := ssh.Dial(network, host, t.config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.client = client
|
||||||
|
|
||||||
|
// Extract agent version from server version string
|
||||||
|
t.agentVersion, _ = extractAgentVersion(string(client.Conn.ServerVersion()))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// createSessionWithTimeout creates a new SSH session with a timeout.
|
||||||
|
func (t *SSHTransport) createSessionWithTimeout(ctx context.Context) (*ssh.Session, error) {
|
||||||
|
if t.client == nil {
|
||||||
|
return nil, errors.New("client not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, t.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
sessionChan := make(chan *ssh.Session, 1)
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
session, err := t.client.NewSession()
|
||||||
|
if err != nil {
|
||||||
|
errChan <- err
|
||||||
|
} else {
|
||||||
|
sessionChan <- session
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case session := <-sessionChan:
|
||||||
|
return session, nil
|
||||||
|
case err := <-errChan:
|
||||||
|
return nil, err
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, errors.New("timeout creating session")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractAgentVersion extracts the beszel version from SSH server version string.
|
||||||
|
func extractAgentVersion(versionString string) (semver.Version, error) {
|
||||||
|
_, after, _ := strings.Cut(versionString, "_")
|
||||||
|
return semver.Parse(after)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestWithRetry sends a request with automatic retry on connection failures.
|
||||||
|
func (t *SSHTransport) RequestWithRetry(ctx context.Context, action common.WebSocketAction, req any, dest any, retries int) error {
|
||||||
|
var lastErr error
|
||||||
|
for attempt := 0; attempt <= retries; attempt++ {
|
||||||
|
err := t.Request(ctx, action, req, dest)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
lastErr = err
|
||||||
|
|
||||||
|
// Check if it's a connection error that warrants a retry
|
||||||
|
if isConnectionError(err) && attempt < retries {
|
||||||
|
t.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return lastErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// isConnectionError checks if an error indicates a connection problem.
|
||||||
|
func isConnectionError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
errStr := err.Error()
|
||||||
|
return strings.Contains(errStr, "connection") ||
|
||||||
|
strings.Contains(errStr, "EOF") ||
|
||||||
|
strings.Contains(errStr, "closed") ||
|
||||||
|
errors.Is(err, io.EOF)
|
||||||
|
}
|
||||||
112
internal/hub/transport/transport.go
Normal file
112
internal/hub/transport/transport.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
// Package transport provides a unified abstraction for hub-agent communication
|
||||||
|
// over different transports (WebSocket, SSH).
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
"github.com/henrygd/beszel/internal/common"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/smart"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/system"
|
||||||
|
"github.com/henrygd/beszel/internal/entities/systemd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Transport defines the interface for hub-agent communication.
|
||||||
|
// Both WebSocket and SSH transports implement this interface.
|
||||||
|
type Transport interface {
|
||||||
|
// Request sends a request to the agent and unmarshals the response into dest.
|
||||||
|
// The dest parameter should be a pointer to the expected response type.
|
||||||
|
Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error
|
||||||
|
// IsConnected returns true if the transport connection is active.
|
||||||
|
IsConnected() bool
|
||||||
|
// Close terminates the transport connection.
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalResponse unmarshals an AgentResponse into the destination type.
|
||||||
|
// It first checks the generic Data field (0.19+ agents), then falls back
|
||||||
|
// to legacy typed fields for backward compatibility with 0.18.0 agents.
|
||||||
|
func UnmarshalResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {
|
||||||
|
if dest == nil {
|
||||||
|
return errors.New("nil destination")
|
||||||
|
}
|
||||||
|
// Try generic Data field first (0.19+)
|
||||||
|
if len(resp.Data) > 0 {
|
||||||
|
if err := cbor.Unmarshal(resp.Data, dest); err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal generic response data: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Fall back to legacy typed fields for older agents/hubs.
|
||||||
|
return unmarshalLegacyResponse(resp, action, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshalLegacyResponse handles legacy responses that use typed fields.
|
||||||
|
func unmarshalLegacyResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {
|
||||||
|
switch action {
|
||||||
|
case common.GetData:
|
||||||
|
d, ok := dest.(*system.CombinedData)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for GetData: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.SystemData == nil {
|
||||||
|
return errors.New("no system data in response")
|
||||||
|
}
|
||||||
|
*d = *resp.SystemData
|
||||||
|
return nil
|
||||||
|
case common.CheckFingerprint:
|
||||||
|
d, ok := dest.(*common.FingerprintResponse)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for CheckFingerprint: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.Fingerprint == nil {
|
||||||
|
return errors.New("no fingerprint in response")
|
||||||
|
}
|
||||||
|
*d = *resp.Fingerprint
|
||||||
|
return nil
|
||||||
|
case common.GetContainerLogs:
|
||||||
|
d, ok := dest.(*string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for GetContainerLogs: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.String == nil {
|
||||||
|
return errors.New("no logs in response")
|
||||||
|
}
|
||||||
|
*d = *resp.String
|
||||||
|
return nil
|
||||||
|
case common.GetContainerInfo:
|
||||||
|
d, ok := dest.(*string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for GetContainerInfo: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.String == nil {
|
||||||
|
return errors.New("no info in response")
|
||||||
|
}
|
||||||
|
*d = *resp.String
|
||||||
|
return nil
|
||||||
|
case common.GetSmartData:
|
||||||
|
d, ok := dest.(*map[string]smart.SmartData)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for GetSmartData: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.SmartData == nil {
|
||||||
|
return errors.New("no SMART data in response")
|
||||||
|
}
|
||||||
|
*d = resp.SmartData
|
||||||
|
return nil
|
||||||
|
case common.GetSystemdInfo:
|
||||||
|
d, ok := dest.(*systemd.ServiceDetails)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected dest type for GetSystemdInfo: %T", dest)
|
||||||
|
}
|
||||||
|
if resp.ServiceInfo == nil {
|
||||||
|
return errors.New("no systemd info in response")
|
||||||
|
}
|
||||||
|
*d = resp.ServiceInfo
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unsupported action: %d", action)
|
||||||
|
}
|
||||||
74
internal/hub/transport/websocket.go
Normal file
74
internal/hub/transport/websocket.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/fxamacker/cbor/v2"
|
||||||
|
"github.com/henrygd/beszel"
|
||||||
|
"github.com/henrygd/beszel/internal/common"
|
||||||
|
"github.com/henrygd/beszel/internal/hub/ws"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrWebSocketNotConnected indicates a WebSocket transport is not currently connected.
|
||||||
|
var ErrWebSocketNotConnected = errors.New("websocket not connected")
|
||||||
|
|
||||||
|
// WebSocketTransport implements Transport over WebSocket connections.
|
||||||
|
type WebSocketTransport struct {
|
||||||
|
wsConn *ws.WsConn
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebSocketTransport creates a new WebSocket transport wrapper.
|
||||||
|
func NewWebSocketTransport(wsConn *ws.WsConn) *WebSocketTransport {
|
||||||
|
return &WebSocketTransport{wsConn: wsConn}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request sends a request to the agent via WebSocket and unmarshals the response.
|
||||||
|
func (t *WebSocketTransport) Request(ctx context.Context, action common.WebSocketAction, req any, dest any) error {
|
||||||
|
if !t.IsConnected() {
|
||||||
|
return ErrWebSocketNotConnected
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingReq, err := t.wsConn.SendRequest(ctx, action, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for response
|
||||||
|
select {
|
||||||
|
case message := <-pendingReq.ResponseCh:
|
||||||
|
defer message.Close()
|
||||||
|
defer pendingReq.Cancel()
|
||||||
|
|
||||||
|
// Legacy agents (< MinVersionAgentResponse) respond with a raw payload instead of an AgentResponse wrapper.
|
||||||
|
if t.wsConn.AgentVersion().LT(beszel.MinVersionAgentResponse) {
|
||||||
|
return cbor.Unmarshal(message.Data.Bytes(), dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
var agentResponse common.AgentResponse
|
||||||
|
if err := cbor.Unmarshal(message.Data.Bytes(), &agentResponse); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if agentResponse.Error != "" {
|
||||||
|
return errors.New(agentResponse.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnmarshalResponse(agentResponse, action, dest)
|
||||||
|
|
||||||
|
case <-pendingReq.Context.Done():
|
||||||
|
return pendingReq.Context.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConnected returns true if the WebSocket connection is active.
|
||||||
|
func (t *WebSocketTransport) IsConnected() bool {
|
||||||
|
return t.wsConn != nil && t.wsConn.IsConnected()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close terminates the WebSocket connection.
|
||||||
|
func (t *WebSocketTransport) Close() {
|
||||||
|
if t.wsConn != nil {
|
||||||
|
t.wsConn.Close(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,14 +6,12 @@ import (
|
|||||||
|
|
||||||
"github.com/fxamacker/cbor/v2"
|
"github.com/fxamacker/cbor/v2"
|
||||||
"github.com/henrygd/beszel/internal/common"
|
"github.com/henrygd/beszel/internal/common"
|
||||||
"github.com/henrygd/beszel/internal/entities/smart"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/system"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
|
||||||
"github.com/lxzan/gws"
|
"github.com/lxzan/gws"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResponseHandler defines interface for handling agent responses
|
// ResponseHandler defines interface for handling agent responses.
|
||||||
|
// This is used by handleAgentRequest for legacy response handling.
|
||||||
type ResponseHandler interface {
|
type ResponseHandler interface {
|
||||||
Handle(agentResponse common.AgentResponse) error
|
Handle(agentResponse common.AgentResponse) error
|
||||||
HandleLegacy(rawData []byte) error
|
HandleLegacy(rawData []byte) error
|
||||||
@@ -27,167 +25,7 @@ func (h *BaseHandler) HandleLegacy(rawData []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////
|
// Fingerprint handling (used for WebSocket authentication)
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// systemDataHandler implements ResponseHandler for system data requests
|
|
||||||
type systemDataHandler struct {
|
|
||||||
data *system.CombinedData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *systemDataHandler) HandleLegacy(rawData []byte) error {
|
|
||||||
return cbor.Unmarshal(rawData, h.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *systemDataHandler) Handle(agentResponse common.AgentResponse) error {
|
|
||||||
if agentResponse.SystemData != nil {
|
|
||||||
*h.data = *agentResponse.SystemData
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestSystemData requests system metrics from the agent and unmarshals the response.
|
|
||||||
func (ws *WsConn) RequestSystemData(ctx context.Context, data *system.CombinedData, options common.DataRequestOptions) error {
|
|
||||||
if !ws.IsConnected() {
|
|
||||||
return gws.ErrConnClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := ws.requestManager.SendRequest(ctx, common.GetData, options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
handler := &systemDataHandler{data: data}
|
|
||||||
return ws.handleAgentRequest(req, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// stringResponseHandler is a generic handler for string responses from agents
|
|
||||||
type stringResponseHandler struct {
|
|
||||||
BaseHandler
|
|
||||||
value string
|
|
||||||
errorMsg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *stringResponseHandler) Handle(agentResponse common.AgentResponse) error {
|
|
||||||
if agentResponse.String == nil {
|
|
||||||
return errors.New(h.errorMsg)
|
|
||||||
}
|
|
||||||
h.value = *agentResponse.String
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// requestContainerStringViaWS is a generic function to request container-related strings via WebSocket
|
|
||||||
func (ws *WsConn) requestContainerStringViaWS(ctx context.Context, action common.WebSocketAction, requestData any, errorMsg string) (string, error) {
|
|
||||||
if !ws.IsConnected() {
|
|
||||||
return "", gws.ErrConnClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := ws.requestManager.SendRequest(ctx, action, requestData)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
handler := &stringResponseHandler{errorMsg: errorMsg}
|
|
||||||
if err := ws.handleAgentRequest(req, handler); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler.value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestContainerLogs requests logs for a specific container via WebSocket.
|
|
||||||
func (ws *WsConn) RequestContainerLogs(ctx context.Context, containerID string) (string, error) {
|
|
||||||
return ws.requestContainerStringViaWS(ctx, common.GetContainerLogs, common.ContainerLogsRequest{ContainerID: containerID}, "no logs in response")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestContainerInfo requests information about a specific container via WebSocket.
|
|
||||||
func (ws *WsConn) RequestContainerInfo(ctx context.Context, containerID string) (string, error) {
|
|
||||||
return ws.requestContainerStringViaWS(ctx, common.GetContainerInfo, common.ContainerInfoRequest{ContainerID: containerID}, "no info in response")
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// RequestSystemdInfo requests detailed information about a systemd service via WebSocket.
|
|
||||||
func (ws *WsConn) RequestSystemdInfo(ctx context.Context, serviceName string) (systemd.ServiceDetails, error) {
|
|
||||||
if !ws.IsConnected() {
|
|
||||||
return nil, gws.ErrConnClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := ws.requestManager.SendRequest(ctx, common.GetSystemdInfo, common.SystemdInfoRequest{ServiceName: serviceName})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var result systemd.ServiceDetails
|
|
||||||
handler := &systemdInfoHandler{result: &result}
|
|
||||||
if err := ws.handleAgentRequest(req, handler); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemdInfoHandler parses ServiceDetails from AgentResponse
|
|
||||||
type systemdInfoHandler struct {
|
|
||||||
BaseHandler
|
|
||||||
result *systemd.ServiceDetails
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *systemdInfoHandler) Handle(agentResponse common.AgentResponse) error {
|
|
||||||
if agentResponse.ServiceInfo == nil {
|
|
||||||
return errors.New("no systemd info in response")
|
|
||||||
}
|
|
||||||
*h.result = agentResponse.ServiceInfo
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// RequestSmartData requests SMART data via WebSocket.
|
|
||||||
func (ws *WsConn) RequestSmartData(ctx context.Context) (map[string]smart.SmartData, error) {
|
|
||||||
if !ws.IsConnected() {
|
|
||||||
return nil, gws.ErrConnClosed
|
|
||||||
}
|
|
||||||
req, err := ws.requestManager.SendRequest(ctx, common.GetSmartData, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var result map[string]smart.SmartData
|
|
||||||
handler := ResponseHandler(&smartDataHandler{result: &result})
|
|
||||||
if err := ws.handleAgentRequest(req, handler); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// smartDataHandler parses SMART data map from AgentResponse
|
|
||||||
type smartDataHandler struct {
|
|
||||||
BaseHandler
|
|
||||||
result *map[string]smart.SmartData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *smartDataHandler) Handle(agentResponse common.AgentResponse) error {
|
|
||||||
if agentResponse.SmartData == nil {
|
|
||||||
return errors.New("no SMART data in response")
|
|
||||||
}
|
|
||||||
*h.result = agentResponse.SmartData
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// fingerprintHandler implements ResponseHandler for fingerprint requests
|
// fingerprintHandler implements ResponseHandler for fingerprint requests
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
//go:build testing
|
|
||||||
|
|
||||||
package ws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/henrygd/beszel/internal/common"
|
|
||||||
"github.com/henrygd/beszel/internal/entities/systemd"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSystemdInfoHandlerSuccess(t *testing.T) {
|
|
||||||
handler := &systemdInfoHandler{
|
|
||||||
result: &systemd.ServiceDetails{},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test successful handling with valid ServiceInfo
|
|
||||||
testDetails := systemd.ServiceDetails{
|
|
||||||
"Id": "nginx.service",
|
|
||||||
"ActiveState": "active",
|
|
||||||
"SubState": "running",
|
|
||||||
"Description": "A high performance web server",
|
|
||||||
"ExecMainPID": 1234,
|
|
||||||
"MemoryCurrent": 1024000,
|
|
||||||
}
|
|
||||||
|
|
||||||
response := common.AgentResponse{
|
|
||||||
ServiceInfo: testDetails,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := handler.Handle(response)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, testDetails, *handler.result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemdInfoHandlerError(t *testing.T) {
|
|
||||||
handler := &systemdInfoHandler{
|
|
||||||
result: &systemd.ServiceDetails{},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test error handling when ServiceInfo is nil
|
|
||||||
response := common.AgentResponse{
|
|
||||||
ServiceInfo: nil,
|
|
||||||
Error: "service not found",
|
|
||||||
}
|
|
||||||
|
|
||||||
err := handler.Handle(response)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, "no systemd info in response", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemdInfoHandlerEmptyResponse(t *testing.T) {
|
|
||||||
handler := &systemdInfoHandler{
|
|
||||||
result: &systemd.ServiceDetails{},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with completely empty response
|
|
||||||
response := common.AgentResponse{}
|
|
||||||
|
|
||||||
err := handler.Handle(response)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, "no systemd info in response", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemdInfoHandlerLegacyNotSupported(t *testing.T) {
|
|
||||||
handler := &systemdInfoHandler{
|
|
||||||
result: &systemd.ServiceDetails{},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that legacy format is not supported
|
|
||||||
err := handler.HandleLegacy([]byte("some data"))
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, "legacy format not supported", err.Error())
|
|
||||||
}
|
|
||||||
@@ -45,7 +45,15 @@ func NewRequestManager(conn *gws.Conn) *RequestManager {
|
|||||||
func (rm *RequestManager) SendRequest(ctx context.Context, action common.WebSocketAction, data any) (*PendingRequest, error) {
|
func (rm *RequestManager) SendRequest(ctx context.Context, action common.WebSocketAction, data any) (*PendingRequest, error) {
|
||||||
reqID := RequestID(rm.nextID.Add(1))
|
reqID := RequestID(rm.nextID.Add(1))
|
||||||
|
|
||||||
reqCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
// Respect any caller-provided deadline. If none is set, apply a reasonable default
|
||||||
|
// so pending requests don't live forever if the agent never responds.
|
||||||
|
reqCtx := ctx
|
||||||
|
var cancel context.CancelFunc
|
||||||
|
if _, hasDeadline := ctx.Deadline(); hasDeadline {
|
||||||
|
reqCtx, cancel = context.WithCancel(ctx)
|
||||||
|
} else {
|
||||||
|
reqCtx, cancel = context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
req := &PendingRequest{
|
req := &PendingRequest{
|
||||||
ID: reqID,
|
ID: reqID,
|
||||||
@@ -100,6 +108,11 @@ func (rm *RequestManager) handleResponse(message *gws.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if response.Id == nil {
|
||||||
|
rm.routeLegacyResponse(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
reqID := RequestID(*response.Id)
|
reqID := RequestID(*response.Id)
|
||||||
|
|
||||||
rm.RLock()
|
rm.RLock()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
"weak"
|
"weak"
|
||||||
@@ -161,3 +162,14 @@ func (ws *WsConn) handleAgentRequest(req *PendingRequest, handler ResponseHandle
|
|||||||
func (ws *WsConn) IsConnected() bool {
|
func (ws *WsConn) IsConnected() bool {
|
||||||
return ws.conn != nil
|
return ws.conn != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AgentVersion returns the connected agent's version (as reported during handshake).
|
||||||
|
func (ws *WsConn) AgentVersion() semver.Version {
|
||||||
|
return ws.agentVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendRequest sends a request to the agent and returns a pending request handle.
|
||||||
|
// This is used by the transport layer to send requests.
|
||||||
|
func (ws *WsConn) SendRequest(ctx context.Context, action common.WebSocketAction, data any) (*PendingRequest, error) {
|
||||||
|
return ws.requestManager.SendRequest(ctx, action, data)
|
||||||
|
}
|
||||||
|
|||||||
@@ -184,14 +184,18 @@ func TestCommonActions(t *testing.T) {
|
|||||||
assert.Equal(t, common.WebSocketAction(2), common.GetContainerLogs, "GetLogs should be action 2")
|
assert.Equal(t, common.WebSocketAction(2), common.GetContainerLogs, "GetLogs should be action 2")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLogsHandler(t *testing.T) {
|
func TestFingerprintHandler(t *testing.T) {
|
||||||
h := &stringResponseHandler{errorMsg: "no logs in response"}
|
var result common.FingerprintResponse
|
||||||
|
h := &fingerprintHandler{result: &result}
|
||||||
|
|
||||||
logValue := "test logs"
|
resp := common.AgentResponse{Fingerprint: &common.FingerprintResponse{
|
||||||
resp := common.AgentResponse{String: &logValue}
|
Fingerprint: "test-fingerprint",
|
||||||
|
Hostname: "test-host",
|
||||||
|
}}
|
||||||
err := h.Handle(resp)
|
err := h.Handle(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, logValue, h.value)
|
assert.Equal(t, "test-fingerprint", result.Fingerprint)
|
||||||
|
assert.Equal(t, "test-host", result.Hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestHandler tests that we can create a Handler
|
// TestHandler tests that we can create a Handler
|
||||||
|
|||||||
@@ -1617,6 +1617,74 @@ func init() {
|
|||||||
"type": "base",
|
"type": "base",
|
||||||
"updateRule": "",
|
"updateRule": "",
|
||||||
"viewRule": "@request.auth.id != \"\" && system.users.id ?= @request.auth.id"
|
"viewRule": "@request.auth.id != \"\" && system.users.id ?= @request.auth.id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"createRule": null,
|
||||||
|
"deleteRule": null,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"autogeneratePattern": "[a-z0-9]{10}",
|
||||||
|
"hidden": false,
|
||||||
|
"id": "text3208210256",
|
||||||
|
"max": 10,
|
||||||
|
"min": 10,
|
||||||
|
"name": "id",
|
||||||
|
"pattern": "^[a-z0-9]+$",
|
||||||
|
"presentable": false,
|
||||||
|
"primaryKey": true,
|
||||||
|
"required": true,
|
||||||
|
"system": true,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cascadeDelete": true,
|
||||||
|
"collectionId": "_pb_users_auth_",
|
||||||
|
"hidden": false,
|
||||||
|
"id": "relation2375276105",
|
||||||
|
"maxSelect": 1,
|
||||||
|
"minSelect": 0,
|
||||||
|
"name": "user",
|
||||||
|
"presentable": false,
|
||||||
|
"required": true,
|
||||||
|
"system": false,
|
||||||
|
"type": "relation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"autogeneratePattern": "",
|
||||||
|
"hidden": false,
|
||||||
|
"id": "text1597481275",
|
||||||
|
"max": 0,
|
||||||
|
"min": 0,
|
||||||
|
"name": "token",
|
||||||
|
"pattern": "",
|
||||||
|
"presentable": false,
|
||||||
|
"primaryKey": false,
|
||||||
|
"required": false,
|
||||||
|
"system": false,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": false,
|
||||||
|
"id": "autodate2990389176",
|
||||||
|
"name": "created",
|
||||||
|
"onCreate": true,
|
||||||
|
"onUpdate": false,
|
||||||
|
"presentable": false,
|
||||||
|
"system": false,
|
||||||
|
"type": "autodate"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "pbc_3383022248",
|
||||||
|
"indexes": [
|
||||||
|
"CREATE INDEX ` + "`" + `idx_iaD9Y2Lgbl` + "`" + ` ON ` + "`" + `universal_tokens` + "`" + ` (` + "`" + `token` + "`" + `)",
|
||||||
|
"CREATE UNIQUE INDEX ` + "`" + `idx_wdR0A4PbRG` + "`" + ` ON ` + "`" + `universal_tokens` + "`" + ` (` + "`" + `user` + "`" + `)"
|
||||||
|
],
|
||||||
|
"listRule": null,
|
||||||
|
"name": "universal_tokens",
|
||||||
|
"system": false,
|
||||||
|
"type": "base",
|
||||||
|
"updateRule": null,
|
||||||
|
"viewRule": null
|
||||||
}
|
}
|
||||||
]`
|
]`
|
||||||
|
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
"lucide-react": "^0.452.0",
|
"lucide-react": "^0.452.0",
|
||||||
"nanostores": "^0.11.4",
|
"nanostores": "^0.11.4",
|
||||||
"pocketbase": "^0.26.2",
|
"pocketbase": "^0.26.2",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.2",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.2",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"shiki": "^3.13.0",
|
"shiki": "^3.13.0",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
@@ -811,9 +811,9 @@
|
|||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
"react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
|
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
|
||||||
|
|
||||||
"react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="],
|
"react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="],
|
||||||
|
|
||||||
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
||||||
|
|
||||||
@@ -851,7 +851,7 @@
|
|||||||
|
|
||||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
|
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||||
|
|
||||||
"semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
@@ -971,8 +971,6 @@
|
|||||||
|
|
||||||
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||||
|
|
||||||
"pseudolocale/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="],
|
|
||||||
|
|
||||||
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
"restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
"restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||||
@@ -981,28 +979,18 @@
|
|||||||
|
|
||||||
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
||||||
|
|
||||||
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
||||||
|
|
||||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
|
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
|
||||||
|
|
||||||
"wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
|
"wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
||||||
|
|
||||||
"@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
"@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
||||||
|
|
||||||
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
||||||
|
|
||||||
"string-width/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
"string-width/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
||||||
|
|
||||||
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export default defineConfig({
|
|||||||
"he",
|
"he",
|
||||||
"hr",
|
"hr",
|
||||||
"hu",
|
"hu",
|
||||||
|
"id",
|
||||||
"it",
|
"it",
|
||||||
"ja",
|
"ja",
|
||||||
"ko",
|
"ko",
|
||||||
|
|||||||
4
internal/site/package-lock.json
generated
4
internal/site/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "beszel",
|
"name": "beszel",
|
||||||
"version": "0.17.0",
|
"version": "0.18.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "beszel",
|
"name": "beszel",
|
||||||
"version": "0.17.0",
|
"version": "0.18.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@henrygd/queue": "^1.0.7",
|
"@henrygd/queue": "^1.0.7",
|
||||||
"@henrygd/semaphore": "^0.0.2",
|
"@henrygd/semaphore": "^0.0.2",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "beszel",
|
"name": "beszel",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.18.0-beta.1",
|
"version": "0.18.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
@@ -77,4 +77,4 @@
|
|||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@esbuild/linux-arm64": "^0.21.5"
|
"@esbuild/linux-arm64": "^0.21.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,8 +57,13 @@ export default function ContainersTable({ systemId }: { systemId?: string }) {
|
|||||||
.then(
|
.then(
|
||||||
({ items }) => {
|
({ items }) => {
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
setData([]);
|
setData((curItems) => {
|
||||||
return;
|
if (systemId) {
|
||||||
|
return curItems?.filter((item) => item.system !== systemId) ?? []
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
setData((curItems) => {
|
setData((curItems) => {
|
||||||
const lastUpdated = Math.max(items[0].updated, items.at(-1)?.updated ?? 0)
|
const lastUpdated = Math.max(items[0].updated, items.at(-1)?.updated ?? 0)
|
||||||
@@ -280,7 +285,7 @@ async function getInfoHtml(container: ContainerRecord): Promise<string> {
|
|||||||
])
|
])
|
||||||
try {
|
try {
|
||||||
info = JSON.stringify(JSON.parse(info), null, 2)
|
info = JSON.stringify(JSON.parse(info), null, 2)
|
||||||
} catch (_) {}
|
} catch (_) { }
|
||||||
return info ? highlighter.codeToHtml(info, { lang: "json", theme: syntaxTheme }) : t`No results.`
|
return info ? highlighter.codeToHtml(info, { lang: "json", theme: syntaxTheme }) : t`No results.`
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -337,7 +342,7 @@ function ContainerSheet({
|
|||||||
setLogsDisplay("")
|
setLogsDisplay("")
|
||||||
setInfoDisplay("")
|
setInfoDisplay("")
|
||||||
if (!container) return
|
if (!container) return
|
||||||
;(async () => {
|
; (async () => {
|
||||||
const [logsHtml, infoHtml] = await Promise.all([getLogsHtml(container), getInfoHtml(container)])
|
const [logsHtml, infoHtml] = await Promise.all([getLogsHtml(container), getInfoHtml(container)])
|
||||||
setLogsDisplay(logsHtml)
|
setLogsDisplay(logsHtml)
|
||||||
setInfoDisplay(infoHtml)
|
setInfoDisplay(infoHtml)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export function LangToggle() {
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="grid grid-cols-3">
|
<DropdownMenuContent className="grid grid-cols-3">
|
||||||
{languages.map(({ lang, label, e }) => (
|
{languages.map(([lang, label, e]) => (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
key={lang}
|
key={lang}
|
||||||
className={cn("px-2.5 flex gap-2.5 cursor-pointer", lang === i18n.locale && "bg-accent/70 font-medium")}
|
className={cn("px-2.5 flex gap-2.5 cursor-pointer", lang === i18n.locale && "bg-accent/70 font-medium")}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ const passwordSchema = v.pipe(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const LoginSchema = v.looseObject({
|
const LoginSchema = v.looseObject({
|
||||||
name: honeypot,
|
company_website: honeypot,
|
||||||
email: emailSchema,
|
email: emailSchema,
|
||||||
password: passwordSchema,
|
password: passwordSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
const RegisterSchema = v.looseObject({
|
const RegisterSchema = v.looseObject({
|
||||||
name: honeypot,
|
company_website: honeypot,
|
||||||
email: emailSchema,
|
email: emailSchema,
|
||||||
password: passwordSchema,
|
password: passwordSchema,
|
||||||
passwordConfirm: passwordSchema,
|
passwordConfirm: passwordSchema,
|
||||||
@@ -248,8 +248,8 @@ export function UserAuthForm({
|
|||||||
)}
|
)}
|
||||||
<div className="sr-only">
|
<div className="sr-only">
|
||||||
{/* honeypot */}
|
{/* honeypot */}
|
||||||
<label htmlFor="name"></label>
|
<label htmlFor="company_website"></label>
|
||||||
<input id="name" type="text" name="name" tabIndex={-1} autoComplete="off" />
|
<input id="company_website" type="text" name="company_website" tabIndex={-1} autoComplete="off" />
|
||||||
</div>
|
</div>
|
||||||
<button className={cn(buttonVariants())} disabled={isLoading}>
|
<button className={cn(buttonVariants())} disabled={isLoading}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@@ -305,9 +305,9 @@ export function UserAuthForm({
|
|||||||
className="me-2 h-4 w-4 dark:brightness-0 dark:invert"
|
className="me-2 h-4 w-4 dark:brightness-0 dark:invert"
|
||||||
src={getAuthProviderIcon(provider)}
|
src={getAuthProviderIcon(provider)}
|
||||||
alt=""
|
alt=""
|
||||||
// onError={(e) => {
|
// onError={(e) => {
|
||||||
// e.currentTarget.src = "/static/lock.svg"
|
// e.currentTarget.src = "/static/lock.svg"
|
||||||
// }}
|
// }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="translate-y-px">{provider.displayName}</span>
|
<span className="translate-y-px">{provider.displayName}</span>
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
|||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{languages.map((lang) => (
|
{languages.map(([lang, label, e]) => (
|
||||||
<SelectItem key={lang.lang} value={lang.lang}>
|
<SelectItem key={lang} value={lang}>
|
||||||
<span className="me-2.5">{lang.e}</span>
|
<span className="me-2.5">{e}</span>
|
||||||
{lang.label}
|
{label}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
|
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { Switch } from "@/components/ui/switch"
|
import { Switch } from "@/components/ui/switch"
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||||
import { toast } from "@/components/ui/use-toast"
|
import { toast } from "@/components/ui/use-toast"
|
||||||
import { isReadOnlyUser, pb } from "@/lib/api"
|
import { isReadOnlyUser, pb } from "@/lib/api"
|
||||||
@@ -137,21 +138,23 @@ const SectionUniversalToken = memo(() => {
|
|||||||
const [token, setToken] = useState("")
|
const [token, setToken] = useState("")
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const [checked, setChecked] = useState(false)
|
const [checked, setChecked] = useState(false)
|
||||||
|
const [isPermanent, setIsPermanent] = useState(false)
|
||||||
|
|
||||||
async function updateToken(enable: number = -1) {
|
async function updateToken(enable: number = -1, permanent: number = -1) {
|
||||||
// enable: 0 for disable, 1 for enable, -1 (unset) for get current state
|
// enable: 0 for disable, 1 for enable, -1 (unset) for get current state
|
||||||
const data = await pb.send(`/api/beszel/universal-token`, {
|
const data = await pb.send(`/api/beszel/universal-token`, {
|
||||||
query: {
|
query: {
|
||||||
token,
|
token,
|
||||||
enable,
|
enable,
|
||||||
|
permanent,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
setToken(data.token)
|
setToken(data.token)
|
||||||
setChecked(data.active)
|
setChecked(data.active)
|
||||||
|
setIsPermanent(!!data.permanent)
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: only on mount
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateToken()
|
updateToken()
|
||||||
}, [])
|
}, [])
|
||||||
@@ -162,30 +165,64 @@ const SectionUniversalToken = memo(() => {
|
|||||||
<Trans>Universal token</Trans>
|
<Trans>Universal token</Trans>
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||||
<Trans>
|
<Trans>When enabled, this token allows agents to self-register without prior system creation.</Trans>
|
||||||
When enabled, this token allows agents to self-register without prior system creation. Expires after one hour
|
|
||||||
or on hub restart.
|
|
||||||
</Trans>
|
|
||||||
</p>
|
</p>
|
||||||
<div className="min-h-16 overflow-auto max-w-full inline-flex items-center gap-5 mt-3 border py-2 ps-5 pe-4 rounded-md">
|
<div className="mt-3 border rounded-md px-4 py-3 max-w-full">
|
||||||
{!isLoading && (
|
{!isLoading && (
|
||||||
<>
|
<div className="flex flex-col gap-3">
|
||||||
<Switch
|
<div className="flex items-center gap-4 min-w-0">
|
||||||
defaultChecked={checked}
|
<Switch
|
||||||
onCheckedChange={(checked) => {
|
checked={checked}
|
||||||
updateToken(checked ? 1 : 0)
|
onCheckedChange={(checked) => {
|
||||||
}}
|
// Keep current permanence preference when enabling/disabling
|
||||||
/>
|
updateToken(checked ? 1 : 0, isPermanent ? 1 : 0)
|
||||||
<span
|
}}
|
||||||
className={cn(
|
/>
|
||||||
"text-sm text-primary opacity-60 transition-opacity",
|
<div className="min-w-0 flex-1 overflow-auto">
|
||||||
checked ? "opacity-100" : "select-none"
|
<span
|
||||||
)}
|
className={cn(
|
||||||
>
|
"text-sm text-primary opacity-60 transition-opacity",
|
||||||
{token}
|
checked ? "opacity-100" : "select-none"
|
||||||
</span>
|
)}
|
||||||
<ActionsButtonUniversalToken token={token} checked={checked} />
|
>
|
||||||
</>
|
{token}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ActionsButtonUniversalToken token={token} checked={checked} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{checked && (
|
||||||
|
<div className="border-t pt-3">
|
||||||
|
<div className="text-sm font-medium">
|
||||||
|
<Trans>Persistence</Trans>
|
||||||
|
</div>
|
||||||
|
<Tabs
|
||||||
|
value={isPermanent ? "permanent" : "ephemeral"}
|
||||||
|
onValueChange={(value) => updateToken(1, value === "permanent" ? 1 : 0)}
|
||||||
|
className="mt-2"
|
||||||
|
>
|
||||||
|
<TabsList>
|
||||||
|
<TabsTrigger className="xs:min-w-40" value="ephemeral">
|
||||||
|
<Trans>Ephemeral</Trans>
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger className="xs:min-w-40" value="permanent">
|
||||||
|
<Trans>Permanent</Trans>
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
<TabsContent value="ephemeral" className="mt-3">
|
||||||
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||||
|
<Trans>Expires after one hour or on hub restart.</Trans>
|
||||||
|
</p>
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="permanent" className="mt-3">
|
||||||
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||||
|
<Trans>Saved in the database and does not expire until you disable it.</Trans>
|
||||||
|
</p>
|
||||||
|
</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import MemChart from "@/components/charts/mem-chart"
|
|||||||
import SwapChart from "@/components/charts/swap-chart"
|
import SwapChart from "@/components/charts/swap-chart"
|
||||||
import TemperatureChart from "@/components/charts/temperature-chart"
|
import TemperatureChart from "@/components/charts/temperature-chart"
|
||||||
import { getPbTimestamp, pb } from "@/lib/api"
|
import { getPbTimestamp, pb } from "@/lib/api"
|
||||||
import { ChartType, Os, SystemStatus, Unit } from "@/lib/enums"
|
import { ChartType, SystemStatus, Unit } from "@/lib/enums"
|
||||||
import { batteryStateTranslations } from "@/lib/i18n"
|
import { batteryStateTranslations } from "@/lib/i18n"
|
||||||
import {
|
import {
|
||||||
$allSystemsById,
|
$allSystemsById,
|
||||||
@@ -46,6 +46,7 @@ import type {
|
|||||||
ChartTimes,
|
ChartTimes,
|
||||||
ContainerStatsRecord,
|
ContainerStatsRecord,
|
||||||
GPUData,
|
GPUData,
|
||||||
|
SystemDetailsRecord,
|
||||||
SystemInfo,
|
SystemInfo,
|
||||||
SystemRecord,
|
SystemRecord,
|
||||||
SystemStats,
|
SystemStats,
|
||||||
@@ -166,7 +167,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
const isLongerChart = !["1m", "1h"].includes(chartTime) // true if chart time is not 1m or 1h
|
const isLongerChart = !["1m", "1h"].includes(chartTime) // true if chart time is not 1m or 1h
|
||||||
const userSettings = $userSettings.get()
|
const userSettings = $userSettings.get()
|
||||||
const chartWrapRef = useRef<HTMLDivElement>(null)
|
const chartWrapRef = useRef<HTMLDivElement>(null)
|
||||||
const [isPodman, setIsPodman] = useState(system.info?.p ?? false)
|
const [details, setDetails] = useState<SystemDetailsRecord>({} as SystemDetailsRecord)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
@@ -176,6 +177,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
persistChartTime.current = false
|
persistChartTime.current = false
|
||||||
setSystemStats([])
|
setSystemStats([])
|
||||||
setContainerData([])
|
setContainerData([])
|
||||||
|
setDetails({} as SystemDetailsRecord)
|
||||||
$containerFilter.set("")
|
$containerFilter.set("")
|
||||||
}
|
}
|
||||||
}, [id])
|
}, [id])
|
||||||
@@ -203,8 +205,23 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
}
|
}
|
||||||
}, [system?.info?.v])
|
}, [system?.info?.v])
|
||||||
|
|
||||||
|
// fetch system details
|
||||||
|
useEffect(() => {
|
||||||
|
// if system.info.m exists, agent is old version without system details
|
||||||
|
if (!system.id || system.info?.m) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pb.collection<SystemDetailsRecord>("system_details")
|
||||||
|
.getOne(system.id, {
|
||||||
|
fields: "hostname,kernel,cores,threads,cpu,os,os_name,arch,memory,podman",
|
||||||
|
headers: {
|
||||||
|
"Cache-Control": "public, max-age=60",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(setDetails)
|
||||||
|
}, [system.id])
|
||||||
|
|
||||||
// subscribe to realtime metrics if chart time is 1m
|
// subscribe to realtime metrics if chart time is 1m
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let unsub = () => {}
|
let unsub = () => {}
|
||||||
if (!system.id || chartTime !== "1m") {
|
if (!system.id || chartTime !== "1m") {
|
||||||
@@ -242,7 +259,6 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
}
|
}
|
||||||
}, [chartTime, system.id])
|
}, [chartTime, system.id])
|
||||||
|
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
|
|
||||||
const chartData: ChartData = useMemo(() => {
|
const chartData: ChartData = useMemo(() => {
|
||||||
const lastCreated = Math.max(
|
const lastCreated = Math.max(
|
||||||
(systemStats.at(-1)?.created as number) ?? 0,
|
(systemStats.at(-1)?.created as number) ?? 0,
|
||||||
@@ -282,7 +298,6 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// get stats
|
// get stats
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: not necessary
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!system.id || !chartTime || chartTime === "1m") {
|
if (!system.id || !chartTime || chartTime === "1m") {
|
||||||
return
|
return
|
||||||
@@ -322,10 +337,6 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
})
|
})
|
||||||
}, [system, chartTime])
|
}, [system, chartTime])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsPodman(system.info?.p ?? false)
|
|
||||||
}, [system.info?.p])
|
|
||||||
|
|
||||||
/** Space for tooltip if more than 10 sensors and no containers table */
|
/** Space for tooltip if more than 10 sensors and no containers table */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sensors = Object.keys(systemStats.at(-1)?.stats.t ?? {})
|
const sensors = Object.keys(systemStats.at(-1)?.stats.t ?? {})
|
||||||
@@ -389,16 +400,39 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
const containerFilterBar = containerData.length ? <FilterBar /> : null
|
const containerFilterBar = containerData.length ? <FilterBar /> : null
|
||||||
|
|
||||||
const dataEmpty = !chartLoading && chartData.systemStats.length === 0
|
const dataEmpty = !chartLoading && chartData.systemStats.length === 0
|
||||||
const lastGpuVals = Object.values(systemStats.at(-1)?.stats.g ?? {})
|
const lastGpus = systemStats.at(-1)?.stats?.g
|
||||||
const hasGpuData = lastGpuVals.length > 0
|
|
||||||
const hasGpuPowerData = lastGpuVals.some((gpu) => gpu.p !== undefined || gpu.pp !== undefined)
|
let hasGpuData = false
|
||||||
const hasGpuEnginesData = lastGpuVals.some((gpu) => gpu.e !== undefined)
|
let hasGpuEnginesData = false
|
||||||
|
let hasGpuPowerData = false
|
||||||
|
|
||||||
|
if (lastGpus) {
|
||||||
|
// check if there are any GPUs at all
|
||||||
|
hasGpuData = Object.keys(lastGpus).length > 0
|
||||||
|
// check if there are any GPUs with engines or power data
|
||||||
|
for (let i = 0; i < systemStats.length && (!hasGpuEnginesData || !hasGpuPowerData); i++) {
|
||||||
|
const gpus = systemStats[i].stats?.g
|
||||||
|
if (!gpus) continue
|
||||||
|
for (const id in gpus) {
|
||||||
|
if (!hasGpuEnginesData && gpus[id].e !== undefined) {
|
||||||
|
hasGpuEnginesData = true
|
||||||
|
}
|
||||||
|
if (!hasGpuPowerData && (gpus[id].p !== undefined || gpus[id].pp !== undefined)) {
|
||||||
|
hasGpuPowerData = true
|
||||||
|
}
|
||||||
|
if (hasGpuEnginesData && hasGpuPowerData) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLinux = !(details?.os ?? system.info?.os)
|
||||||
|
const isPodman = details?.podman ?? system.info?.p ?? false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div ref={chartWrapRef} className="grid gap-4 mb-14 overflow-x-clip">
|
<div ref={chartWrapRef} className="grid gap-4 mb-14 overflow-x-clip">
|
||||||
{/* system info */}
|
{/* system info */}
|
||||||
<InfoBar system={system} chartData={chartData} grid={grid} setGrid={setGrid} setIsPodman={setIsPodman} />
|
<InfoBar system={system} chartData={chartData} grid={grid} setGrid={setGrid} details={details} />
|
||||||
|
|
||||||
{/* <Tabs defaultValue="overview" className="w-full">
|
{/* <Tabs defaultValue="overview" className="w-full">
|
||||||
<TabsList className="w-full h-11">
|
<TabsList className="w-full h-11">
|
||||||
@@ -702,64 +736,65 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
<GpuEnginesChart chartData={chartData} />
|
<GpuEnginesChart chartData={chartData} />
|
||||||
</ChartCard>
|
</ChartCard>
|
||||||
)}
|
)}
|
||||||
{Object.keys(systemStats.at(-1)?.stats.g ?? {}).map((id) => {
|
{lastGpus &&
|
||||||
const gpu = systemStats.at(-1)?.stats.g?.[id] as GPUData
|
Object.keys(lastGpus).map((id) => {
|
||||||
return (
|
const gpu = lastGpus[id] as GPUData
|
||||||
<div key={id} className="contents">
|
return (
|
||||||
<ChartCard
|
<div key={id} className="contents">
|
||||||
className={cn(grid && "!col-span-1")}
|
|
||||||
empty={dataEmpty}
|
|
||||||
grid={grid}
|
|
||||||
title={`${gpu.n} ${t`Usage`}`}
|
|
||||||
description={t`Average utilization of ${gpu.n}`}
|
|
||||||
>
|
|
||||||
<AreaChartDefault
|
|
||||||
chartData={chartData}
|
|
||||||
dataPoints={[
|
|
||||||
{
|
|
||||||
label: t`Usage`,
|
|
||||||
dataKey: ({ stats }) => stats?.g?.[id]?.u ?? 0,
|
|
||||||
color: 1,
|
|
||||||
opacity: 0.35,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
|
|
||||||
contentFormatter={({ value }) => `${decimalString(value)}%`}
|
|
||||||
/>
|
|
||||||
</ChartCard>
|
|
||||||
|
|
||||||
{(gpu.mt ?? 0) > 0 && (
|
|
||||||
<ChartCard
|
<ChartCard
|
||||||
|
className={cn(grid && "!col-span-1")}
|
||||||
empty={dataEmpty}
|
empty={dataEmpty}
|
||||||
grid={grid}
|
grid={grid}
|
||||||
title={`${gpu.n} VRAM`}
|
title={`${gpu.n} ${t`Usage`}`}
|
||||||
description={t`Precise utilization at the recorded time`}
|
description={t`Average utilization of ${gpu.n}`}
|
||||||
>
|
>
|
||||||
<AreaChartDefault
|
<AreaChartDefault
|
||||||
chartData={chartData}
|
chartData={chartData}
|
||||||
dataPoints={[
|
dataPoints={[
|
||||||
{
|
{
|
||||||
label: t`Usage`,
|
label: t`Usage`,
|
||||||
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
|
dataKey: ({ stats }) => stats?.g?.[id]?.u ?? 0,
|
||||||
color: 2,
|
color: 1,
|
||||||
opacity: 0.25,
|
opacity: 0.35,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
max={gpu.mt}
|
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
|
||||||
tickFormatter={(val) => {
|
contentFormatter={({ value }) => `${decimalString(value)}%`}
|
||||||
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
|
|
||||||
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
|
|
||||||
}}
|
|
||||||
contentFormatter={({ value }) => {
|
|
||||||
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
|
|
||||||
return `${decimalString(convertedValue)} ${unit}`
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</ChartCard>
|
</ChartCard>
|
||||||
)}
|
|
||||||
</div>
|
{(gpu.mt ?? 0) > 0 && (
|
||||||
)
|
<ChartCard
|
||||||
})}
|
empty={dataEmpty}
|
||||||
|
grid={grid}
|
||||||
|
title={`${gpu.n} VRAM`}
|
||||||
|
description={t`Precise utilization at the recorded time`}
|
||||||
|
>
|
||||||
|
<AreaChartDefault
|
||||||
|
chartData={chartData}
|
||||||
|
dataPoints={[
|
||||||
|
{
|
||||||
|
label: t`Usage`,
|
||||||
|
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
|
||||||
|
color: 2,
|
||||||
|
opacity: 0.25,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
max={gpu.mt}
|
||||||
|
tickFormatter={(val) => {
|
||||||
|
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
|
||||||
|
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
|
||||||
|
}}
|
||||||
|
contentFormatter={({ value }) => {
|
||||||
|
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
|
||||||
|
return `${decimalString(convertedValue)} ${unit}`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ChartCard>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -841,7 +876,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
<LazyContainersTable systemId={system.id} />
|
<LazyContainersTable systemId={system.id} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{system.info?.os === Os.Linux && compareSemVer(chartData.agentVersion, parseSemVer("0.16.0")) >= 0 && (
|
{isLinux && compareSemVer(chartData.agentVersion, parseSemVer("0.16.0")) >= 0 && (
|
||||||
<LazySystemdTable systemId={system.id} />
|
<LazySystemdTable systemId={system.id} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -853,16 +888,30 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function GpuEnginesChart({ chartData }: { chartData: ChartData }) {
|
function GpuEnginesChart({ chartData }: { chartData: ChartData }) {
|
||||||
const dataPoints: DataPoint[] = []
|
const { gpuId, engines } = useMemo(() => {
|
||||||
const engines = Object.keys(chartData.systemStats?.at(-1)?.stats.g?.[0]?.e ?? {}).sort()
|
for (let i = chartData.systemStats.length - 1; i >= 0; i--) {
|
||||||
for (const engine of engines) {
|
const gpus = chartData.systemStats[i].stats?.g
|
||||||
dataPoints.push({
|
if (!gpus) continue
|
||||||
label: engine,
|
for (const id in gpus) {
|
||||||
dataKey: ({ stats }: SystemStatsRecord) => stats?.g?.[0]?.e?.[engine] ?? 0,
|
if (gpus[id].e) {
|
||||||
color: `hsl(${140 + (((engines.indexOf(engine) * 360) / engines.length) % 360)}, 65%, 52%)`,
|
return { gpuId: id, engines: Object.keys(gpus[id].e).sort() }
|
||||||
opacity: 0.35,
|
}
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
return { gpuId: null, engines: [] }
|
||||||
|
}, [chartData.systemStats])
|
||||||
|
|
||||||
|
if (!gpuId) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataPoints: DataPoint[] = engines.map((engine, i) => ({
|
||||||
|
label: engine,
|
||||||
|
dataKey: ({ stats }: SystemStatsRecord) => stats?.g?.[gpuId]?.e?.[engine] ?? 0,
|
||||||
|
color: `hsl(${140 + (((i * 360) / engines.length) % 360)}, 65%, 52%)`,
|
||||||
|
opacity: 0.35,
|
||||||
|
}))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LineChartDefault
|
<LineChartDefault
|
||||||
legend={true}
|
legend={true}
|
||||||
|
|||||||
@@ -11,14 +11,13 @@ import {
|
|||||||
MonitorIcon,
|
MonitorIcon,
|
||||||
Rows,
|
Rows,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { useEffect, useMemo, useState } from "react"
|
import { useMemo } from "react"
|
||||||
import ChartTimeSelect from "@/components/charts/chart-time-select"
|
import ChartTimeSelect from "@/components/charts/chart-time-select"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Card } from "@/components/ui/card"
|
import { Card } from "@/components/ui/card"
|
||||||
import { FreeBsdIcon, TuxIcon, WebSocketIcon, WindowsIcon } from "@/components/ui/icons"
|
import { FreeBsdIcon, TuxIcon, WebSocketIcon, WindowsIcon } from "@/components/ui/icons"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||||||
import { pb } from "@/lib/api"
|
|
||||||
import { ConnectionType, connectionTypeLabels, Os, SystemStatus } from "@/lib/enums"
|
import { ConnectionType, connectionTypeLabels, Os, SystemStatus } from "@/lib/enums"
|
||||||
import { cn, formatBytes, getHostDisplayValue, secondsToString, toFixedFloat } from "@/lib/utils"
|
import { cn, formatBytes, getHostDisplayValue, secondsToString, toFixedFloat } from "@/lib/utils"
|
||||||
import type { ChartData, SystemDetailsRecord, SystemRecord } from "@/types"
|
import type { ChartData, SystemDetailsRecord, SystemRecord } from "@/types"
|
||||||
@@ -28,44 +27,15 @@ export default function InfoBar({
|
|||||||
chartData,
|
chartData,
|
||||||
grid,
|
grid,
|
||||||
setGrid,
|
setGrid,
|
||||||
setIsPodman,
|
details,
|
||||||
}: {
|
}: {
|
||||||
system: SystemRecord
|
system: SystemRecord
|
||||||
chartData: ChartData
|
chartData: ChartData
|
||||||
grid: boolean
|
grid: boolean
|
||||||
setGrid: (grid: boolean) => void
|
setGrid: (grid: boolean) => void
|
||||||
setIsPodman: (isPodman: boolean) => void
|
details: SystemDetailsRecord | null
|
||||||
}) {
|
}) {
|
||||||
const { t } = useLingui()
|
const { t } = useLingui()
|
||||||
const [details, setDetails] = useState<SystemDetailsRecord | null>(null)
|
|
||||||
|
|
||||||
// Fetch system_details on mount / when system changes
|
|
||||||
useEffect(() => {
|
|
||||||
let active = true
|
|
||||||
setDetails(null)
|
|
||||||
// skip fetching system details if agent is older version which includes details in Info struct
|
|
||||||
if (!system.id || system.info?.m) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pb.collection<SystemDetailsRecord>("system_details")
|
|
||||||
.getOne(system.id, {
|
|
||||||
fields: "hostname,kernel,cores,threads,cpu,os,os_name,arch,memory,podman",
|
|
||||||
headers: {
|
|
||||||
"Cache-Control": "public, max-age=60",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((details) => {
|
|
||||||
if (active) {
|
|
||||||
setDetails(details)
|
|
||||||
setIsPodman(details.podman)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
active = false
|
|
||||||
}
|
|
||||||
}, [system.id])
|
|
||||||
|
|
||||||
// values for system info bar - use details with fallback to system.info
|
// values for system info bar - use details with fallback to system.info
|
||||||
const systemInfo = useMemo(() => {
|
const systemInfo = useMemo(() => {
|
||||||
|
|||||||
@@ -93,51 +93,15 @@ export const smartColumns: ColumnDef<SmartAttribute>[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export type DiskInfo = {
|
|
||||||
id: string
|
|
||||||
system: string
|
|
||||||
device: string
|
|
||||||
model: string
|
|
||||||
capacity: string
|
|
||||||
status: string
|
|
||||||
temperature: number
|
|
||||||
deviceType: string
|
|
||||||
powerOnHours?: number
|
|
||||||
powerCycles?: number
|
|
||||||
attributes?: SmartAttribute[]
|
|
||||||
updated: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to format capacity display
|
// Function to format capacity display
|
||||||
function formatCapacity(bytes: number): string {
|
function formatCapacity(bytes: number): string {
|
||||||
const { value, unit } = formatBytes(bytes)
|
const { value, unit } = formatBytes(bytes)
|
||||||
return `${toFixedFloat(value, value >= 10 ? 1 : 2)} ${unit}`
|
return `${toFixedFloat(value, value >= 10 ? 1 : 2)} ${unit}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to convert SmartDeviceRecord to DiskInfo
|
|
||||||
function convertSmartDeviceRecordToDiskInfo(records: SmartDeviceRecord[]): DiskInfo[] {
|
|
||||||
const unknown = "Unknown"
|
|
||||||
return records.map((record) => ({
|
|
||||||
id: record.id,
|
|
||||||
system: record.system,
|
|
||||||
device: record.name || unknown,
|
|
||||||
model: record.model || unknown,
|
|
||||||
serialNumber: record.serial || unknown,
|
|
||||||
firmwareVersion: record.firmware || unknown,
|
|
||||||
capacity: record.capacity ? formatCapacity(record.capacity) : unknown,
|
|
||||||
status: record.state || unknown,
|
|
||||||
temperature: record.temp || 0,
|
|
||||||
deviceType: record.type || unknown,
|
|
||||||
attributes: record.attributes,
|
|
||||||
updated: record.updated,
|
|
||||||
powerOnHours: record.hours,
|
|
||||||
powerCycles: record.cycles,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const SMART_DEVICE_FIELDS = "id,system,name,model,state,capacity,temp,type,hours,cycles,updated"
|
const SMART_DEVICE_FIELDS = "id,system,name,model,state,capacity,temp,type,hours,cycles,updated"
|
||||||
|
|
||||||
export const columns: ColumnDef<DiskInfo>[] = [
|
export const columns: ColumnDef<SmartDeviceRecord>[] = [
|
||||||
{
|
{
|
||||||
id: "system",
|
id: "system",
|
||||||
accessorFn: (record) => record.system,
|
accessorFn: (record) => record.system,
|
||||||
@@ -154,12 +118,12 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "device",
|
accessorKey: "name",
|
||||||
sortingFn: (a, b) => a.original.device.localeCompare(b.original.device),
|
sortingFn: (a, b) => a.original.name.localeCompare(b.original.name),
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Device`} Icon={HardDrive} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Device`} Icon={HardDrive} />,
|
||||||
cell: ({ row }) => (
|
cell: ({ getValue }) => (
|
||||||
<div className="font-medium max-w-40 truncate ms-1.5" title={row.getValue("device")}>
|
<div className="font-medium max-w-40 truncate ms-1.5" title={getValue() as string}>
|
||||||
{row.getValue("device")}
|
{getValue() as string}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -167,19 +131,20 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
accessorKey: "model",
|
accessorKey: "model",
|
||||||
sortingFn: (a, b) => a.original.model.localeCompare(b.original.model),
|
sortingFn: (a, b) => a.original.model.localeCompare(b.original.model),
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Model`} Icon={Box} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Model`} Icon={Box} />,
|
||||||
cell: ({ row }) => (
|
cell: ({ getValue }) => (
|
||||||
<div className="max-w-48 truncate ms-1.5" title={row.getValue("model")}>
|
<div className="max-w-48 truncate ms-1.5" title={getValue() as string}>
|
||||||
{row.getValue("model")}
|
{getValue() as string}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "capacity",
|
accessorKey: "capacity",
|
||||||
|
invertSorting: true,
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Capacity`} Icon={BinaryIcon} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Capacity`} Icon={BinaryIcon} />,
|
||||||
cell: ({ getValue }) => <span className="ms-1.5">{getValue() as string}</span>,
|
cell: ({ getValue }) => <span className="ms-1.5">{formatCapacity(getValue() as number)}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "status",
|
accessorKey: "state",
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Status`} Icon={Activity} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Status`} Icon={Activity} />,
|
||||||
cell: ({ getValue }) => {
|
cell: ({ getValue }) => {
|
||||||
const status = getValue() as string
|
const status = getValue() as string
|
||||||
@@ -191,8 +156,8 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "deviceType",
|
accessorKey: "type",
|
||||||
sortingFn: (a, b) => a.original.deviceType.localeCompare(b.original.deviceType),
|
sortingFn: (a, b) => a.original.type.localeCompare(b.original.type),
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Type`} Icon={ArrowLeftRightIcon} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Type`} Icon={ArrowLeftRightIcon} />,
|
||||||
cell: ({ getValue }) => (
|
cell: ({ getValue }) => (
|
||||||
<div className="ms-1.5">
|
<div className="ms-1.5">
|
||||||
@@ -203,7 +168,7 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "powerOnHours",
|
accessorKey: "hours",
|
||||||
invertSorting: true,
|
invertSorting: true,
|
||||||
header: ({ column }) => (
|
header: ({ column }) => (
|
||||||
<HeaderButton column={column} name={t({ message: "Power On", comment: "Power On Time" })} Icon={Clock} />
|
<HeaderButton column={column} name={t({ message: "Power On", comment: "Power On Time" })} Icon={Clock} />
|
||||||
@@ -223,7 +188,7 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "powerCycles",
|
accessorKey: "cycles",
|
||||||
invertSorting: true,
|
invertSorting: true,
|
||||||
header: ({ column }) => (
|
header: ({ column }) => (
|
||||||
<HeaderButton column={column} name={t({ message: "Cycles", comment: "Power Cycles" })} Icon={RotateCwIcon} />
|
<HeaderButton column={column} name={t({ message: "Cycles", comment: "Power Cycles" })} Icon={RotateCwIcon} />
|
||||||
@@ -237,7 +202,7 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "temperature",
|
accessorKey: "temp",
|
||||||
invertSorting: true,
|
invertSorting: true,
|
||||||
header: ({ column }) => <HeaderButton column={column} name={t`Temp`} Icon={ThermometerIcon} />,
|
header: ({ column }) => <HeaderButton column={column} name={t`Temp`} Icon={ThermometerIcon} />,
|
||||||
cell: ({ getValue }) => {
|
cell: ({ getValue }) => {
|
||||||
@@ -246,14 +211,14 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// accessorKey: "serialNumber",
|
// accessorKey: "serial",
|
||||||
// sortingFn: (a, b) => a.original.serialNumber.localeCompare(b.original.serialNumber),
|
// sortingFn: (a, b) => a.original.serial.localeCompare(b.original.serial),
|
||||||
// header: ({ column }) => <HeaderButton column={column} name={t`Serial Number`} Icon={HashIcon} />,
|
// header: ({ column }) => <HeaderButton column={column} name={t`Serial Number`} Icon={HashIcon} />,
|
||||||
// cell: ({ getValue }) => <span className="ms-1.5">{getValue() as string}</span>,
|
// cell: ({ getValue }) => <span className="ms-1.5">{getValue() as string}</span>,
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// accessorKey: "firmwareVersion",
|
// accessorKey: "firmware",
|
||||||
// sortingFn: (a, b) => a.original.firmwareVersion.localeCompare(b.original.firmwareVersion),
|
// sortingFn: (a, b) => a.original.firmware.localeCompare(b.original.firmware),
|
||||||
// header: ({ column }) => <HeaderButton column={column} name={t`Firmware`} Icon={CpuIcon} />,
|
// header: ({ column }) => <HeaderButton column={column} name={t`Firmware`} Icon={CpuIcon} />,
|
||||||
// cell: ({ getValue }) => <span className="ms-1.5">{getValue() as string}</span>,
|
// cell: ({ getValue }) => <span className="ms-1.5">{getValue() as string}</span>,
|
||||||
// },
|
// },
|
||||||
@@ -272,7 +237,15 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function HeaderButton({ column, name, Icon }: { column: Column<DiskInfo>; name: string; Icon: React.ElementType }) {
|
function HeaderButton({
|
||||||
|
column,
|
||||||
|
name,
|
||||||
|
Icon,
|
||||||
|
}: {
|
||||||
|
column: Column<SmartDeviceRecord>
|
||||||
|
name: string
|
||||||
|
Icon: React.ElementType
|
||||||
|
}) {
|
||||||
const isSorted = column.getIsSorted()
|
const isSorted = column.getIsSorted()
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
@@ -290,7 +263,7 @@ function HeaderButton({ column, name, Icon }: { column: Column<DiskInfo>; name:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function DisksTable({ systemId }: { systemId?: string }) {
|
export default function DisksTable({ systemId }: { systemId?: string }) {
|
||||||
const [sorting, setSorting] = useState<SortingState>([{ id: systemId ? "device" : "system", desc: false }])
|
const [sorting, setSorting] = useState<SortingState>([{ id: systemId ? "name" : "system", desc: false }])
|
||||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
||||||
const [rowSelection, setRowSelection] = useState({})
|
const [rowSelection, setRowSelection] = useState({})
|
||||||
const [smartDevices, setSmartDevices] = useState<SmartDeviceRecord[] | undefined>(undefined)
|
const [smartDevices, setSmartDevices] = useState<SmartDeviceRecord[] | undefined>(undefined)
|
||||||
@@ -299,96 +272,95 @@ export default function DisksTable({ systemId }: { systemId?: string }) {
|
|||||||
const [rowActionState, setRowActionState] = useState<{ type: "refresh" | "delete"; id: string } | null>(null)
|
const [rowActionState, setRowActionState] = useState<{ type: "refresh" | "delete"; id: string } | null>(null)
|
||||||
const [globalFilter, setGlobalFilter] = useState("")
|
const [globalFilter, setGlobalFilter] = useState("")
|
||||||
|
|
||||||
const openSheet = (disk: DiskInfo) => {
|
const openSheet = (disk: SmartDeviceRecord) => {
|
||||||
setActiveDiskId(disk.id)
|
setActiveDiskId(disk.id)
|
||||||
setSheetOpen(true)
|
setSheetOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch smart devices from collection (without attributes to save bandwidth)
|
// Fetch smart devices
|
||||||
const fetchSmartDevices = useCallback(() => {
|
useEffect(() => {
|
||||||
|
const controller = new AbortController()
|
||||||
|
|
||||||
pb.collection<SmartDeviceRecord>("smart_devices")
|
pb.collection<SmartDeviceRecord>("smart_devices")
|
||||||
.getFullList({
|
.getFullList({
|
||||||
filter: systemId ? pb.filter("system = {:system}", { system: systemId }) : undefined,
|
filter: systemId ? pb.filter("system = {:system}", { system: systemId }) : undefined,
|
||||||
fields: SMART_DEVICE_FIELDS,
|
fields: SMART_DEVICE_FIELDS,
|
||||||
|
signal: controller.signal,
|
||||||
})
|
})
|
||||||
.then((records) => {
|
.then(setSmartDevices)
|
||||||
setSmartDevices(records)
|
.catch((err) => {
|
||||||
|
if (!err.isAbort) {
|
||||||
|
setSmartDevices([])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => setSmartDevices([]))
|
|
||||||
|
return () => controller.abort()
|
||||||
}, [systemId])
|
}, [systemId])
|
||||||
|
|
||||||
// Fetch smart devices when component mounts or systemId changes
|
// Subscribe to updates
|
||||||
useEffect(() => {
|
|
||||||
fetchSmartDevices()
|
|
||||||
}, [fetchSmartDevices])
|
|
||||||
|
|
||||||
// Subscribe to live updates so rows add/remove without manual refresh/filtering
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let unsubscribe: (() => void) | undefined
|
let unsubscribe: (() => void) | undefined
|
||||||
const pbOptions = systemId
|
const pbOptions = systemId
|
||||||
? { fields: SMART_DEVICE_FIELDS, filter: pb.filter("system = {:system}", { system: systemId }) }
|
? { fields: SMART_DEVICE_FIELDS, filter: pb.filter("system = {:system}", { system: systemId }) }
|
||||||
: { fields: SMART_DEVICE_FIELDS }
|
: { fields: SMART_DEVICE_FIELDS }
|
||||||
|
|
||||||
;(async () => {
|
; (async () => {
|
||||||
try {
|
try {
|
||||||
unsubscribe = await pb.collection("smart_devices").subscribe(
|
unsubscribe = await pb.collection("smart_devices").subscribe(
|
||||||
"*",
|
"*",
|
||||||
(event) => {
|
(event) => {
|
||||||
const record = event.record as SmartDeviceRecord
|
const record = event.record as SmartDeviceRecord
|
||||||
setSmartDevices((currentDevices) => {
|
setSmartDevices((currentDevices) => {
|
||||||
const devices = currentDevices ?? []
|
const devices = currentDevices ?? []
|
||||||
const matchesSystemScope = !systemId || record.system === systemId
|
const matchesSystemScope = !systemId || record.system === systemId
|
||||||
|
|
||||||
if (event.action === "delete") {
|
if (event.action === "delete") {
|
||||||
return devices.filter((device) => device.id !== record.id)
|
return devices.filter((device) => device.id !== record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matchesSystemScope) {
|
if (!matchesSystemScope) {
|
||||||
// Record moved out of scope; ensure it disappears locally.
|
// Record moved out of scope; ensure it disappears locally.
|
||||||
return devices.filter((device) => device.id !== record.id)
|
return devices.filter((device) => device.id !== record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingIndex = devices.findIndex((device) => device.id === record.id)
|
const existingIndex = devices.findIndex((device) => device.id === record.id)
|
||||||
if (existingIndex === -1) {
|
if (existingIndex === -1) {
|
||||||
return [record, ...devices]
|
return [record, ...devices]
|
||||||
}
|
}
|
||||||
|
|
||||||
const next = [...devices]
|
const next = [...devices]
|
||||||
next[existingIndex] = record
|
next[existingIndex] = record
|
||||||
return next
|
return next
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
pbOptions
|
pbOptions
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to subscribe to SMART device updates:", error)
|
console.error("Failed to subscribe to SMART device updates:", error)
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe?.()
|
unsubscribe?.()
|
||||||
}
|
}
|
||||||
}, [systemId])
|
}, [systemId])
|
||||||
|
|
||||||
const handleRowRefresh = useCallback(
|
const handleRowRefresh = useCallback(async (disk: SmartDeviceRecord) => {
|
||||||
async (disk: DiskInfo) => {
|
if (!disk.system) return
|
||||||
if (!disk.system) return
|
setRowActionState({ type: "refresh", id: disk.id })
|
||||||
setRowActionState({ type: "refresh", id: disk.id })
|
try {
|
||||||
try {
|
await pb.send("/api/beszel/smart/refresh", {
|
||||||
await pb.send("/api/beszel/smart/refresh", {
|
method: "POST",
|
||||||
method: "POST",
|
query: { system: disk.system },
|
||||||
query: { system: disk.system },
|
})
|
||||||
})
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error("Failed to refresh SMART device:", error)
|
||||||
console.error("Failed to refresh SMART device:", error)
|
} finally {
|
||||||
} finally {
|
setRowActionState((state) => (state?.id === disk.id ? null : state))
|
||||||
setRowActionState((state) => (state?.id === disk.id ? null : state))
|
}
|
||||||
}
|
}, [])
|
||||||
},
|
|
||||||
[fetchSmartDevices]
|
|
||||||
)
|
|
||||||
|
|
||||||
const handleDeleteDevice = useCallback(async (disk: DiskInfo) => {
|
const handleDeleteDevice = useCallback(async (disk: SmartDeviceRecord) => {
|
||||||
setRowActionState({ type: "delete", id: disk.id })
|
setRowActionState({ type: "delete", id: disk.id })
|
||||||
try {
|
try {
|
||||||
await pb.collection("smart_devices").delete(disk.id)
|
await pb.collection("smart_devices").delete(disk.id)
|
||||||
@@ -400,7 +372,7 @@ export default function DisksTable({ systemId }: { systemId?: string }) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const actionColumn = useMemo<ColumnDef<DiskInfo>>(
|
const actionColumn = useMemo<ColumnDef<SmartDeviceRecord>>(
|
||||||
() => ({
|
() => ({
|
||||||
id: "actions",
|
id: "actions",
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
@@ -468,13 +440,8 @@ export default function DisksTable({ systemId }: { systemId?: string }) {
|
|||||||
return [...baseColumns, actionColumn]
|
return [...baseColumns, actionColumn]
|
||||||
}, [systemId, actionColumn])
|
}, [systemId, actionColumn])
|
||||||
|
|
||||||
// Convert SmartDeviceRecord to DiskInfo
|
|
||||||
const diskData = useMemo(() => {
|
|
||||||
return smartDevices ? convertSmartDeviceRecordToDiskInfo(smartDevices) : []
|
|
||||||
}, [smartDevices])
|
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data: diskData,
|
data: smartDevices || ([] as SmartDeviceRecord[]),
|
||||||
columns: tableColumns,
|
columns: tableColumns,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
@@ -492,10 +459,10 @@ export default function DisksTable({ systemId }: { systemId?: string }) {
|
|||||||
globalFilterFn: (row, _columnId, filterValue) => {
|
globalFilterFn: (row, _columnId, filterValue) => {
|
||||||
const disk = row.original
|
const disk = row.original
|
||||||
const systemName = $allSystemsById.get()[disk.system]?.name ?? ""
|
const systemName = $allSystemsById.get()[disk.system]?.name ?? ""
|
||||||
const device = disk.device ?? ""
|
const device = disk.name ?? ""
|
||||||
const model = disk.model ?? ""
|
const model = disk.model ?? ""
|
||||||
const status = disk.status ?? ""
|
const status = disk.state ?? ""
|
||||||
const type = disk.deviceType ?? ""
|
const type = disk.type ?? ""
|
||||||
const searchString = `${systemName} ${device} ${model} ${status} ${type}`.toLowerCase()
|
const searchString = `${systemName} ${device} ${model} ${status} ${type}`.toLowerCase()
|
||||||
return (filterValue as string)
|
return (filterValue as string)
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
@@ -505,7 +472,7 @@ export default function DisksTable({ systemId }: { systemId?: string }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Hide the table on system pages if there's no data, but always show on global page
|
// Hide the table on system pages if there's no data, but always show on global page
|
||||||
if (systemId && !diskData.length && !columnFilters.length) {
|
if (systemId && !smartDevices?.length && !columnFilters.length) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -287,12 +287,12 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef<Syste
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconColor = pct < 10 ? "text-red-500" : pct < 25 ? "text-yellow-500" : "text-muted-foreground"
|
|
||||||
|
|
||||||
let Icon = PlugChargingIcon
|
let Icon = PlugChargingIcon
|
||||||
|
let iconColor = "text-muted-foreground"
|
||||||
|
|
||||||
if (state !== BatteryState.Charging) {
|
if (state !== BatteryState.Charging) {
|
||||||
if (pct < 25) {
|
if (pct < 25) {
|
||||||
|
iconColor = pct < 11 ? "text-red-500" : "text-yellow-500"
|
||||||
Icon = BatteryLowIcon
|
Icon = BatteryLowIcon
|
||||||
} else if (pct < 75) {
|
} else if (pct < 75) {
|
||||||
Icon = BatteryMediumIcon
|
Icon = BatteryMediumIcon
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export function BatteryMediumIcon(props: SVGProps<SVGSVGElement>) {
|
|||||||
export function BatteryLowIcon(props: SVGProps<SVGSVGElement>) {
|
export function BatteryLowIcon(props: SVGProps<SVGSVGElement>) {
|
||||||
return (
|
return (
|
||||||
<svg viewBox="0 0 24 24" {...props} fill="currentColor">
|
<svg viewBox="0 0 24 24" {...props} fill="currentColor">
|
||||||
<path d="M16 20H8V6h8m.67-2H15V2H9v2H7.33C6.6 4 6 4.6 6 5.33v15.34C6 21.4 6.6 22 7.33 22h9.34c.74 0 1.33-.59 1.33-1.33V5.33C18 4.6 17.4 4 16.67 4M15 16H9v3h6zm0-4.5H9v3h6z" />
|
<path d="M16 17H8V6h8m.7-2H15V2H9v2H7.3A1.3 1.3 0 0 0 6 5.3v15.4q.1 1.2 1.3 1.3h9.4a1.3 1.3 0 0 0 1.3-1.3V5.3q-.1-1.2-1.3-1.3" />
|
||||||
</svg>
|
</svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export function getLocale() {
|
|||||||
}
|
}
|
||||||
locale = (locale || "en").split("-")[0]
|
locale = (locale || "en").split("-")[0]
|
||||||
// use en if locale is not in languages
|
// use en if locale is not in languages
|
||||||
if (!languages.some((l) => l.lang === locale)) {
|
if (!languages.some((l) => l[0] === locale)) {
|
||||||
locale = "en"
|
locale = "en"
|
||||||
}
|
}
|
||||||
return locale
|
return locale
|
||||||
|
|||||||
@@ -1,147 +1,32 @@
|
|||||||
export default [
|
export default [
|
||||||
{
|
["ar", "العربية", "🇵🇸"],
|
||||||
lang: "ar",
|
["bg", "Български", "🇧🇬"],
|
||||||
label: "العربية",
|
["cs", "Čeština", "🇨🇿"],
|
||||||
e: "🇵🇸",
|
["da", "Dansk", "🇩🇰"],
|
||||||
},
|
["de", "Deutsch", "🇩🇪"],
|
||||||
{
|
["en", "English", "🇬🇧"],
|
||||||
lang: "bg",
|
["es", "Español", "🇪🇸"],
|
||||||
label: "Български",
|
["fa", "فارسی", "🇮🇷"],
|
||||||
e: "🇧🇬",
|
["fr", "Français", "🇫🇷"],
|
||||||
},
|
["he", "עברית", "🕎"],
|
||||||
{
|
["hr", "Hrvatski", "🇭🇷"],
|
||||||
lang: "cs",
|
["hu", "Magyar", "🇭🇺"],
|
||||||
label: "Čeština",
|
["id", "Indonesia", "🇮🇩"],
|
||||||
e: "🇨🇿",
|
["it", "Italiano", "🇮🇹"],
|
||||||
},
|
["ja", "日本語", "🇯🇵"],
|
||||||
{
|
["ko", "한국어", "🇰🇷"],
|
||||||
lang: "da",
|
["nl", "Nederlands", "🇳🇱"],
|
||||||
label: "Dansk",
|
["no", "Norsk", "🇳🇴"],
|
||||||
e: "🇩🇰",
|
["pl", "Polski", "🇵🇱"],
|
||||||
},
|
["pt", "Português", "🇵🇹"],
|
||||||
{
|
["ru", "Русский", "🇷🇺"],
|
||||||
lang: "de",
|
["sl", "Slovenščina", "🇸🇮"],
|
||||||
label: "Deutsch",
|
["sr", "Српски", "🇷🇸"],
|
||||||
e: "🇩🇪",
|
["sv", "Svenska", "🇸🇪"],
|
||||||
},
|
["tr", "Türkçe", "🇹🇷"],
|
||||||
{
|
["uk", "Українська", "🇺🇦"],
|
||||||
lang: "en",
|
["vi", "Tiếng Việt", "🇻🇳"],
|
||||||
label: "English",
|
["zh-CN", "简体中文", "🇨🇳"],
|
||||||
e: "🇺🇸",
|
["zh-HK", "繁體中文", "🇭🇰"],
|
||||||
},
|
["zh", "繁體中文", "🇹🇼"],
|
||||||
{
|
|
||||||
lang: "es",
|
|
||||||
label: "Español",
|
|
||||||
e: "🇲🇽",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "fa",
|
|
||||||
label: "فارسی",
|
|
||||||
e: "🇮🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "fr",
|
|
||||||
label: "Français",
|
|
||||||
e: "🇫🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "he",
|
|
||||||
label: "עברית",
|
|
||||||
e: "🕎",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "hr",
|
|
||||||
label: "Hrvatski",
|
|
||||||
e: "🇭🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "hu",
|
|
||||||
label: "Magyar",
|
|
||||||
e: "🇭🇺",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "it",
|
|
||||||
label: "Italiano",
|
|
||||||
e: "🇮🇹",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "ja",
|
|
||||||
label: "日本語",
|
|
||||||
e: "🇯🇵",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "ko",
|
|
||||||
label: "한국어",
|
|
||||||
e: "🇰🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "nl",
|
|
||||||
label: "Nederlands",
|
|
||||||
e: "🇳🇱",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "no",
|
|
||||||
label: "Norsk",
|
|
||||||
e: "🇳🇴",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "pl",
|
|
||||||
label: "Polski",
|
|
||||||
e: "🇵🇱",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "pt",
|
|
||||||
label: "Português",
|
|
||||||
e: "🇧🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "ru",
|
|
||||||
label: "Русский",
|
|
||||||
e: "🇷🇺",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "sl",
|
|
||||||
label: "Slovenščina",
|
|
||||||
e: "🇸🇮",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "sr",
|
|
||||||
label: "Српски",
|
|
||||||
e: "🇷🇸",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "sv",
|
|
||||||
label: "Svenska",
|
|
||||||
e: "🇸🇪",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "tr",
|
|
||||||
label: "Türkçe",
|
|
||||||
e: "🇹🇷",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "uk",
|
|
||||||
label: "Українська",
|
|
||||||
e: "🇺🇦",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "vi",
|
|
||||||
label: "Tiếng Việt",
|
|
||||||
e: "🇻🇳",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "zh-CN",
|
|
||||||
label: "简体中文",
|
|
||||||
e: "🇨🇳",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "zh-HK",
|
|
||||||
label: "繁體中文",
|
|
||||||
e: "🇭🇰",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lang: "zh",
|
|
||||||
label: "繁體中文",
|
|
||||||
e: "🇹🇼",
|
|
||||||
},
|
|
||||||
] as const
|
] as const
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-25 19:15\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Arabic\n"
|
"Language-Team: Arabic\n"
|
||||||
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
|
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "تم تحديد {0} من {1} صف"
|
msgstr "تم تحديد {0} من {1} صف"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# نواة} other {# نواة}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} يوم} other {{countString} أيام}}"
|
msgstr "{count, plural, one {{countString} يوم} other {{countString} أيام}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} ساعة} other {{countString} ساع
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} دقيقة} few {{countString} دقائق} many {{countString} دقيقة} other {{countString} دقيقة}}"
|
msgstr "{count, plural, one {{countString} دقيقة} few {{countString} دقائق} many {{countString} دقيقة} other {{countString} دقيقة}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# خيط} other {# خيط}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 ساعة"
|
msgstr "1 ساعة"
|
||||||
@@ -182,6 +190,11 @@ msgstr "متوسط"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "متوسط استخدام وحدة المعالجة المركزية للحاويات"
|
msgstr "متوسط استخدام وحدة المعالجة المركزية للحاويات"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "المتوسط ينخفض أقل من <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "النسخ الاحتياطية"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "عرض النطاق الترددي"
|
msgstr "عرض النطاق الترددي"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "بطارية"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "البطارية"
|
msgstr "البطارية"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "أصبح غير نشط"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "قبل"
|
msgstr "قبل"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "أقل من {0}{1} في آخر {2, plural, one {# دقيقة} other {# دقائق}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "يدعم بيزيل بروتوكول OpenID Connect والعديد من مزوّدي المصادقة عبر بروتوكول OAuth2."
|
msgstr "يدعم بيزيل بروتوكول OpenID Connect والعديد من مزوّدي المصادقة عبر بروتوكول OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "التوثيق"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -594,7 +620,7 @@ msgstr "تعديل"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Edit {foo}"
|
msgid "Edit {foo}"
|
||||||
msgstr ""
|
msgstr "إضافة {foo}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
@@ -628,6 +654,10 @@ msgstr "أدخل عنوان البريد الإشباكي..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "أدخل كلمة المرور لمرة واحدة الخاصة بك."
|
msgstr "أدخل كلمة المرور لمرة واحدة الخاصة بك."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "مؤقت"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "سيتم حذف الأنظمة الحالية غير المعرفة في
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "خرج نشطًا"
|
msgstr "خرج نشطًا"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "ينتهي بعد ساعة واحدة أو عند إعادة تشغيل المحور."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "تصدير"
|
msgstr "تصدير"
|
||||||
@@ -803,11 +837,6 @@ msgstr "غير نشط"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "عنوان البريد الإشباكي غير صالح."
|
msgstr "عنوان البريد الإشباكي غير صالح."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "النواة"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "اللغة"
|
msgstr "اللغة"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "الحد الأقصى دقيقة"
|
msgstr "الحد الأقصى دقيقة"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "متوسط الاستخدام لكل نواة"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "النسبة المئوية للوقت المقضي في كل حالة"
|
msgstr "النسبة المئوية للوقت المقضي في كل حالة"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "دائم"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "الاستمرارية"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "يرجى <0>تكوين خادم SMTP</0> لضمان تسليم التنبيهات."
|
msgstr "يرجى <0>تكوين خادم SMTP</0> لضمان تسليم التنبيهات."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "حفظ الإعدادات"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "احفظ النظام"
|
msgstr "احفظ النظام"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "محفوظ في قاعدة البيانات ولا ينتهي حتى تقوم بتعطيله."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "جدولة"
|
msgstr "جدولة"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "تنسيق الوقت"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "إلى البريد الإشباكي"
|
msgstr "إلى البريد الإشباكي"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "تبديل الشبكة"
|
msgstr "تبديل الشبكة"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "يتم التفعيل عندما يتجاوز متوسط التحميل
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "يتم التفعيل عندما يتجاوز أي مستشعر عتبة معينة"
|
msgstr "يتم التفعيل عندما يتجاوز أي مستشعر عتبة معينة"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "يتم التفعيل عندما تنخفض شحنة البطارية أقل من عتبة معينة"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "يتم التفعيل عندما يتجاوز الجمع بين الصعود/الهبوط عتبة معينة"
|
msgstr "يتم التفعيل عندما يتجاوز الجمع بين الصعود/الهبوط عتبة معينة"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "غير محدود"
|
msgstr "غير محدود"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "قيد التشغيل"
|
msgstr "قيد التشغيل"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "يتم التحديث كل 10 دقائق."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "رفع"
|
msgstr "رفع"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "مدة التشغيل"
|
msgstr "مدة التشغيل"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "إشعارات Webhook / Push"
|
msgstr "إشعارات Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "عند التفعيل، يسمح هذا الرمز المميز للوكلاء بالتسجيل الذاتي دون إنشاء نظام مسبق. ينتهي بعد ساعة واحدة أو عند إعادة تشغيل المحور."
|
msgstr "عند التفعيل، يسمح هذا الرمز المميز للوكلاء بالتسجيل الذاتي دون إنشاء نظام مسبق."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: bg\n"
|
"Language: bg\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:17\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Bulgarian\n"
|
"Language-Team: Bulgarian\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} от {1} селектирани."
|
msgstr "{0} от {1} селектирани."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# ядро} other {# ядра}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} ден} other {{countString} дни}}"
|
msgstr "{count, plural, one {{countString} ден} other {{countString} дни}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} час} other {{countString} часа
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} минута} few {{countString} минути} many {{countString} минути} other {{countString} минути}}"
|
msgstr "{count, plural, one {{countString} минута} few {{countString} минути} many {{countString} минути} other {{countString} минути}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# нишка} other {# нишки}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 час"
|
msgstr "1 час"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Средно"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Средно използване на процесора на контейнерите"
|
msgstr "Средно използване на процесора на контейнерите"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Средната стойност пада под <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Архиви"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bandwidth на мрежата"
|
msgstr "Bandwidth на мрежата"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Батерия"
|
msgstr "Батерия"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Стана неактивен"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Преди"
|
msgstr "Преди"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Под {0}{1} в последните {2, plural, one {# минута} other {# минути}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel поддържа OpenID Connect и много други OAuth2 доставчици за удостоверяване."
|
msgstr "Beszel поддържа OpenID Connect и много други OAuth2 доставчици за удостоверяване."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Документация"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Въведи имейл адрес..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Въведете Вашата еднократна парола."
|
msgstr "Въведете Вашата еднократна парола."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Ефимерен"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Съществуващи системи които не са дефин
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Излезе активно"
|
msgstr "Излезе активно"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Изтича след един час или при рестартиране на хъба."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Експортиране"
|
msgstr "Експортиране"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Неактивен"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Невалиден имейл адрес."
|
msgstr "Невалиден имейл адрес."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Linux Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Език"
|
msgstr "Език"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Максимум 1 минута"
|
msgstr "Максимум 1 минута"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Средно използване на ядро"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Процент време, прекарано във всяко състояние"
|
msgstr "Процент време, прекарано във всяко състояние"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Постоянен"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Устойчивост"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Моля <0>конфигурурай SMTP сървър</0> за да се подсигуриш, че тревогите са доставени."
|
msgstr "Моля <0>конфигурурай SMTP сървър</0> за да се подсигуриш, че тревогите са доставени."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Запази настройките"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Запази система"
|
msgstr "Запази система"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Запазен е в базата данни и не изтича, докато не го деактивирате."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "График"
|
msgstr "График"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Формат на времето"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "До имейл(ите)"
|
msgstr "До имейл(ите)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Превключване на мрежа"
|
msgstr "Превключване на мрежа"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Задейства се, когато употребата на паме
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Задейства се, когато някой даден сензор надвиши зададен праг"
|
msgstr "Задейства се, когато някой даден сензор надвиши зададен праг"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Задейства се, когато зарядът на батерията падне под зададен праг"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Задейства се, когато комбинираното качване/сваляне надвиши зададен праг"
|
msgstr "Задейства се, когато комбинираното качване/сваляне надвиши зададен праг"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Неограничено"
|
msgstr "Неограничено"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Нагоре"
|
msgstr "Нагоре"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Актуализира се на всеки 10 минути."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Качване"
|
msgstr "Качване"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Време на работа"
|
msgstr "Време на работа"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Пуш нотификации"
|
msgstr "Webhook / Пуш нотификации"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Когато е активиран, този символ позволява на агентите да се регистрират сами без предварително създаване на система. Изтича след един час или при рестартиране на хъба."
|
msgstr "Когато е активиран, този символ позволява на агентите да се регистрират сами без предварително създаване на система."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: cs\n"
|
"Language: cs\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Czech\n"
|
"Language-Team: Czech\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
|
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} z {1} vybraných řádků."
|
msgstr "{0} z {1} vybraných řádků."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# jádro} few {# jádra} many {# jader} other {# jader}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} den} few {{countString} dny} other {{countString} dní}}"
|
msgstr "{count, plural, one {{countString} den} few {{countString} dny} other {{countString} dní}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} Hodina} few {{countString} Hodiny} ma
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
|
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# vlákno} few {# vlákna} many {# vláken} other {# vláken}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 hodina"
|
msgstr "1 hodina"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Průměr"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Průměrné využití CPU kontejnerů"
|
msgstr "Průměrné využití CPU kontejnerů"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Průměr klesne pod <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Zálohy"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Přenos"
|
msgstr "Přenos"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Baterie"
|
msgstr "Baterie"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Stal se neaktivním"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Před"
|
msgstr "Před"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Pod {0}{1} za {2, plural, one {poslední # minutu} few {poslední # minuty} other {posledních # minut}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel podporuje OpenID Connect a mnoho poskytovatelů OAuth2 ověřování."
|
msgstr "Beszel podporuje OpenID Connect a mnoho poskytovatelů OAuth2 ověřování."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentace"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Zadejte e-mailovou adresu..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Zadejte Vaše jednorázové heslo."
|
msgstr "Zadejte Vaše jednorázové heslo."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efemérní"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Stávající systémy, které nejsou definovány v <0>config.yml</0>, bu
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Ukončeno aktivně"
|
msgstr "Ukončeno aktivně"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Vyprší po jedné hodině nebo při restartu hubu."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportovat"
|
msgstr "Exportovat"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Neaktivní"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Neplatná e-mailová adresa."
|
msgstr "Neplatná e-mailová adresa."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Jádro"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Jazyk"
|
msgstr "Jazyk"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max. 1 min"
|
msgstr "Max. 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Průměrné využití na jádro"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Procento času strávěného v každém stavu"
|
msgstr "Procento času strávěného v každém stavu"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Trvalý"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Trvalost"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "<0>nakonfigurujte SMTP server</0> pro zajištění toho, aby byla upozornění doručena."
|
msgstr "<0>nakonfigurujte SMTP server</0> pro zajištění toho, aby byla upozornění doručena."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Uložit nastavení"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Uložit systém"
|
msgstr "Uložit systém"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Uložen v databázi a nevyprší, dokud jej nezablokujete."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Plán"
|
msgstr "Plán"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Formát času"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Na email(y)"
|
msgstr "Na email(y)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Přepnout mřížku"
|
msgstr "Přepnout mřížku"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Spustí se, když využití paměti během 5 minut překročí prahovou
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Spustí se, když některý senzor překročí prahovou hodnotu"
|
msgstr "Spustí se, když některý senzor překročí prahovou hodnotu"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Spustí se, když úroveň nabití baterie klesne pod prahovou hodnotu"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Spustí se, když kombinace up/down překročí prahovou hodnotu"
|
msgstr "Spustí se, když kombinace up/down překročí prahovou hodnotu"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Neomezeno"
|
msgstr "Neomezeno"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Funkční"
|
msgstr "Funkční"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Aktualizováno každých 10 minut."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Odeslání"
|
msgstr "Odeslání"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Doba provozu"
|
msgstr "Doba provozu"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push oznámení"
|
msgstr "Webhook / Push oznámení"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Pokud je povoleno, tento token umožňuje agentům, aby se sami zaregistrovali bez předchozího vytvoření systému. Vyprší po jedné hodině nebo po restartu uzlu."
|
msgstr "Pokud je povoleno, umožňuje tento token agentům samo-registraci bez předchozího vytvoření systému."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: da\n"
|
"Language: da\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-19 10:55\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Danish\n"
|
"Language-Team: Danish\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} af {1} række(r) valgt."
|
msgstr "{0} af {1} række(r) valgt."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# kerne} other {# kerner}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dag} other {{countString} dage}}"
|
msgstr "{count, plural, one {{countString} dag} other {{countString} dage}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} time} other {{countString} timer}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minut} other {{countString} minutter}}"
|
msgstr "{count, plural, one {{countString} minut} other {{countString} minutter}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# tråd} other {# tråde}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 time"
|
msgstr "1 time"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Gennemsnitlig"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Gennemsnitlig CPU udnyttelse af containere"
|
msgstr "Gennemsnitlig CPU udnyttelse af containere"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Gennemsnit falder under <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Sikkerhedskopier"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Båndbredde"
|
msgstr "Båndbredde"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batteri"
|
msgstr "Batteri"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Blev inaktiv"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Før"
|
msgstr "Før"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Under {0}{1} i sidste {2, plural, one {# minut} other {# minutter}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel understøtter OpenID Connect og mange OAuth2 godkendelsesudbydere."
|
msgstr "Beszel understøtter OpenID Connect og mange OAuth2 godkendelsesudbydere."
|
||||||
@@ -442,7 +468,7 @@ msgstr "CPU Peak"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "CPU time"
|
msgid "CPU time"
|
||||||
msgstr ""
|
msgstr "CPU tid"
|
||||||
|
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "CPU Time Breakdown"
|
msgid "CPU Time Breakdown"
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentation"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Indtast e-mailadresse..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Indtast din engangsadgangskode."
|
msgstr "Indtast din engangsadgangskode."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efemer"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -648,7 +678,7 @@ msgstr "Overskrider {0}{1} i sidste {2, plural, one {# minut} other {# minutter}
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Exec main PID"
|
msgid "Exec main PID"
|
||||||
msgstr ""
|
msgstr "Exec vigtigste PID"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
||||||
@@ -658,6 +688,10 @@ msgstr "Eksisterende systemer ikke defineret i <0>config.yml</0> vil blive slett
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Afsluttet aktiv"
|
msgstr "Afsluttet aktiv"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Udløber efter en time eller ved hub-genstart."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Eksporter"
|
msgstr "Eksporter"
|
||||||
@@ -720,7 +754,7 @@ msgstr "Fingeraftryk"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Firmware"
|
msgid "Firmware"
|
||||||
msgstr ""
|
msgstr "Firmware"
|
||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inaktiv"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Ugyldig email adresse."
|
msgstr "Ugyldig email adresse."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kerne"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprog"
|
msgstr "Sprog"
|
||||||
@@ -827,7 +856,7 @@ msgstr "Livscyklus"
|
|||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "limit"
|
msgid "limit"
|
||||||
msgstr ""
|
msgstr "grænse"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Load Average"
|
msgid "Load Average"
|
||||||
@@ -883,7 +912,7 @@ msgstr "Leder du i stedet for efter hvor du kan oprette alarmer? Klik på klokke
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Main PID"
|
msgid "Main PID"
|
||||||
msgstr ""
|
msgstr "Primær PID"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Manage display and notification preferences."
|
msgid "Manage display and notification preferences."
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maks. 1 min"
|
msgstr "Maks. 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -913,7 +943,7 @@ msgstr "Hukommelsesgrænse"
|
|||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Memory Peak"
|
msgid "Memory Peak"
|
||||||
msgstr ""
|
msgstr "Hukommelsesspids"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
@@ -939,7 +969,7 @@ msgstr "Navn"
|
|||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Net"
|
msgid "Net"
|
||||||
msgstr ""
|
msgstr "Net"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Network traffic of docker containers"
|
msgid "Network traffic of docker containers"
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Gennemsnitlig udnyttelse pr. kerne"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Procentdel af tid brugt i hver tilstand"
|
msgstr "Procentdel af tid brugt i hver tilstand"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Vedholdenhed"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Konfigurer <0>en SMTP server</0> for at sikre at alarmer bliver leveret."
|
msgstr "Konfigurer <0>en SMTP server</0> for at sikre at alarmer bliver leveret."
|
||||||
@@ -1208,7 +1246,7 @@ msgstr "Genoptag"
|
|||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgctxt "Root disk label"
|
msgctxt "Root disk label"
|
||||||
msgid "Root"
|
msgid "Root"
|
||||||
msgstr ""
|
msgstr "Root"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Rotate token"
|
msgid "Rotate token"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Gem indstillinger"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Gem system"
|
msgstr "Gem system"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Gemt i databasen og udløber ikke, før du deaktiverer det."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Planlæg"
|
msgstr "Planlæg"
|
||||||
@@ -1366,7 +1408,7 @@ msgstr "Gennemsnitlig system belastning over tid"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Systemd Services"
|
msgid "Systemd Services"
|
||||||
msgstr ""
|
msgstr "Systemd Services"
|
||||||
|
|
||||||
#: src/components/navbar.tsx
|
#: src/components/navbar.tsx
|
||||||
msgid "Systems"
|
msgid "Systems"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Tidsformat"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Til email(s)"
|
msgstr "Til email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Slå gitter til/fra"
|
msgstr "Slå gitter til/fra"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Udløser når 5 minut belastning gennemsnit overstiger en tærskel"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Udløser når en sensor overstiger en tærskel"
|
msgstr "Udløser når en sensor overstiger en tærskel"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Udløses når batteriniveauet falder under en tærskel"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Udløses når de kombinerede op/ned overstiger en tærskel"
|
msgstr "Udløses når de kombinerede op/ned overstiger en tærskel"
|
||||||
@@ -1541,7 +1587,7 @@ msgstr "Type"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Unit file"
|
msgid "Unit file"
|
||||||
msgstr ""
|
msgstr "Enhed fil"
|
||||||
|
|
||||||
#. Temperature / network units
|
#. Temperature / network units
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
@@ -1561,10 +1607,10 @@ msgstr "Ukendt"
|
|||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Unlimited"
|
msgid "Unlimited"
|
||||||
msgstr ""
|
msgstr "Ubegrænset"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Oppe"
|
msgstr "Oppe"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Opdateret hver 10. minut."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Overfør"
|
msgstr "Overfør"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Oppetid"
|
msgstr "Oppetid"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push notifikationer"
|
msgstr "Webhook / Push notifikationer"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Når aktiveret tillader denne nøgle agenter at selvregistrere uden forudgående systemoprettelse. Udløber efter en time eller ved hub-genstart."
|
msgstr "Når aktiveret, tillader denne token agenter at registrere sig selv uden forudgående systemoprettelse."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: German\n"
|
"Language-Team: German\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} von {1} Zeile(n) ausgewählt."
|
msgstr "{0} von {1} Zeile(n) ausgewählt."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# Kern} other {# Kerne}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} Tag} other {{countString} Tage}}"
|
msgstr "{count, plural, one {{countString} Tag} other {{countString} Tage}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} Stunde} other {{countString} Stunden}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} Minute} other {{countString} Minuten}}"
|
msgstr "{count, plural, one {{countString} Minute} other {{countString} Minuten}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# Thread} other {# Threads}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 Stunde"
|
msgstr "1 Stunde"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Durchschnitt"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Durchschnittliche CPU-Auslastung der Container"
|
msgstr "Durchschnittliche CPU-Auslastung der Container"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Durchschnitt unterschreitet <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Backups"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bandbreite"
|
msgstr "Bandbreite"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batterie"
|
msgstr "Batterie"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Wurde inaktiv"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Vor"
|
msgstr "Vor"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Unterschreitet {0}{1} in den letzten {2, plural, one {# Minute} other {# Minuten}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel unterstützt OpenID Connect und viele OAuth2-Authentifizierungsanbieter."
|
msgstr "Beszel unterstützt OpenID Connect und viele OAuth2-Authentifizierungsanbieter."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentation"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "E-Mail-Adresse eingeben..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Geben Sie Ihr Einmalpasswort ein."
|
msgstr "Geben Sie Ihr Einmalpasswort ein."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Flüchtig"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Bestehende Systeme, die nicht in der <0>config.yml</0> definiert sind, w
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Beendet aktiv"
|
msgstr "Beendet aktiv"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Läuft nach einer Stunde oder bei Hub-Neustart ab."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportieren"
|
msgstr "Exportieren"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inaktiv"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Ungültige E-Mail-Adresse."
|
msgstr "Ungültige E-Mail-Adresse."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprache"
|
msgstr "Sprache"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max 1 Min"
|
msgstr "Max 1 Min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Durchschnittliche Auslastung pro Kern"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Prozentsatz der Zeit in jedem Zustand"
|
msgstr "Prozentsatz der Zeit in jedem Zustand"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistenz"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Bitte <0>konfiguriere einen SMTP-Server</0>, um sicherzustellen, dass Warnungen zugestellt werden."
|
msgstr "Bitte <0>konfiguriere einen SMTP-Server</0>, um sicherzustellen, dass Warnungen zugestellt werden."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Einstellungen speichern"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "System speichern"
|
msgstr "System speichern"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "In der Datenbank gespeichert und läuft nicht ab, bis Sie es deaktivieren."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Zeitplan"
|
msgstr "Zeitplan"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Zeitformat"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "An E-Mail(s)"
|
msgstr "An E-Mail(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Raster umschalten"
|
msgstr "Raster umschalten"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Löst aus, wenn der Lastdurchschnitt der letzten 5 Minuten einen Schwell
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet"
|
msgstr "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Löst aus, wenn der Batterieladestand unter einen Schwellenwert fällt"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Löst aus, wenn die kombinierte Up- und Downloadrate einen Schwellenwert überschreitet"
|
msgstr "Löst aus, wenn die kombinierte Up- und Downloadrate einen Schwellenwert überschreitet"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Unbegrenzt"
|
msgstr "Unbegrenzt"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "aktiv"
|
msgstr "aktiv"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Alle 10 Minuten aktualisiert."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Hochladen"
|
msgstr "Hochladen"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Betriebszeit"
|
msgstr "Betriebszeit"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push-Benachrichtigungen"
|
msgstr "Webhook / Push-Benachrichtigungen"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Wenn aktiviert, ermöglicht dieser Token Agents, sich selbst zu registrieren, ohne vorherige Systemerstellung. Läuft nach einer Stunde oder beim Hub-Neustart ab."
|
msgstr "Wenn aktiviert, ermöglicht dieser Token Agenten die Selbstregistrierung ohne vorherige Systemerstellung."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} of {1} row(s) selected."
|
msgstr "{0} of {1} row(s) selected."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgstr "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
@@ -31,6 +35,10 @@ msgstr "{count, plural, one {{countString} hour} other {{countString} hours}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgstr "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 hour"
|
msgstr "1 hour"
|
||||||
@@ -177,6 +185,11 @@ msgstr "Average"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Average CPU utilization of containers"
|
msgstr "Average CPU utilization of containers"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Average drops below <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -209,7 +222,13 @@ msgstr "Backups"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bandwidth"
|
msgstr "Bandwidth"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Battery"
|
msgstr "Battery"
|
||||||
|
|
||||||
@@ -225,6 +244,13 @@ msgstr "Became inactive"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Before"
|
msgstr "Before"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgstr "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
@@ -563,7 +589,7 @@ msgstr "Documentation"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -623,6 +649,10 @@ msgstr "Enter email address..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Enter your one-time password."
|
msgstr "Enter your one-time password."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Ephemeral"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -653,6 +683,10 @@ msgstr "Existing systems not defined in <0>config.yml</0> will be deleted. Pleas
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Exited active"
|
msgstr "Exited active"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Expires after one hour or on hub restart."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Export"
|
msgstr "Export"
|
||||||
@@ -798,11 +832,6 @@ msgstr "Inactive"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Invalid email address."
|
msgstr "Invalid email address."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Language"
|
msgstr "Language"
|
||||||
@@ -895,6 +924,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max 1 min"
|
msgstr "Max 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1082,6 +1112,14 @@ msgstr "Per-core average utilization"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Percentage of time spent in each state"
|
msgstr "Percentage of time spent in each state"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistence"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgstr "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
@@ -1238,6 +1276,10 @@ msgstr "Save Settings"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Save system"
|
msgstr "Save system"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Saved in the database and does not expire until you disable it."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Schedule"
|
msgstr "Schedule"
|
||||||
@@ -1434,8 +1476,8 @@ msgstr "Time format"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "To email(s)"
|
msgstr "To email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Toggle grid"
|
msgstr "Toggle grid"
|
||||||
|
|
||||||
@@ -1504,6 +1546,10 @@ msgstr "Triggers when 5 minute load average exceeds a threshold"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Triggers when any sensor exceeds a threshold"
|
msgstr "Triggers when any sensor exceeds a threshold"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Triggers when battery charge drops below a threshold"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Triggers when combined up/down exceeds a threshold"
|
msgstr "Triggers when combined up/down exceeds a threshold"
|
||||||
@@ -1559,7 +1605,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Unlimited"
|
msgstr "Unlimited"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Up"
|
msgstr "Up"
|
||||||
@@ -1586,7 +1632,7 @@ msgstr "Updated every 10 minutes."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Upload"
|
msgstr "Upload"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Uptime"
|
msgstr "Uptime"
|
||||||
|
|
||||||
@@ -1658,8 +1704,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push notifications"
|
msgstr "Webhook / Push notifications"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgstr "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-12-01 23:32\n"
|
"PO-Revision-Date: 2025-12-14 09:39\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Spanish\n"
|
"Language-Team: Spanish\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} de {1} fila(s) seleccionada(s)."
|
msgstr "{0} de {1} fila(s) seleccionada(s)."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# núcleo} other {# núcleos}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} día} other {{countString} días}}"
|
msgstr "{count, plural, one {{countString} día} other {{countString} días}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} hora} other {{countString} horas}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
|
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# hilo} other {# hilos}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 hora"
|
msgstr "1 hora"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Promedio"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Utilización promedio de CPU de los contenedores"
|
msgstr "Utilización promedio de CPU de los contenedores"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "El promedio cae por debajo de <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Copias de seguridad"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Ancho de banda"
|
msgstr "Ancho de banda"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batería"
|
msgstr "Batería"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Se desactivó"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Antes"
|
msgstr "Antes"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Por debajo de {0}{1} en el último {2, plural, one {# minuto} other {# minutos}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel admite OpenID Connect y muchos proveedores de autenticación OAuth2."
|
msgstr "Beszel admite OpenID Connect y muchos proveedores de autenticación OAuth2."
|
||||||
@@ -331,7 +357,7 @@ msgstr "Verifica tu servicio de notificaciones"
|
|||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
#: src/components/systems-table/systems-table.tsx
|
#: src/components/systems-table/systems-table.tsx
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr ""
|
msgstr "Limpiar"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table.tsx
|
#: src/components/containers-table/containers-table.tsx
|
||||||
msgid "Click on a container to view more information."
|
msgid "Click on a container to view more information."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Documentación"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Ingresa dirección de correo..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Ingrese su contraseña de un solo uso."
|
msgstr "Ingrese su contraseña de un solo uso."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efímero"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Los sistemas existentes no definidos en <0>config.yml</0> serán elimina
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Salió activo"
|
msgstr "Salió activo"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Expira después de una hora o al reiniciar el hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportar"
|
msgstr "Exportar"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inactivo"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Dirección de correo electrónico no válida."
|
msgstr "Dirección de correo electrónico no válida."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Idioma"
|
msgstr "Idioma"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Máx. 1 min"
|
msgstr "Máx. 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Uso promedio por núcleo"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Porcentaje de tiempo dedicado a cada estado"
|
msgstr "Porcentaje de tiempo dedicado a cada estado"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanente"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistencia"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Por favor, <0>configura un servidor SMTP</0> para asegurar que las alertas sean entregadas."
|
msgstr "Por favor, <0>configura un servidor SMTP</0> para asegurar que las alertas sean entregadas."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Guardar configuración"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Guardar sistema"
|
msgstr "Guardar sistema"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Guardado en la base de datos y no expira hasta que lo desactives."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Programar"
|
msgstr "Programar"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Formato de hora"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "A correo(s)"
|
msgstr "A correo(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Alternar cuadrícula"
|
msgstr "Alternar cuadrícula"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Se activa cuando la carga media de 5 minutos supera un umbral"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Se activa cuando cualquier sensor supera un umbral"
|
msgstr "Se activa cuando cualquier sensor supera un umbral"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Se activa cuando la carga de la batería baja de un umbral"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Se activa cuando la suma de subida/bajada supera un umbral"
|
msgstr "Se activa cuando la suma de subida/bajada supera un umbral"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Ilimitado"
|
msgstr "Ilimitado"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Activo"
|
msgstr "Activo"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Actualizado cada 10 minutos."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Cargar"
|
msgstr "Cargar"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Tiempo de actividad"
|
msgstr "Tiempo de actividad"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Notificaciones Webhook / Push"
|
msgstr "Notificaciones Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Cuando está habilitado, este token permite que los agentes se auto-registren sin crear previamente el sistema. Expira después de una hora o al reiniciar el hub."
|
msgstr "Cuando está habilitado, este token permite a los agentes registrarse automáticamente sin creación previa del sistema."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: fa\n"
|
"Language: fa\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Persian\n"
|
"Language-Team: Persian\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} از {1} ردیف انتخاب شده است."
|
msgstr "{0} از {1} ردیف انتخاب شده است."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# هسته} other {# هسته}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} روز} other {{countString} روز}}"
|
msgstr "{count, plural, one {{countString} روز} other {{countString} روز}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} ساعت} other {{countString} ساع
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} دقیقه} few {{countString} دقیقه} many {{countString} دقیقه} other {{countString} دقیقه}}"
|
msgstr "{count, plural, one {{countString} دقیقه} few {{countString} دقیقه} many {{countString} دقیقه} other {{countString} دقیقه}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# رشته} other {# رشته}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "۱ ساعت"
|
msgstr "۱ ساعت"
|
||||||
@@ -182,6 +190,11 @@ msgstr "میانگین"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "میانگین استفاده از CPU کانتینرها"
|
msgstr "میانگین استفاده از CPU کانتینرها"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "میانگین به زیر <0>{value}{0}</0> میافتد"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "پشتیبانگیریها"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "پهنای باند"
|
msgstr "پهنای باند"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "باتری"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "باتری"
|
msgstr "باتری"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "غیرفعال شد"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "قبل از"
|
msgstr "قبل از"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "زیر {0}{1} در آخرین {2, plural, one {# دقیقه} other {# دقیقه}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "بِزل از OpenID Connect و بسیاری از ارائهدهندگان احراز هویت OAuth2 پشتیبانی میکند."
|
msgstr "بِزل از OpenID Connect و بسیاری از ارائهدهندگان احراز هویت OAuth2 پشتیبانی میکند."
|
||||||
@@ -331,7 +357,7 @@ msgstr "سرویس اطلاعرسانی خود را بررسی کنید"
|
|||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
#: src/components/systems-table/systems-table.tsx
|
#: src/components/systems-table/systems-table.tsx
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr ""
|
msgstr "پاک کردن"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table.tsx
|
#: src/components/containers-table/containers-table.tsx
|
||||||
msgid "Click on a container to view more information."
|
msgid "Click on a container to view more information."
|
||||||
@@ -568,7 +594,7 @@ msgstr "مستندات"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "آدرس ایمیل را وارد کنید..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "رمز عبور یکبار مصرف خود را وارد کنید."
|
msgstr "رمز عبور یکبار مصرف خود را وارد کنید."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "گذرا"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -648,7 +678,7 @@ msgstr "در {2, plural, one {# دقیقه} other {# دقیقه}} گذشته ا
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Exec main PID"
|
msgid "Exec main PID"
|
||||||
msgstr ""
|
msgstr "PID اصلی اجرایی"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
||||||
@@ -658,6 +688,10 @@ msgstr "سیستمهای موجود که در <0>config.yml</0> تعریف ن
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "خروج فعال"
|
msgstr "خروج فعال"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "پس از یک ساعت یا راهاندازی مجدد هاب منقضی میشود."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "خروجی گرفتن"
|
msgstr "خروجی گرفتن"
|
||||||
@@ -803,11 +837,6 @@ msgstr "غیرفعال"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "آدرس ایمیل نامعتبر است."
|
msgstr "آدرس ایمیل نامعتبر است."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "هسته"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "زبان"
|
msgstr "زبان"
|
||||||
@@ -827,7 +856,7 @@ msgstr "چرخه حیات"
|
|||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "limit"
|
msgid "limit"
|
||||||
msgstr ""
|
msgstr "محدودیت"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Load Average"
|
msgid "Load Average"
|
||||||
@@ -883,7 +912,7 @@ msgstr "به دنبال جایی برای ایجاد هشدار هستید؟ ر
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Main PID"
|
msgid "Main PID"
|
||||||
msgstr ""
|
msgstr "PID اصلی"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Manage display and notification preferences."
|
msgid "Manage display and notification preferences."
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "حداکثر ۱ دقیقه"
|
msgstr "حداکثر ۱ دقیقه"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "میانگین استفاده در هر هسته"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "درصد زمان صرف شده در هر حالت"
|
msgstr "درصد زمان صرف شده در هر حالت"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "دائمی"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "ماندگاری"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "لطفاً برای اطمینان از تحویل هشدارها، یک <0>سرور SMTP پیکربندی کنید</0>."
|
msgstr "لطفاً برای اطمینان از تحویل هشدارها، یک <0>سرور SMTP پیکربندی کنید</0>."
|
||||||
@@ -1208,7 +1246,7 @@ msgstr "ادامه"
|
|||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgctxt "Root disk label"
|
msgctxt "Root disk label"
|
||||||
msgid "Root"
|
msgid "Root"
|
||||||
msgstr ""
|
msgstr "ریشه"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Rotate token"
|
msgid "Rotate token"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "ذخیره تنظیمات"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "ذخیره سیستم"
|
msgstr "ذخیره سیستم"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "در پایگاه داده ذخیره شده و تا زمانی که آن را غیرفعال نکنید، منقضی نمیشود."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "برنامهریزی"
|
msgstr "برنامهریزی"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "فرمت زمان"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "به ایمیل(ها)"
|
msgstr "به ایمیل(ها)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "تغییر نمایش جدول"
|
msgstr "تغییر نمایش جدول"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "هنگامی که میانگین بار ۵ دقیقهای از یک
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "هنگامی که هر حسگری از یک آستانه فراتر رود، فعال میشود"
|
msgstr "هنگامی که هر حسگری از یک آستانه فراتر رود، فعال میشود"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "زمانی که شارژ باتری زیر آستانه قرار میگیرد، فعال میشود"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "هنگامی که مجموع بالا/پایین از یک آستانه فراتر رود، فعال میشود"
|
msgstr "هنگامی که مجموع بالا/پایین از یک آستانه فراتر رود، فعال میشود"
|
||||||
@@ -1541,7 +1587,7 @@ msgstr "نوع"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Unit file"
|
msgid "Unit file"
|
||||||
msgstr ""
|
msgstr "فایل واحد"
|
||||||
|
|
||||||
#. Temperature / network units
|
#. Temperature / network units
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "نامحدود"
|
msgstr "نامحدود"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "فعال"
|
msgstr "فعال"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "هر ۱۰ دقیقه بهروزرسانی میشود."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "آپلود"
|
msgstr "آپلود"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "آپتایم"
|
msgstr "آپتایم"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "اعلانهای Webhook / Push"
|
msgstr "اعلانهای Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "هنگامی که فعال است، این توکن به عاملها اجازه خودثبتنامی بدون ایجاد سیستم قبلی میدهد. پس از یک ساعت یا در راهاندازی مجدد هاب منقضی میشود."
|
msgstr "هنگامی که فعال باشد، این توکن به عوامل اجازه میدهد بدون ایجاد سیستم قبلی، خود را ثبت کنند."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2026-01-09 21:08\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: French\n"
|
"Language-Team: French\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} sur {1} ligne(s) sélectionnée(s)."
|
msgstr "{0} sur {1} ligne(s) sélectionnée(s)."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# cœur} other {# cœurs}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} jour} other {{countString} jours}}"
|
msgstr "{count, plural, one {{countString} jour} other {{countString} jours}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} heure} other {{countString} heures}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minute} other {{countString} minutes}}"
|
msgstr "{count, plural, one {{countString} minute} other {{countString} minutes}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# fil} other {# fils}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 heure"
|
msgstr "1 heure"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Moyenne"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Utilisation moyenne du CPU des conteneurs"
|
msgstr "Utilisation moyenne du CPU des conteneurs"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "La moyenne descend en dessous de <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Sauvegardes"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bande passante"
|
msgstr "Bande passante"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batterie"
|
msgstr "Batterie"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Devenu inactif"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Avant"
|
msgstr "Avant"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Inférieur à {0}{1} dans {2, plural, one {la dernière # minute} other {les dernières # minutes}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel prend en charge OpenID Connect et de nombreux fournisseurs d'authentification OAuth2."
|
msgstr "Beszel prend en charge OpenID Connect et de nombreux fournisseurs d'authentification OAuth2."
|
||||||
@@ -512,7 +538,7 @@ msgstr "Supprimer l'empreinte"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr ""
|
msgstr "Description"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table.tsx
|
#: src/components/containers-table/containers-table.tsx
|
||||||
msgid "Detail"
|
msgid "Detail"
|
||||||
@@ -568,11 +594,11 @@ msgstr "Documentation"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
msgstr "Injoignable"
|
msgstr "Hors ligne"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table.tsx
|
#: src/components/systems-table/systems-table.tsx
|
||||||
msgid "Down ({downSystemsLength})"
|
msgid "Down ({downSystemsLength})"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Entrez l'adresse email..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Entrez votre mot de passe à usage unique."
|
msgstr "Entrez votre mot de passe à usage unique."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Éphémère"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Les systèmes existants non définis dans <0>config.yml</0> seront suppr
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Sorti actif"
|
msgstr "Sorti actif"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Expire après une heure ou au redémarrage du hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exporter"
|
msgstr "Exporter"
|
||||||
@@ -724,7 +758,7 @@ msgstr "Micrologiciel"
|
|||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
msgstr "Pour <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgstr "Pendant <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Forgot password?"
|
msgid "Forgot password?"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inactif"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Adresse email invalide."
|
msgstr "Adresse email invalide."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Noyau"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Langue"
|
msgstr "Langue"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max 1 min"
|
msgstr "Max 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -939,7 +969,7 @@ msgstr "Nom"
|
|||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Net"
|
msgid "Net"
|
||||||
msgstr "Net"
|
msgstr "Rés"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Network traffic of docker containers"
|
msgid "Network traffic of docker containers"
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Utilisation moyenne par cœur"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Pourcentage de temps passé dans chaque état"
|
msgstr "Pourcentage de temps passé dans chaque état"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistance"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Veuillez <0>configurer un serveur SMTP</0> pour garantir la livraison des alertes."
|
msgstr "Veuillez <0>configurer un serveur SMTP</0> pour garantir la livraison des alertes."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Enregistrer les paramètres"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Sauvegarder le système"
|
msgstr "Sauvegarder le système"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Enregistré dans la base de données et n'expire pas tant que vous ne le désactivez pas."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Programmer"
|
msgstr "Programmer"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Format d'heure"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Aux email(s)"
|
msgstr "Aux email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Basculer la grille"
|
msgstr "Basculer la grille"
|
||||||
|
|
||||||
@@ -1499,16 +1541,20 @@ msgstr "Se déclenche lorsque la charge moyenne sur 1 minute dépasse un seuil"
|
|||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when 15 minute load average exceeds a threshold"
|
msgid "Triggers when 15 minute load average exceeds a threshold"
|
||||||
msgstr "Se déclenche lorsque la charge moyenne sur 15 minute dépasse un seuil"
|
msgstr "Se déclenche lorsque la charge moyenne sur 15 minutes dépasse un seuil"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when 5 minute load average exceeds a threshold"
|
msgid "Triggers when 5 minute load average exceeds a threshold"
|
||||||
msgstr "Se déclenche lorsque la charge moyenne sur 5 minute dépasse un seuil"
|
msgstr "Se déclenche lorsque la charge moyenne sur 5 minutes dépasse un seuil"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Déclenchement lorsque tout capteur dépasse un seuil"
|
msgstr "Déclenchement lorsque tout capteur dépasse un seuil"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Déclenchement lorsque la charge de la batterie descend en dessous d'un seuil"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Déclenchement lorsque le montant/descendant combinée dépasse un seuil"
|
msgstr "Déclenchement lorsque le montant/descendant combinée dépasse un seuil"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Illimité"
|
msgstr "Illimité"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Joignable"
|
msgstr "Joignable"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Mis à jour toutes les 10 minutes."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Téléverser"
|
msgstr "Téléverser"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Temps de fonctionnement"
|
msgstr "Temps de fonctionnement"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Notifications Webhook / Push"
|
msgstr "Notifications Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Lorsqu'il est activé, ce token permet aux agents de s'auto-enregistrer sans création préalable du système. Expire après une heure ou au redémarrage du hub."
|
msgstr "Lorsqu'il est activé, ce jeton permet aux agents de s'enregistrer automatiquement sans création préalable du système."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: he\n"
|
"Language: he\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Hebrew\n"
|
"Language-Team: Hebrew\n"
|
||||||
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
|
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} מתוך {1} שורה(ות) נבחרו."
|
msgstr "{0} מתוך {1} שורה(ות) נבחרו."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# ליבה} other {# ליבות}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} יום} two {{countString} ימים} other {{countString} ימים}}"
|
msgstr "{count, plural, one {{countString} יום} two {{countString} ימים} other {{countString} ימים}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} שעה} two {{countString} שעות}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} דקה} two {{countString} דקות} other {{countString} דקות}}"
|
msgstr "{count, plural, one {{countString} דקה} two {{countString} דקות} other {{countString} דקות}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# תהליכון} other {# תהליכונים}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "שעה"
|
msgstr "שעה"
|
||||||
@@ -182,6 +190,11 @@ msgstr "ממוצע"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "ניצול ממוצע של CPU בקונטיינרים"
|
msgstr "ניצול ממוצע של CPU בקונטיינרים"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "הממוצע יורד מתחת ל-<0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "גיבויים"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "רוחב פס"
|
msgstr "רוחב פס"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "סוללה"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "סוללה"
|
msgstr "סוללה"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "הפך ללא פעיל"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "לפני"
|
msgstr "לפני"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "מתחת ל-{0}{1} ב-{2, plural, one {דקה האחרונה} other {-# הדקות האחרונות}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel תומך ב-OpenID Connect ובספקי אימות רבים של OAuth2."
|
msgstr "Beszel תומך ב-OpenID Connect ובספקי אימות רבים של OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "תיעוד"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "הכנס כתובת אימייל..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "הכנס את הסיסמה החד-פעמית שלך."
|
msgstr "הכנס את הסיסמה החד-פעמית שלך."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "זמני"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "מערכות קיימות שלא מוגדרות ב-<0>config.yml</0> י
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "יצא פעיל"
|
msgstr "יצא פעיל"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "פג תוקף לאחר שעה או בהפעלה מחדש של ה-hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "ייצא"
|
msgstr "ייצא"
|
||||||
@@ -803,11 +837,6 @@ msgstr "לא פעיל"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "כתובת אימייל לא תקינה."
|
msgstr "כתובת אימייל לא תקינה."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "קרנל"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "שפה"
|
msgstr "שפה"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "מקס 1 דק'"
|
msgstr "מקס 1 דק'"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "ניצול ממוצע לליבה"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "אחוז הזמן המוקדש לכל מצב"
|
msgstr "אחוז הזמן המוקדש לכל מצב"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "קבוע"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "עקביות"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "אנא <0>הגדר שרת SMTP</0> כדי להבטיח שהתראות יישלחו."
|
msgstr "אנא <0>הגדר שרת SMTP</0> כדי להבטיח שהתראות יישלחו."
|
||||||
@@ -1208,7 +1246,7 @@ msgstr "המשך"
|
|||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgctxt "Root disk label"
|
msgctxt "Root disk label"
|
||||||
msgid "Root"
|
msgid "Root"
|
||||||
msgstr ""
|
msgstr "שורש"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Rotate token"
|
msgid "Rotate token"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "שמור הגדרות"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "שמור מערכת"
|
msgstr "שמור מערכת"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "נשמר במסד הנתונים ולא פג תוקף עד שתבטל אותו."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "לוח זמנים"
|
msgstr "לוח זמנים"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "פורמט זמן"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "לאימייל(ים)"
|
msgstr "לאימייל(ים)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "החלף רשת"
|
msgstr "החלף רשת"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "מופעל כאשר ממוצע העומס ל-5 דקות עולה על ס
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "מופעל כאשר כל חיישן עולה על סף"
|
msgstr "מופעל כאשר כל חיישן עולה על סף"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "מופעל כאשר טעינת הסוללה יורדת מתחת לסף"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "מופעל כאשר השילוב של למעלה/למטה עולה על סף"
|
msgstr "מופעל כאשר השילוב של למעלה/למטה עולה על סף"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "ללא הגבלה"
|
msgstr "ללא הגבלה"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "למעלה"
|
msgstr "למעלה"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "מתעדכן כל 10 דקות."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "העלאה"
|
msgstr "העלאה"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "זמן פעילות"
|
msgstr "זמן פעילות"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / התראות דחיפה"
|
msgstr "Webhook / התראות דחיפה"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "כאשר מופעל, token זה מאפשר לסוכנים להירשם עצמאית ללא יצירת מערכת מוקדמת. פג לאחר שעה אחת או בהפעלה מחדש של hub."
|
msgstr "כאשר מופעל, אסימון זה מאפשר לסוכנים להירשם באופן עצמי ללא יצירת מערכת מוקדמת."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: hr\n"
|
"Language: hr\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Croatian\n"
|
"Language-Team: Croatian\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} od {1} redaka izabrano."
|
msgstr "{0} od {1} redaka izabrano."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# jezgra} few {# jezgre} other {# jezgri}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dan} other {{countString} dani}}"
|
msgstr "{count, plural, one {{countString} dan} other {{countString} dani}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} sat} other {{countString} sati}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuta} many {{countString} minuta} other {{countString} minute}}"
|
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuta} many {{countString} minuta} other {{countString} minute}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# nit} few {# niti} other {# niti}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 sat"
|
msgstr "1 sat"
|
||||||
@@ -101,7 +109,7 @@ msgstr "Aktivno stanje"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Add {foo}"
|
msgid "Add {foo}"
|
||||||
msgstr ""
|
msgstr "Dodaj {foo}"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Add <0>System</0>"
|
msgid "Add <0>System</0>"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Prosjek"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Prosječna iskorištenost procesora u spremnicima"
|
msgstr "Prosječna iskorištenost procesora u spremnicima"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Prosjek pada ispod <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Sigurnosne kopije"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Propusnost"
|
msgstr "Propusnost"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Baterija"
|
msgstr "Baterija"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Postalo neaktivno"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Prije"
|
msgstr "Prije"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Ispod {0}{1} u posljednjih {2, plural, one {# minuti} few {# minute} other {# minuta}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel podržava OpenID Connect i mnoge druge OAuth2 davatalje autentifikacije."
|
msgstr "Beszel podržava OpenID Connect i mnoge druge OAuth2 davatalje autentifikacije."
|
||||||
@@ -280,7 +306,7 @@ msgstr "Otkaži"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Capabilities"
|
msgid "Capabilities"
|
||||||
msgstr ""
|
msgstr "Mogućnosti"
|
||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Capacity"
|
msgid "Capacity"
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentacija"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -594,7 +620,7 @@ msgstr "Uredi"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Edit {foo}"
|
msgid "Edit {foo}"
|
||||||
msgstr ""
|
msgstr "Uredi {foo}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
@@ -628,6 +654,10 @@ msgstr "Unesite email adresu..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Unesite Vašu jednokratnu lozinku."
|
msgstr "Unesite Vašu jednokratnu lozinku."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efemeran"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Postojeći sistemi koji nisu definirani u <0>config.yml</0> će biti izb
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Izašlo aktivno"
|
msgstr "Izašlo aktivno"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Istječe nakon jednog sata ili ponovnog pokretanja huba."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Izvezi"
|
msgstr "Izvezi"
|
||||||
@@ -720,7 +754,7 @@ msgstr "Otisak prsta"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Firmware"
|
msgid "Firmware"
|
||||||
msgstr ""
|
msgstr "Firmver"
|
||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Neaktivno"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Nevažeća adresa e-pošte."
|
msgstr "Nevažeća adresa e-pošte."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Jezgra"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Jezik"
|
msgstr "Jezik"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maksimalno 1 minuta"
|
msgstr "Maksimalno 1 minuta"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -926,7 +956,7 @@ msgstr "Upotreba memorije Docker spremnika"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Model"
|
msgid "Model"
|
||||||
msgstr ""
|
msgstr "Model"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Prosječna iskorištenost po jezgri"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Postotak vremena provedenog u svakom stanju"
|
msgstr "Postotak vremena provedenog u svakom stanju"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Trajan"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Postojanost"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Molimo <0>konfigurirajte SMTP server</0> kako biste osigurali isporuku upozorenja."
|
msgstr "Molimo <0>konfigurirajte SMTP server</0> kako biste osigurali isporuku upozorenja."
|
||||||
@@ -1208,7 +1246,7 @@ msgstr "Nastavi"
|
|||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgctxt "Root disk label"
|
msgctxt "Root disk label"
|
||||||
msgid "Root"
|
msgid "Root"
|
||||||
msgstr ""
|
msgstr "Korijen"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Rotate token"
|
msgid "Rotate token"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Spremi Postavke"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Spremi sustav"
|
msgstr "Spremi sustav"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Spremljeno u bazi podataka i ne istječe dok ga ne onemogućite."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Raspored"
|
msgstr "Raspored"
|
||||||
@@ -1269,7 +1311,7 @@ msgstr "Pogledajte <0>postavke obavijesti</0> da biste konfigurirali način prim
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Select {foo}"
|
msgid "Select {foo}"
|
||||||
msgstr ""
|
msgstr "Odaberi {foo}"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Sent"
|
msgid "Sent"
|
||||||
@@ -1366,7 +1408,7 @@ msgstr "Prosječno opterećenje sustava kroz vrijeme"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Systemd Services"
|
msgid "Systemd Services"
|
||||||
msgstr ""
|
msgstr "Systemd servisi"
|
||||||
|
|
||||||
#: src/components/navbar.tsx
|
#: src/components/navbar.tsx
|
||||||
msgid "Systems"
|
msgid "Systems"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Format vremena"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Primaoci e-pošte"
|
msgstr "Primaoci e-pošte"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Uključi/isključi rešetku"
|
msgstr "Uključi/isključi rešetku"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Pokreće se kada prosječna opterećenost sustava unutar 5 minuta prije
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Pokreće se kada bilo koji senzor prijeđe prag"
|
msgstr "Pokreće se kada bilo koji senzor prijeđe prag"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Pokreće se kada razina baterije padne ispod praga"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Pokreće se kada kombinacija gore/dolje premaši prag"
|
msgstr "Pokreće se kada kombinacija gore/dolje premaši prag"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Neograničeno"
|
msgstr "Neograničeno"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Sustav je podignut"
|
msgstr "Sustav je podignut"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Ažurirano svakih 10 minuta."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Otpremi"
|
msgstr "Otpremi"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Vrijeme rada"
|
msgstr "Vrijeme rada"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push obavijest"
|
msgstr "Webhook / Push obavijest"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Kada je podešen, ovaj token dopušta agentima da se prijave bez prvobitnog stvaranja sustava. Ističe nakon jednog sata ili ponovnog pokretanja središnje kontrole."
|
msgstr "Kada je omogućen, ovaj token omogućuje agentima da se sami registriraju bez prethodnog stvaranja sustava."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: hu\n"
|
"Language: hu\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Hungarian\n"
|
"Language-Team: Hungarian\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} a(z) {1} sorból kiválasztva."
|
msgstr "{0} a(z) {1} sorból kiválasztva."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# mag} other {# mag}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} nap} other {{countString} nap}}"
|
msgstr "{count, plural, one {{countString} nap} other {{countString} nap}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} óra} other {{countString} óra}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} perc} few {{countString} perc} many {{countString} perc} other {{countString} perc}}"
|
msgstr "{count, plural, one {{countString} perc} few {{countString} perc} many {{countString} perc} other {{countString} perc}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# szál} other {# szál}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 óra"
|
msgstr "1 óra"
|
||||||
@@ -101,7 +109,7 @@ msgstr "Aktív állapot"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Add {foo}"
|
msgid "Add {foo}"
|
||||||
msgstr ""
|
msgstr "Hozzáadás {foo}"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Add <0>System</0>"
|
msgid "Add <0>System</0>"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Átlag"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Konténerek átlagos CPU kihasználtsága"
|
msgstr "Konténerek átlagos CPU kihasználtsága"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Az átlag esik <0>{value}{0}</0> alá"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Biztonsági mentések"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Sávszélesség"
|
msgstr "Sávszélesség"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Akk"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Akkumulátor"
|
msgstr "Akkumulátor"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Inaktívvá vált"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Előtte"
|
msgstr "Előtte"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "{0}{1} alatt az elmúlt {2, plural, one {# percben} other {# percben}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "A Beszel támogatja az OpenID Connect-et és számos OAuth2 hitelesítési szolgáltatót."
|
msgstr "A Beszel támogatja az OpenID Connect-et és számos OAuth2 hitelesítési szolgáltatót."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentáció"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -594,7 +620,7 @@ msgstr "Szerkesztés"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Edit {foo}"
|
msgid "Edit {foo}"
|
||||||
msgstr ""
|
msgstr "Szerkesztés {foo}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
@@ -628,6 +654,10 @@ msgstr "Adja meg az e-mail címet..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Adja meg az egyszeri jelszavát."
|
msgstr "Adja meg az egyszeri jelszavát."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Átmeneti"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -648,7 +678,7 @@ msgstr "Túllépi a {0}{1} értéket az elmúlt {2, plural, one {# percben} othe
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Exec main PID"
|
msgid "Exec main PID"
|
||||||
msgstr ""
|
msgstr "Fő folyamat PID"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
||||||
@@ -658,6 +688,10 @@ msgstr "A <0>config.yml</0> fájlban nem definiált meglévő rendszerek törlé
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Aktívként kilépett"
|
msgstr "Aktívként kilépett"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Lejár egy óra után vagy a hub újraindításakor."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportálás"
|
msgstr "Exportálás"
|
||||||
@@ -720,7 +754,7 @@ msgstr "Ujjlenyomat"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Firmware"
|
msgid "Firmware"
|
||||||
msgstr ""
|
msgstr "Firmware"
|
||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inaktív"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Érvénytelen e-mail cím."
|
msgstr "Érvénytelen e-mail cím."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Nyelv"
|
msgstr "Nyelv"
|
||||||
@@ -883,7 +912,7 @@ msgstr "Inkább azt keresi, hogy hol hozhat létre riasztásokat? Kattintson a c
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Main PID"
|
msgid "Main PID"
|
||||||
msgstr ""
|
msgstr "Fő PID"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Manage display and notification preferences."
|
msgid "Manage display and notification preferences."
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maximum 1 perc"
|
msgstr "Maximum 1 perc"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Átlagos kihasználtság magonként"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Az idő százalékos aránya minden állapotban"
|
msgstr "Az idő százalékos aránya minden állapotban"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Állandó"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Kitartás"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Kérjük, <0>konfigurálj egy SMTP szervert</0> az értesítések kézbesítésének biztosítása érdekében."
|
msgstr "Kérjük, <0>konfigurálj egy SMTP szervert</0> az értesítések kézbesítésének biztosítása érdekében."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Beállítások mentése"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Rendszer mentése"
|
msgstr "Rendszer mentése"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Elmentve az adatbázisban és nem jár le, amíg ki nem kapcsolod."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Ütemezés"
|
msgstr "Ütemezés"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Időformátum"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "E-mailben"
|
msgstr "E-mailben"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Rács ki- és bekapcsolása"
|
msgstr "Rács ki- és bekapcsolása"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Riaszt, ha az 5 perces terhelési átlag túllép egy küszöbértéket"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
|
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
|
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Korlátlan"
|
msgstr "Korlátlan"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Online"
|
msgstr "Online"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "10 percenként frissítve."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Feltöltés"
|
msgstr "Feltöltés"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Üzemidő"
|
msgstr "Üzemidő"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push értesítések"
|
msgstr "Webhook / Push értesítések"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Ha engedélyezve van, ez a token lehetővé teszi az ügynökök önregisztrációját előzetes rendszerlétrehozás nélkül. Egy óra után vagy a hub újraindításakor lejár."
|
msgstr "Ha engedélyezve van, ez a token lehetővé teszi az ügynökök számára az önregisztrációt rendszer előzetes létrehozása nélkül."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: it\n"
|
"Language: it\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-20 16:58\n"
|
"PO-Revision-Date: 2025-12-02 23:17\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Italian\n"
|
"Language-Team: Italian\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} di {1} righe selezionate."
|
msgstr "{0} di {1} righe selezionate."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# core} other {# core}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} giorno} other {{countString} giorni}}"
|
msgstr "{count, plural, one {{countString} giorno} other {{countString} giorni}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} ora} other {{countString} ore}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuto} other {{countString} minuti}}"
|
msgstr "{count, plural, one {{countString} minuto} other {{countString} minuti}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# thread} other {# thread}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 ora"
|
msgstr "1 ora"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Media"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Utilizzo medio della CPU dei container"
|
msgstr "Utilizzo medio della CPU dei container"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "La media scende sotto <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Backup"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Larghezza di banda"
|
msgstr "Larghezza di banda"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batteria"
|
msgstr "Batteria"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Diventato inattivo"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Prima"
|
msgstr "Prima"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Sotto {0}{1} negli ultimi {2, plural, one {# minuto} other {# minuti}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel supporta OpenID Connect e molti provider di autenticazione OAuth2."
|
msgstr "Beszel supporta OpenID Connect e molti provider di autenticazione OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Documentazione"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Inserisci l'indirizzo email..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Inserisci la tua password monouso."
|
msgstr "Inserisci la tua password monouso."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Effimero"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "I sistemi esistenti non definiti in <0>config.yml</0> verranno eliminati
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Uscito attivo"
|
msgstr "Uscito attivo"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Scade dopo un'ora o al riavvio dell'hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Esporta"
|
msgstr "Esporta"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inattivo"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Indirizzo email non valido."
|
msgstr "Indirizzo email non valido."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Lingua"
|
msgstr "Lingua"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max 1 min"
|
msgstr "Max 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Utilizzo medio per core"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Percentuale di tempo trascorso in ogni stato"
|
msgstr "Percentuale di tempo trascorso in ogni stato"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanente"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistenza"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Si prega di <0>configurare un server SMTP</0> per garantire la consegna degli avvisi."
|
msgstr "Si prega di <0>configurare un server SMTP</0> per garantire la consegna degli avvisi."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Salva Impostazioni"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Salva sistema"
|
msgstr "Salva sistema"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Salvato nel database e non scade finché non lo disabiliti."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Pianifica"
|
msgstr "Pianifica"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Formato orario"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "A email(s)"
|
msgstr "A email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Attiva/disattiva griglia"
|
msgstr "Attiva/disattiva griglia"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Si attiva quando la media di carico di 5 minuti supera una soglia"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Attiva quando un sensore supera una soglia"
|
msgstr "Attiva quando un sensore supera una soglia"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Attiva quando la carica della batteria scende sotto una soglia"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Attiva quando il combinato up/down supera una soglia"
|
msgstr "Attiva quando il combinato up/down supera una soglia"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Illimitato"
|
msgstr "Illimitato"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Attivo"
|
msgstr "Attivo"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Aggiornato ogni 10 minuti."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Carica"
|
msgstr "Carica"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Tempo di attività"
|
msgstr "Tempo di attività"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Notifiche Webhook / Push"
|
msgstr "Notifiche Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Quando abilitato, questo token consente agli agenti di auto-registrarsi senza creazione preventiva del sistema. Scade dopo un'ora o al riavvio dell'hub."
|
msgstr "Quando abilitato, questo token consente agli agenti di registrarsi automaticamente senza creazione preventiva del sistema."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: ja\n"
|
"Language: ja\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Japanese\n"
|
"Language-Team: Japanese\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{1}行のうち{0}行が選択されました。"
|
msgstr "{1}行のうち{0}行が選択されました。"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# コア} other {# コア}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} 日} other {{countString} 日}}"
|
msgstr "{count, plural, one {{countString} 日} other {{countString} 日}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} 時間} other {{countString} 時間}}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} 分} few {{countString} 分} many {{countString} 分} other {{countString} 分}}"
|
msgstr "{count, plural, one {{countString} 分} few {{countString} 分} many {{countString} 分} other {{countString} 分}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# スレッド} other {# スレッド}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1時間"
|
msgstr "1時間"
|
||||||
@@ -182,6 +190,11 @@ msgstr "平均"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "コンテナの平均CPU使用率"
|
msgstr "コンテナの平均CPU使用率"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "平均が<0>{value}{0}</0>を下回っています"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "バックアップ"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "帯域幅"
|
msgstr "帯域幅"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "バッテリー"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "バッテリー"
|
msgstr "バッテリー"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "非アクティブになった"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "前"
|
msgstr "前"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "過去{2, plural, one {# 分} other {# 分}}で{0}{1}を下回っています"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサポートしています。"
|
msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサポートしています。"
|
||||||
@@ -568,7 +594,7 @@ msgstr "ドキュメント"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "メールアドレスを入力..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "ワンタイムパスワードを入力してください。"
|
msgstr "ワンタイムパスワードを入力してください。"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "一時的"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "<0>config.yml</0>に定義されていない既存のシステムは削
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "アクティブ状態で終了"
|
msgstr "アクティブ状態で終了"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "1時間後、またはハブの再起動時に有効期限が切れます。"
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "エクスポート"
|
msgstr "エクスポート"
|
||||||
@@ -803,11 +837,6 @@ msgstr "非アクティブ"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "無効なメールアドレスです。"
|
msgstr "無効なメールアドレスです。"
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "カーネル"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "言語"
|
msgstr "言語"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "最大1分"
|
msgstr "最大1分"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "コアごとの平均使用率"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "各状態で費やした時間の割合"
|
msgstr "各状態で費やした時間の割合"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "永久"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "永続性"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "アラートが配信されるように<0>SMTPサーバーを設定</0>してください。"
|
msgstr "アラートが配信されるように<0>SMTPサーバーを設定</0>してください。"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "設定を保存"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "システムを保存"
|
msgstr "システムを保存"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "データベースに保存され、無効にするまで有効期限が切れません。"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "スケジュール"
|
msgstr "スケジュール"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "時間形式"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "宛先メールアドレス"
|
msgstr "宛先メールアドレス"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "グリッドを切り替え"
|
msgstr "グリッドを切り替え"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "5分間の負荷平均がしきい値を超えたときにトリガー
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "センサーがしきい値を超えたときにトリガーされます"
|
msgstr "センサーがしきい値を超えたときにトリガーされます"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "バッテリーの充電量がしきい値を下回ったときにトリガーされます"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "上り/下りの合計がしきい値を超えたときにトリガーされます"
|
msgstr "上り/下りの合計がしきい値を超えたときにトリガーされます"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "無制限"
|
msgstr "無制限"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "正常"
|
msgstr "正常"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "10分ごとに更新されます。"
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "アップロード"
|
msgstr "アップロード"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "稼働時間"
|
msgstr "稼働時間"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / プッシュ通知"
|
msgstr "Webhook / プッシュ通知"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "有効にすると、このトークンはエージェントが事前のシステム作成なしに自己登録することを可能にします。1時間後またはハブの再起動時に期限切れになります。"
|
msgstr "有効にすると、このトークンによりエージェントは事前のシステム作成なしで自己登録できます。"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: ko\n"
|
"Language: ko\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Korean\n"
|
"Language-Team: Korean\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{1}개의 행 중 {0}개가 선택되었습니다."
|
msgstr "{1}개의 행 중 {0}개가 선택되었습니다."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# 코어} other {# 코어}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} 일} other {{countString} 일}}"
|
msgstr "{count, plural, one {{countString} 일} other {{countString} 일}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} 시간} other {{countString} 시간}}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} 분} few {{countString} 분} many {{countString} 분} other {{countString} 분}}"
|
msgstr "{count, plural, one {{countString} 분} few {{countString} 분} many {{countString} 분} other {{countString} 분}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# 스레드} other {# 스레드}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1시간"
|
msgstr "1시간"
|
||||||
@@ -182,6 +190,11 @@ msgstr "평균"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Docker 컨테이너의 평균 CPU 사용량"
|
msgstr "Docker 컨테이너의 평균 CPU 사용량"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "평균이 <0>{value}{0}</0> 아래로 떨어집니다"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "백업"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "대역폭"
|
msgstr "대역폭"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "배터리"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "배터리"
|
msgstr "배터리"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "비활성화됨"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "이전"
|
msgstr "이전"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "마지막 {2, plural, one {# 분} other {# 분}} 동안 {0}{1} 미만"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합니다."
|
msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합니다."
|
||||||
@@ -568,7 +594,7 @@ msgstr "문서"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "이메일 주소 입력..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "OTP를 입력하세요."
|
msgstr "OTP를 입력하세요."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "일시적"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "<0>config.yml</0>에 정의되지 않은 기존 시스템은 삭제됩
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "활성 종료됨"
|
msgstr "활성 종료됨"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "한 시간 후 또는 허브 재시작 시 만료됩니다."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "내보내기"
|
msgstr "내보내기"
|
||||||
@@ -803,11 +837,6 @@ msgstr "비활성"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "잘못된 이메일 주소입니다."
|
msgstr "잘못된 이메일 주소입니다."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "커널"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "언어"
|
msgstr "언어"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "1분간 최댓값"
|
msgstr "1분간 최댓값"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "코어별 평균 사용률"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "각 상태에서 보낸 시간의 백분율"
|
msgstr "각 상태에서 보낸 시간의 백분율"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "영구적"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "지속성"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "알림이 전달되도록 <0>SMTP 서버를 구성</0>하세요."
|
msgstr "알림이 전달되도록 <0>SMTP 서버를 구성</0>하세요."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "설정 저장"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "시스템 저장"
|
msgstr "시스템 저장"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "데이터베이스에 저장되며 비활성화할 때까지 만료되지 않습니다."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "일정"
|
msgstr "일정"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "시간 형식"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "받는사람(들)"
|
msgstr "받는사람(들)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "그리드 전환"
|
msgstr "그리드 전환"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "5분 부하 평균이 임계값을 초과하면 트리거됩니다."
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "센서가 임계값을 초과할 때 트리거됩니다."
|
msgstr "센서가 임계값을 초과할 때 트리거됩니다."
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "배터리 충전량이 임계값 아래로 떨어질 때 트리거됩니다."
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "업로드와 다운로드 대역폭의 합이 임계값을 초과할 때 트리거됩니다."
|
msgstr "업로드와 다운로드 대역폭의 합이 임계값을 초과할 때 트리거됩니다."
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "무제한"
|
msgstr "무제한"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "온라인"
|
msgstr "온라인"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "10분마다 업데이트됩니다."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "업로드"
|
msgstr "업로드"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "가동 시간"
|
msgstr "가동 시간"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / 푸시 알림"
|
msgstr "Webhook / 푸시 알림"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "활성화하면 이 토큰을 통해 에이전트가 사전 시스템 생성 없이 자체 등록할 수 있습니다. 1시간 후 또는 허브 재시작 시 만료됩니다."
|
msgstr "활성화되면 이 토큰은 사전 시스템 생성 없이 에이전트가 자체 등록할 수 있도록 합니다."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-17 12:02\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Dutch\n"
|
"Language-Team: Dutch\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} van de {1} rij(en) geselecteerd."
|
msgstr "{0} van de {1} rij(en) geselecteerd."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# kern} other {# kernen}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dag} other {{countString} dagen}}"
|
msgstr "{count, plural, one {{countString} dag} other {{countString} dagen}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} uur} other {{countString} uren}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuut} other {{countString} minuten}}"
|
msgstr "{count, plural, one {{countString} minuut} other {{countString} minuten}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 uur"
|
msgstr "1 uur"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Gemiddelde"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Gemiddeld CPU-gebruik van containers"
|
msgstr "Gemiddeld CPU-gebruik van containers"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Gemiddelde daalt onder <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Back-ups"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bandbreedte"
|
msgstr "Bandbreedte"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batterij"
|
msgstr "Batterij"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Inactief geworden"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Voor"
|
msgstr "Voor"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Onder {0}{1} in de laatste {2, plural, one {# minuut} other {# minuten}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel ondersteunt OpenID Connect en vele OAuth2 authenticatieaanbieders."
|
msgstr "Beszel ondersteunt OpenID Connect en vele OAuth2 authenticatieaanbieders."
|
||||||
@@ -516,7 +542,7 @@ msgstr "Beschrijving"
|
|||||||
|
|
||||||
#: src/components/containers-table/containers-table.tsx
|
#: src/components/containers-table/containers-table.tsx
|
||||||
msgid "Detail"
|
msgid "Detail"
|
||||||
msgstr ""
|
msgstr "Details"
|
||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Device"
|
msgid "Device"
|
||||||
@@ -568,7 +594,7 @@ msgstr "Documentatie"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Voer een e-mailadres in..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Voer uw eenmalig wachtwoord in."
|
msgstr "Voer uw eenmalig wachtwoord in."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Tijdelijk"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Bestaande systemen die niet gedefinieerd zijn in <0>config.yml</0> zulle
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Beëindigd actief"
|
msgstr "Beëindigd actief"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Verloopt na één uur of bij hub-herstart."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exporteren"
|
msgstr "Exporteren"
|
||||||
@@ -720,7 +754,7 @@ msgstr "Vingerafdruk"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Firmware"
|
msgid "Firmware"
|
||||||
msgstr ""
|
msgstr "Firmware"
|
||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
|
||||||
@@ -793,7 +827,7 @@ msgstr "Als je het wachtwoord voor je beheerdersaccount bent kwijtgeraakt, kan j
|
|||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
msgctxt "Docker image"
|
msgctxt "Docker image"
|
||||||
msgid "Image"
|
msgid "Image"
|
||||||
msgstr ""
|
msgstr "Afbeelding"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Inactive"
|
msgid "Inactive"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inactief"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Ongeldig e-mailadres."
|
msgstr "Ongeldig e-mailadres."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Taal"
|
msgstr "Taal"
|
||||||
@@ -822,12 +851,12 @@ msgstr "Layoutbreedte"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Lifecycle"
|
msgid "Lifecycle"
|
||||||
msgstr ""
|
msgstr "Levenscyclus"
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "limit"
|
msgid "limit"
|
||||||
msgstr ""
|
msgstr "limiet"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Load Average"
|
msgid "Load Average"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -926,7 +956,7 @@ msgstr "Geheugengebruik van docker containers"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Model"
|
msgid "Model"
|
||||||
msgstr ""
|
msgstr "Model"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1064,7 +1094,7 @@ msgstr "Wachtwoord reset aanvraag ontvangen"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Past"
|
msgid "Past"
|
||||||
msgstr ""
|
msgstr "Verleden"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Pause"
|
msgid "Pause"
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Gemiddeld gebruik per kern"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Percentage tijd besteed in elke status"
|
msgstr "Percentage tijd besteed in elke status"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistentie"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "<0>Configureer een SMTP-server </0> om ervoor te zorgen dat waarschuwingen worden afgeleverd."
|
msgstr "<0>Configureer een SMTP-server </0> om ervoor te zorgen dat waarschuwingen worden afgeleverd."
|
||||||
@@ -1208,7 +1246,7 @@ msgstr "Hervatten"
|
|||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgctxt "Root disk label"
|
msgctxt "Root disk label"
|
||||||
msgid "Root"
|
msgid "Root"
|
||||||
msgstr ""
|
msgstr "Root"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Rotate token"
|
msgid "Rotate token"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Instellingen opslaan"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Systeem bewaren"
|
msgstr "Systeem bewaren"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Opgeslagen in de database en verloopt niet totdat u het uitschakelt."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Schema"
|
msgstr "Schema"
|
||||||
@@ -1285,7 +1327,7 @@ msgstr "Servicedetails"
|
|||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Services"
|
msgid "Services"
|
||||||
msgstr ""
|
msgstr "Services"
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Set percentage thresholds for meter colors."
|
msgid "Set percentage thresholds for meter colors."
|
||||||
@@ -1317,7 +1359,7 @@ msgstr "Sorteren op"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Start Time"
|
msgid "Start Time"
|
||||||
msgstr ""
|
msgstr "Starttijd"
|
||||||
|
|
||||||
#. Context: alert state (active or resolved)
|
#. Context: alert state (active or resolved)
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Tijdnotatie"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Naar e-mail(s)"
|
msgstr "Naar e-mail(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Schakel raster"
|
msgstr "Schakel raster"
|
||||||
|
|
||||||
@@ -1491,7 +1533,7 @@ msgstr "Geactiveerd door"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Triggers"
|
msgid "Triggers"
|
||||||
msgstr ""
|
msgstr "Triggers"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when 1 minute load average exceeds a threshold"
|
msgid "Triggers when 1 minute load average exceeds a threshold"
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Triggert wanneer de 5 minuten gemiddelde belasting een drempelwaarde ove
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Triggert wanneer een sensor een drempelwaarde overschrijdt"
|
msgstr "Triggert wanneer een sensor een drempelwaarde overschrijdt"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Triggert wanneer de batterijlading onder een drempelwaarde daalt"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Triggert wanneer de gecombineerde up/down een drempelwaarde overschrijdt"
|
msgstr "Triggert wanneer de gecombineerde up/down een drempelwaarde overschrijdt"
|
||||||
@@ -1537,7 +1583,7 @@ msgstr "Triggert wanneer het gebruik van een schijf een drempelwaarde overschrij
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr "Type"
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Unit file"
|
msgid "Unit file"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Onbeperkt"
|
msgstr "Onbeperkt"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Online"
|
msgstr "Online"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Elke 10 minuten bijgewerkt."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Uploaden"
|
msgstr "Uploaden"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Actief"
|
msgstr "Actief"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Pushmeldingen"
|
msgstr "Webhook / Pushmeldingen"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Wanneer ingeschakeld kunnen agenten zich met dit token registreren zonder dat er vooraf een systeem aangemaakt hoeft te worden. Het token verloopt na één uur of bij herstart van de hub."
|
msgstr "Indien ingeschakeld, stelt deze token agenten in staat zich zelf te registreren zonder voorafgaande systeemcreatie."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: no\n"
|
"Language: no\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Norwegian\n"
|
"Language-Team: Norwegian\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} av {1} rad(er) valgt."
|
msgstr "{0} av {1} rad(er) valgt."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# kjerne} other {# kjerner}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dag} other {{countString} dager}}"
|
msgstr "{count, plural, one {{countString} dag} other {{countString} dager}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} time} other {{countString} timer}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minutt} other {{countString} minutter}}"
|
msgstr "{count, plural, one {{countString} minutt} other {{countString} minutter}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# tråd} other {# tråder}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 time"
|
msgstr "1 time"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Gjennomsnitt"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Gjennomsnittlig CPU-utnyttelse av konteinere"
|
msgstr "Gjennomsnittlig CPU-utnyttelse av konteinere"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Gjennomsnittet faller under <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Sikkerhetskopier"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Båndbredde"
|
msgstr "Båndbredde"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batteri"
|
msgstr "Batteri"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Ble inaktiv"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Før"
|
msgstr "Før"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Under {0}{1} i siste {2, plural, one {# minutt} other {# minutter}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel støtter OpenID Connect og mange OAuth2 autentiserings-tilbydere."
|
msgstr "Beszel støtter OpenID Connect og mange OAuth2 autentiserings-tilbydere."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentasjon"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Skriv inn e-postadresse..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Skriv inn ditt engangspassord."
|
msgstr "Skriv inn ditt engangspassord."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Flyktig"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Eksisterende systemer som ikke er er definert i <0>config.yml</0> vil bl
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Avsluttet aktiv"
|
msgstr "Avsluttet aktiv"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Utløper etter en time eller ved hub-omstart."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Eksporter"
|
msgstr "Eksporter"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inaktiv"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Ugyldig e-postadresse."
|
msgstr "Ugyldig e-postadresse."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kjerne"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Språk"
|
msgstr "Språk"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maks 1 min"
|
msgstr "Maks 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1064,7 +1094,7 @@ msgstr "Mottatt forespørsel om å nullstille passord"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Past"
|
msgid "Past"
|
||||||
msgstr ""
|
msgstr "Fortid"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Pause"
|
msgid "Pause"
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Gjennomsnittlig utnyttelse per kjerne"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Prosentandel av tid brukt i hver tilstand"
|
msgstr "Prosentandel av tid brukt i hver tilstand"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Vedvarenhet"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Vennligst <0>konfigurer en SMTP-server</0> for å forsikre deg om at varsler blir levert."
|
msgstr "Vennligst <0>konfigurer en SMTP-server</0> for å forsikre deg om at varsler blir levert."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Lagre Innstillinger"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Lagre system"
|
msgstr "Lagre system"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Lagret i databasen og utløper ikke før du deaktiverer det."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Tidsplan"
|
msgstr "Tidsplan"
|
||||||
@@ -1317,7 +1359,7 @@ msgstr "Sorter Etter"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Start Time"
|
msgid "Start Time"
|
||||||
msgstr ""
|
msgstr "Starttid"
|
||||||
|
|
||||||
#. Context: alert state (active or resolved)
|
#. Context: alert state (active or resolved)
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Tidsformat"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Til e-postadresse(r)"
|
msgstr "Til e-postadresse(r)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Rutenett av/på"
|
msgstr "Rutenett av/på"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Slår inn når gjennomsnittsbelastningen over 5 minutter overstiger en g
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Slår inn når enhver sensor overstiger en grenseverdi"
|
msgstr "Slår inn når enhver sensor overstiger en grenseverdi"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Utløses når batterilading faller under en terskel"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Slår inn når kombinert opp/ned overskrider en grenseverdi"
|
msgstr "Slår inn når kombinert opp/ned overskrider en grenseverdi"
|
||||||
@@ -1537,7 +1583,7 @@ msgstr "Slår inn når forbruk av hvilken som helst disk overstiger en grensever
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr "Type"
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Unit file"
|
msgid "Unit file"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Ubegrenset"
|
msgstr "Ubegrenset"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Oppe"
|
msgstr "Oppe"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Oppdatert hvert 10. minutt."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Last opp"
|
msgstr "Last opp"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Oppetid"
|
msgstr "Oppetid"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push-varslinger"
|
msgstr "Webhook / Push-varslinger"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Når aktivert lar denne tokenen agenter registrere seg selv uten å opprettes på systemet først. Utløper etter én time eller når huben starter på nytt."
|
msgstr "Når aktivert, tillater denne tokenen agenter å registrere seg selv uten forutgående systemskapelse."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: pl\n"
|
"Language: pl\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-17 16:53\n"
|
"PO-Revision-Date: 2025-12-18 19:21\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Polish\n"
|
"Language-Team: Polish\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} z {1} wybranych wierszy."
|
msgstr "{0} z {1} wybranych wierszy."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# rdzeń} few {# rdzenie} many {# rdzeni} other {# rdzeni}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dzień} few {{countString} dni} many {{countString} dni} other {{countString} dni}}"
|
msgstr "{count, plural, one {{countString} dzień} few {{countString} dni} many {{countString} dni} other {{countString} dni}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {godzinę} few {{countString} godziny} many {{countS
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
|
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# wątek} few {# wątki} many {# wątków} other {# wątków}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 godzina"
|
msgstr "1 godzina"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Średnia"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Średnie wykorzystanie procesora przez kontenery"
|
msgstr "Średnie wykorzystanie procesora przez kontenery"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Kopie"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Przepustowość"
|
msgstr "Przepustowość"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Bateria"
|
msgstr "Bateria"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Stało się nieaktywnym"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Przed"
|
msgstr "Przed"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel obsługuje OpenID Connect i wielu dostawców uwierzytelniania OAuth2."
|
msgstr "Beszel obsługuje OpenID Connect i wielu dostawców uwierzytelniania OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentacja"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Wprowadź adres e-mail..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Wprowadź swoje jednorazowe hasło."
|
msgstr "Wprowadź swoje jednorazowe hasło."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efemeryczny"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Istniejące systemy, które nie są zdefiniowane w <0>config.yml</0>, zo
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Zakończono aktywnie"
|
msgstr "Zakończono aktywnie"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Wygasa po godzinie lub przy ponownym uruchomieniu huba."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Eksport"
|
msgstr "Eksport"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Nieaktywny"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Nieprawidłowy adres e-mail."
|
msgstr "Nieprawidłowy adres e-mail."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Jądro"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Język"
|
msgstr "Język"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maks. 1 min"
|
msgstr "Maks. 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1064,7 +1094,7 @@ msgstr "Otrzymane żądanie resetowania hasła"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Past"
|
msgid "Past"
|
||||||
msgstr ""
|
msgstr "Przeszłe"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Pause"
|
msgid "Pause"
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Średnie wykorzystanie na rdzeń"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Procent czasu spędzonego w każdym stanie"
|
msgstr "Procent czasu spędzonego w każdym stanie"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Stały"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Trwałość"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Proszę <0>skonfigurować serwer SMTP</0>, aby zapewnić dostarczanie powiadomień."
|
msgstr "Proszę <0>skonfigurować serwer SMTP</0>, aby zapewnić dostarczanie powiadomień."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Zapisz ustawienia"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Zapisz system"
|
msgstr "Zapisz system"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Zapisane w bazie danych i nie wygasa, dopóki go nie wyłączysz."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Harmonogram"
|
msgstr "Harmonogram"
|
||||||
@@ -1317,7 +1359,7 @@ msgstr "Sortuj według"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Start Time"
|
msgid "Start Time"
|
||||||
msgstr ""
|
msgstr "Czas rozpoczęcia"
|
||||||
|
|
||||||
#. Context: alert state (active or resolved)
|
#. Context: alert state (active or resolved)
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Format czasu"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Do e-mail(ów)"
|
msgstr "Do e-mail(ów)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Przełącz siatkę"
|
msgstr "Przełącz siatkę"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Uruchamia się, gdy 5-minutowe średnie obciążenie systemu przekroczy
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Wyzwalane, gdy jakikolwiek czujnik przekroczy ustalony próg."
|
msgstr "Wyzwalane, gdy jakikolwiek czujnik przekroczy ustalony próg."
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Wyzwalane, gdy łączna wartość w górę/w dół przekroczy próg"
|
msgstr "Wyzwalane, gdy łączna wartość w górę/w dół przekroczy próg"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Bez limitu"
|
msgstr "Bez limitu"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Działa"
|
msgstr "Działa"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Aktualizowane co 10 minut."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Wysyłanie"
|
msgstr "Wysyłanie"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Czas pracy"
|
msgstr "Czas pracy"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Powiadomienia push"
|
msgstr "Webhook / Powiadomienia push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Po włączeniu ten token umożliwia agentom samodzielną rejestrację bez wcześniejszego utworzenia systemu. Wygasa po jednej godzinie lub po ponownym uruchomieniu huba."
|
msgstr "Gdy jest włączony, ten token pozwala agentom na samodzielną rejestrację bez wcześniejszego tworzenia systemu."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: pt\n"
|
"Language: pt\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Portuguese\n"
|
"Language-Team: Portuguese\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} de {1} linha(s) selecionada(s)."
|
msgstr "{0} de {1} linha(s) selecionada(s)."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# núcleo} other {# núcleos}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dia} other {{countString} dias}}"
|
msgstr "{count, plural, one {{countString} dia} other {{countString} dias}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} hora} other {{countString} horas}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
|
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 hora"
|
msgstr "1 hora"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Média"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Utilização média de CPU dos contêineres"
|
msgstr "Utilização média de CPU dos contêineres"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "A média cai abaixo de <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Cópias de segurança"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Largura de Banda"
|
msgstr "Largura de Banda"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Bateria"
|
msgstr "Bateria"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Tornou-se inativo"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Antes"
|
msgstr "Antes"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Abaixo de {0}{1} no último {2, plural, one {# minuto} other {# minutos}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel suporta OpenID Connect e muitos provedores de autenticação OAuth2."
|
msgstr "Beszel suporta OpenID Connect e muitos provedores de autenticação OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Documentação"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Digite o endereço de email..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Insira a sua senha de uso único."
|
msgstr "Insira a sua senha de uso único."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Efêmero"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Sistemas existentes não definidos em <0>config.yml</0> serão excluído
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Saiu ativo"
|
msgstr "Saiu ativo"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Expira após uma hora ou no reinício do hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportar"
|
msgstr "Exportar"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inativo"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Endereço de email inválido."
|
msgstr "Endereço de email inválido."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Idioma"
|
msgstr "Idioma"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Máx 1 min"
|
msgstr "Máx 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Utilização média por núcleo"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Percentagem de tempo gasto em cada estado"
|
msgstr "Percentagem de tempo gasto em cada estado"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanente"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Persistência"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Por favor, <0>configure um servidor SMTP</0> para garantir que os alertas sejam entregues."
|
msgstr "Por favor, <0>configure um servidor SMTP</0> para garantir que os alertas sejam entregues."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Guardar Definições"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Guardar Sistema"
|
msgstr "Guardar Sistema"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Salvo no banco de dados e não expira até você desativá-lo."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Agendar"
|
msgstr "Agendar"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Formato de hora"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Para email(s)"
|
msgstr "Para email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Alternar grade"
|
msgstr "Alternar grade"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Dispara quando a média de carga de 5 minutos excede um limite"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Dispara quando qualquer sensor excede um limite"
|
msgstr "Dispara quando qualquer sensor excede um limite"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Dispara quando a carga da bateria cai abaixo de um limite"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Dispara quando a soma de subida/descida excede um limite"
|
msgstr "Dispara quando a soma de subida/descida excede um limite"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Ilimitado"
|
msgstr "Ilimitado"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Ligado"
|
msgstr "Ligado"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Atualizado a cada 10 minutos."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Carregar"
|
msgstr "Carregar"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Tempo de Atividade"
|
msgstr "Tempo de Atividade"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Notificações Webhook / Push"
|
msgstr "Notificações Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Quando habilitado, este token permite que os agentes se registrem automaticamente sem criação prévia do sistema. Expira após uma hora ou na reinicialização do hub."
|
msgstr "Quando ativado, este token permite que os agentes se registrem automaticamente sem criação prévia do sistema."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: ru\n"
|
"Language: ru\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-12-01 23:32\n"
|
"PO-Revision-Date: 2025-12-02 23:17\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Russian\n"
|
"Language-Team: Russian\n"
|
||||||
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "Выбрано {0} из {1} строк."
|
msgstr "Выбрано {0} из {1} строк."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# ядро} few {# ядра} many {# ядер} other {# ядер}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} день} other {{countString} дней}}"
|
msgstr "{count, plural, one {{countString} день} other {{countString} дней}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} час} other {{countString} часо
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} минута} few {{countString} минут} many {{countString} минут} other {{countString} минуты}}"
|
msgstr "{count, plural, one {{countString} минута} few {{countString} минут} many {{countString} минут} other {{countString} минуты}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# поток} few {# потока} many {# потоков} other {# потоков}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 час"
|
msgstr "1 час"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Среднее"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Среднее использование CPU контейнерами"
|
msgstr "Среднее использование CPU контейнерами"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Среднее опускается ниже <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Резервные копии"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Пропускная способность"
|
msgstr "Пропускная способность"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Батарея"
|
msgstr "Батарея"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Стал неактивным"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "До"
|
msgstr "До"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Ниже {0}{1} за последние {2, plural, one {# минуту} other {# минут}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel поддерживает OpenID Connect и множество поставщиков аутентификации OAuth2."
|
msgstr "Beszel поддерживает OpenID Connect и множество поставщиков аутентификации OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Документация"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Введите адрес электронной почты..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Введите ваш одноразовый пароль."
|
msgstr "Введите ваш одноразовый пароль."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Эфемерный"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Существующие системы, не определенные
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Завершился активным"
|
msgstr "Завершился активным"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Истекает через час или при перезапуске хаба."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Экспорт"
|
msgstr "Экспорт"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Неактивно"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Неверный адрес электронной почты."
|
msgstr "Неверный адрес электронной почты."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Ядро"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Язык"
|
msgstr "Язык"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Макс 1 мин"
|
msgstr "Макс 1 мин"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Среднее использование на ядро"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Процент времени, проведенного в каждом состоянии"
|
msgstr "Процент времени, проведенного в каждом состоянии"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Постоянный"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Устойчивость"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Пожалуйста, <0>настройте SMTP-сервер</0>, чтобы гарантировать доставку оповещений."
|
msgstr "Пожалуйста, <0>настройте SMTP-сервер</0>, чтобы гарантировать доставку оповещений."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Сохранить настройки"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Сохранить систему"
|
msgstr "Сохранить систему"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Сохранено в базе данных и не истекает, пока вы его не отключите."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Расписание"
|
msgstr "Расписание"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Формат времени"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "На электронную почту"
|
msgstr "На электронную почту"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Переключить сетку"
|
msgstr "Переключить сетку"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Срабатывает, когда средняя загрузка за
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Срабатывает, когда любой датчик превышает порог"
|
msgstr "Срабатывает, когда любой датчик превышает порог"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Срабатывает, когда заряд батареи опускается ниже порога"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Срабатывает, когда комбинированный вход/выход превышает порог"
|
msgstr "Срабатывает, когда комбинированный вход/выход превышает порог"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Неограниченно"
|
msgstr "Неограниченно"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "В сети"
|
msgstr "В сети"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Обновляется каждые 10 минут."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Отдача"
|
msgstr "Отдача"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Время работы"
|
msgstr "Время работы"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push уведомления"
|
msgstr "Webhook / Push уведомления"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Если включено, этот токен позволяет агентам регистрироваться самостоятельно без предварительного создания системы. Истекает через час или при перезапуске хаба."
|
msgstr "При включении этот токен позволяет агентам самостоятельно регистрироваться без предварительного создания системы."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: sl\n"
|
"Language: sl\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Slovenian\n"
|
"Language-Team: Slovenian\n"
|
||||||
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
|
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} od {1} vrstic izbranih."
|
msgstr "{0} od {1} vrstic izbranih."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# jedro} two {# jedri} few {# jedra} other {# jeder}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dan} two {{countString} dneva} few {{countString} dni} other {{countString} dni}}"
|
msgstr "{count, plural, one {{countString} dan} two {{countString} dneva} few {{countString} dni} other {{countString} dni}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} ura} two {{countString} uri} few {{co
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuti} many {{countString} minut} other {{countString} minut}}"
|
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuti} many {{countString} minut} other {{countString} minut}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# nit} two {# niti} few {# niti} other {# niti}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 ura"
|
msgstr "1 ura"
|
||||||
@@ -134,7 +142,7 @@ msgstr "Po"
|
|||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Agent"
|
msgid "Agent"
|
||||||
msgstr ""
|
msgstr "Agent"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
@@ -182,6 +190,11 @@ msgstr "Povprečno"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Povprečna izkoriščenost procesorja kontejnerjev"
|
msgstr "Povprečna izkoriščenost procesorja kontejnerjev"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Varnostne kopije"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Pasovna širina"
|
msgstr "Pasovna širina"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Baterija"
|
msgstr "Baterija"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Postalo neaktivno"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Pred"
|
msgstr "Pred"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel podpira OpenID Connect in številne ponudnike preverjanja pristnosti OAuth2."
|
msgstr "Beszel podpira OpenID Connect in številne ponudnike preverjanja pristnosti OAuth2."
|
||||||
@@ -292,7 +318,7 @@ msgstr "Pozor - možna izguba podatkov"
|
|||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Celsius (°C)"
|
msgid "Celsius (°C)"
|
||||||
msgstr ""
|
msgstr "Celzija (°C)"
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Change display units for metrics."
|
msgid "Change display units for metrics."
|
||||||
@@ -430,7 +456,7 @@ msgstr "Kopiraj YAML"
|
|||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "CPU"
|
msgid "CPU"
|
||||||
msgstr ""
|
msgstr "CPU"
|
||||||
|
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "CPU Cores"
|
msgid "CPU Cores"
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentacija"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Vnesite e-poštni naslov..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Vnesite svoje enkratno geslo."
|
msgstr "Vnesite svoje enkratno geslo."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Prehodni"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Obstoječi sistemi, ki niso definirani v <0>config.yml</0>, bodo izbrisa
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Izhod aktivno"
|
msgstr "Izhod aktivno"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Poteče po eni uri ali ob ponovnem zagonu huba."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Izvozi"
|
msgstr "Izvozi"
|
||||||
@@ -672,7 +706,7 @@ msgstr "Izvozi trenutne nastavitve sistema."
|
|||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Fahrenheit (°F)"
|
msgid "Fahrenheit (°F)"
|
||||||
msgstr ""
|
msgstr "Fahrenheit (°F)"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Failed"
|
msgid "Failed"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Neaktivno"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Napačen e-poštni naslov."
|
msgstr "Napačen e-poštni naslov."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Jedro"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Jezik"
|
msgstr "Jezik"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Največ 1 min"
|
msgstr "Največ 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Povprečna izkoriščenost na jedro"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Odstotek časa, preživetega v vsakem stanju"
|
msgstr "Odstotek časa, preživetega v vsakem stanju"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Trajen"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Vztrajnost"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "<0>Nastavite strežnik SMTP</0>, da zagotovite dostavo opozoril."
|
msgstr "<0>Nastavite strežnik SMTP</0>, da zagotovite dostavo opozoril."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Shrani nastavitve"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Shrani sistem"
|
msgstr "Shrani sistem"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Shranjeno v bazi podatkov in ne poteče, dokler ga ne onemogočite."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Razpored"
|
msgstr "Razpored"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Oblika časa"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "E-pošta za"
|
msgstr "E-pošta za"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Preklopi način mreže"
|
msgstr "Preklopi način mreže"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Sproži se, ko 5-minutna povprečna obremenitev preseže prag"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Sproži se, ko kateri koli senzor preseže prag"
|
msgstr "Sproži se, ko kateri koli senzor preseže prag"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Sproži, ko kombinacija gor/dol preseže prag"
|
msgstr "Sproži, ko kombinacija gor/dol preseže prag"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Neomejeno"
|
msgstr "Neomejeno"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Delujoč"
|
msgstr "Delujoč"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Posodobljeno vsakih 10 minut."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Naloži"
|
msgstr "Naloži"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Čas delovanja"
|
msgstr "Čas delovanja"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / potisna obvestila"
|
msgstr "Webhook / potisna obvestila"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Ko je omogočeno, ta žeton omogoča agentom samoregistracijo brez predhodnega ustvarjanja sistema. Poteče po eni uri ali ob ponovnem zagonu vozlišča."
|
msgstr "Ko je omogočen, ta žeton omogoča agentom samoregistracijo brez predhodnega ustvarjanja sistema."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"POT-Creation-Date: 2025-12-04 14:50-0500\n"
|
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
"Language: sr\n"
|
"Language: sr\n"
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: 2025-12-08 18:22\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: Serbian (Cyrillic)\n"
|
||||||
"Plural-Forms: \n"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
"X-Crowdin-Project: beszel\n"
|
||||||
|
"X-Crowdin-Project-ID: 733311\n"
|
||||||
|
"X-Crowdin-Language: sr\n"
|
||||||
|
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
|
||||||
|
"X-Crowdin-File-ID: 32\n"
|
||||||
|
|
||||||
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
|
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
|
||||||
#. placeholder {1}: table.getFilteredRowModel().rows.length
|
#. placeholder {1}: table.getFilteredRowModel().rows.length
|
||||||
@@ -19,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} од {1} редова изабрано."
|
msgstr "{0} од {1} редова изабрано."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# jezgro} few {# jezgra} other {# jezgara}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} дан} few {{countString} дана} other {{countString} дана}}"
|
msgstr "{count, plural, one {{countString} дан} few {{countString} дана} other {{countString} дана}}"
|
||||||
@@ -31,6 +40,10 @@ msgstr "{count, plural, one {{countString} сат} few {{countString} сата}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} минут} few {{countString} минута} many {{countString} минута} other {{countString} минута}}"
|
msgstr "{count, plural, one {{countString} минут} few {{countString} минута} many {{countString} минута} other {{countString} минута}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# nit} few {# niti} other {# niti}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 сат"
|
msgstr "1 сат"
|
||||||
@@ -175,7 +188,12 @@ msgstr "Просек"
|
|||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Просечна CPU употреба контејнера"
|
msgstr "Просечна искоришћеност процесора контејнера"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Prosek pada ispod <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
@@ -184,11 +202,11 @@ msgstr "Просек премашује <0>{value}{0}</0>"
|
|||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Average power consumption of GPUs"
|
msgid "Average power consumption of GPUs"
|
||||||
msgstr "Просечна потрошња енергије GPU-ова"
|
msgstr "Просечна потрошња енергије графичких картица"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Average system-wide CPU utilization"
|
msgid "Average system-wide CPU utilization"
|
||||||
msgstr "Просечна системска CPU употреба"
|
msgstr "Просечна системска искоришћеност процесор"
|
||||||
|
|
||||||
#. placeholder {0}: gpu.n
|
#. placeholder {0}: gpu.n
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
@@ -197,7 +215,7 @@ msgstr "Просечна употреба {0}"
|
|||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Average utilization of GPU engines"
|
msgid "Average utilization of GPU engines"
|
||||||
msgstr "Просечна употреба GPU енгине-а"
|
msgstr "Просечна искоришћеност мотора графичких картица"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/navbar.tsx
|
#: src/components/navbar.tsx
|
||||||
@@ -209,7 +227,13 @@ msgstr "Резервне копије"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Пропусни опсег"
|
msgstr "Пропусни опсег"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Батерија"
|
msgstr "Батерија"
|
||||||
|
|
||||||
@@ -225,6 +249,13 @@ msgstr "Постао неактиван"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Пре"
|
msgstr "Пре"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Ispod {0}{1} u poslednjih {2, plural, one {# minuti} few {# minuta} other {# minuta}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel подржава OpenID Connect и многе OAuth2 провајдере аутентификације."
|
msgstr "Beszel подржава OpenID Connect и многе OAuth2 провајдере аутентификације."
|
||||||
@@ -373,7 +404,7 @@ msgstr "Настави"
|
|||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "Copied to clipboard"
|
msgid "Copied to clipboard"
|
||||||
msgstr "Копирано у клипборд"
|
msgstr "Копирано у међуспремник"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
@@ -394,7 +425,7 @@ msgstr "Копирај env"
|
|||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Copy host"
|
msgid "Copy host"
|
||||||
msgstr "Копирај хост"
|
msgstr "Копирај хоста"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
@@ -425,7 +456,7 @@ msgstr "Копирај YAML"
|
|||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "CPU"
|
msgid "CPU"
|
||||||
msgstr ""
|
msgstr "Процесор"
|
||||||
|
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "CPU Cores"
|
msgid "CPU Cores"
|
||||||
@@ -433,7 +464,7 @@ msgstr "CPU језгра"
|
|||||||
|
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
msgid "CPU Peak"
|
msgid "CPU Peak"
|
||||||
msgstr "CPU пик"
|
msgstr "CPU врхунац"
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "CPU time"
|
msgid "CPU time"
|
||||||
@@ -441,14 +472,14 @@ msgstr "CPU време"
|
|||||||
|
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "CPU Time Breakdown"
|
msgid "CPU Time Breakdown"
|
||||||
msgstr "Растављање CPU времена"
|
msgstr "Расподела времена процесора"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "CPU Usage"
|
msgid "CPU Usage"
|
||||||
msgstr "CPU употреба"
|
msgstr "Искоришћеност процесора"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
@@ -532,7 +563,7 @@ msgstr "Диск I/O"
|
|||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Disk unit"
|
msgid "Disk unit"
|
||||||
msgstr "Јединица диска"
|
msgstr "Диск јединица"
|
||||||
|
|
||||||
#: src/components/charts/disk-chart.tsx
|
#: src/components/charts/disk-chart.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
@@ -563,7 +594,7 @@ msgstr "Документација"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -595,16 +626,16 @@ msgstr "Измени {foo}"
|
|||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
#: src/components/login/otp-forms.tsx
|
#: src/components/login/otp-forms.tsx
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Имејл"
|
msgstr "Е-пошта"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Email notifications"
|
msgid "Email notifications"
|
||||||
msgstr "Имејл обавештења"
|
msgstr "Обавештењe е-поштом"
|
||||||
|
|
||||||
#. Context: Battery state
|
#. Context: Battery state
|
||||||
#: src/lib/i18n.ts
|
#: src/lib/i18n.ts
|
||||||
msgid "Empty"
|
msgid "Empty"
|
||||||
msgstr "Празна"
|
msgstr "Празнo"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
@@ -613,16 +644,20 @@ msgstr "Време завршетка"
|
|||||||
|
|
||||||
#: src/components/login/login.tsx
|
#: src/components/login/login.tsx
|
||||||
msgid "Enter email address to reset password"
|
msgid "Enter email address to reset password"
|
||||||
msgstr "Унесите имејл адресу за ресетовање лозинке"
|
msgstr "Унесите адресу е-поште за ресетовање лозинке"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Enter email address..."
|
msgid "Enter email address..."
|
||||||
msgstr "Унесите имејл адресу..."
|
msgstr "Унесите адресу е-поште..."
|
||||||
|
|
||||||
#: src/components/login/otp-forms.tsx
|
#: src/components/login/otp-forms.tsx
|
||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Унесите вашу једнократну лозинку."
|
msgstr "Унесите вашу једнократну лозинку."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Ефемеран"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -647,23 +682,27 @@ msgstr "Главни PID извршавања"
|
|||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
|
||||||
msgstr ""
|
msgstr "Системи који нису дефинисани у <0>config.yml</0> биће обрисани. Молимо вас да редовно правите резервне копије."
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Излазак активан"
|
msgstr "Излазак активан"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Истиче након једног сата или при поновном покретању хаба."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Извези"
|
msgstr "Извези"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Export configuration"
|
msgid "Export configuration"
|
||||||
msgstr ""
|
msgstr "Извези конфигурацију"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "Export your current systems configuration."
|
msgid "Export your current systems configuration."
|
||||||
msgstr ""
|
msgstr "Извезите тренутну конфигурацију система."
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Fahrenheit (°F)"
|
msgid "Fahrenheit (°F)"
|
||||||
@@ -788,7 +827,7 @@ msgstr "Ако сте изгубили лозинку за ваш админис
|
|||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
msgctxt "Docker image"
|
msgctxt "Docker image"
|
||||||
msgid "Image"
|
msgid "Image"
|
||||||
msgstr ""
|
msgstr "Слика"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Inactive"
|
msgid "Inactive"
|
||||||
@@ -798,11 +837,6 @@ msgstr "Неактивно"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Неважећа имејл адреса."
|
msgstr "Неважећа имејл адреса."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Кернел"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Језик"
|
msgstr "Језик"
|
||||||
@@ -874,7 +908,7 @@ msgstr "Логови"
|
|||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
|
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
|
||||||
msgstr "Тражите где да креирате упозорења? Кликните на звона <0/> иконе у табели система."
|
msgstr "Тражите где да креирате упозорења? Кликните на звоно <0/> у табели система."
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Main PID"
|
msgid "Main PID"
|
||||||
@@ -895,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Макс 1 мин"
|
msgstr "Макс 1 мин"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -908,7 +943,7 @@ msgstr "Ограничење меморије"
|
|||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Memory Peak"
|
msgid "Memory Peak"
|
||||||
msgstr "Пик меморије"
|
msgstr "Врхунац меморије"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
@@ -956,7 +991,7 @@ msgstr "Мрежна јединица"
|
|||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr ""
|
msgstr "Не"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
@@ -1059,7 +1094,7 @@ msgstr "Захтев за ресетовање лозинке примљен"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Past"
|
msgid "Past"
|
||||||
msgstr "Прошло"
|
msgstr "Прошлост"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Pause"
|
msgid "Pause"
|
||||||
@@ -1082,6 +1117,14 @@ msgstr "Просечна употреба по језгру"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Проценат времена проведеног у сваком стању"
|
msgstr "Проценат времена проведеног у сваком стању"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Трајан"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Упорност"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Молимо вас <0>конфигуришите SMTP сервер</0> да бисте осигурали да се упозорења испоручују."
|
msgstr "Молимо вас <0>конфигуришите SMTP сервер</0> да бисте осигурали да се упозорења испоручују."
|
||||||
@@ -1093,7 +1136,7 @@ msgstr "Молимо вас проверите логове за више дет
|
|||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
msgid "Please check your credentials and try again"
|
msgid "Please check your credentials and try again"
|
||||||
msgstr "Молимо вас проверите ваше акредитиве и покушајте поново"
|
msgstr "Молимо вас проверите своје податке за пријаву и покушајте поново"
|
||||||
|
|
||||||
#: src/components/login/login.tsx
|
#: src/components/login/login.tsx
|
||||||
msgid "Please create an admin account"
|
msgid "Please create an admin account"
|
||||||
@@ -1101,11 +1144,11 @@ msgstr "Молимо вас креирајте администраторски
|
|||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Please enable pop-ups for this site"
|
msgid "Please enable pop-ups for this site"
|
||||||
msgstr "Молимо вас омогућите поп-упе за овај сајт"
|
msgstr "Молимо вас омогућите искачуће прозоре за овај сајт"
|
||||||
|
|
||||||
#: src/lib/api.ts
|
#: src/lib/api.ts
|
||||||
msgid "Please log in again"
|
msgid "Please log in again"
|
||||||
msgstr "Молимо вас пријавите се поново"
|
msgstr "Молимо вас да се пријавите поново"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Please see <0>the documentation</0> for instructions."
|
msgid "Please see <0>the documentation</0> for instructions."
|
||||||
@@ -1113,7 +1156,7 @@ msgstr "Молимо вас погледајте <0>документацију</
|
|||||||
|
|
||||||
#: src/components/login/login.tsx
|
#: src/components/login/login.tsx
|
||||||
msgid "Please sign in to your account"
|
msgid "Please sign in to your account"
|
||||||
msgstr "Молимо вас пријавите се на ваш налог"
|
msgstr "Молимо вас да се пријавите на ваш налог"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Port"
|
msgid "Port"
|
||||||
@@ -1122,7 +1165,7 @@ msgstr "Порт"
|
|||||||
#. Power On Time
|
#. Power On Time
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "Power On"
|
msgid "Power On"
|
||||||
msgstr "Укључен"
|
msgstr "Укључи"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
@@ -1223,11 +1266,11 @@ msgstr "S.M.A.R.T. детаљи"
|
|||||||
|
|
||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
msgid "S.M.A.R.T. Self-Test"
|
msgid "S.M.A.R.T. Self-Test"
|
||||||
msgstr "S.M.A.R.T. само-тест"
|
msgstr "S.M.A.R.T. самопровера"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
|
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
|
||||||
msgstr "Сачувајте адресу користећи enter тастер или зарез. Оставите празно да онемогућите имејл обавештења."
|
msgstr "Сачувајте адресу користећи enter тастер или зарез. Оставите празно да онемогућите обавештења путем е -поште."
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
@@ -1238,6 +1281,10 @@ msgstr "Сачувај подешавања"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Сачувај систем"
|
msgstr "Сачувај систем"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Сачувано у бази података и не истиче док га не онемогућите."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Распоред"
|
msgstr "Распоред"
|
||||||
@@ -1432,10 +1479,10 @@ msgstr "Формат времена"
|
|||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "На имејл(ове)"
|
msgstr "На е-пошту(е)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Укључи/искључи мрежу"
|
msgstr "Укључи/искључи мрежу"
|
||||||
|
|
||||||
@@ -1446,7 +1493,7 @@ msgstr "Промени тему"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Token"
|
msgid "Token"
|
||||||
msgstr ""
|
msgstr "Токен"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
@@ -1504,6 +1551,10 @@ msgstr "Окида се када просечно оптерећење од 5 м
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Окида се када било који сензор премаши праг"
|
msgstr "Окида се када било који сензор премаши праг"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Pokreće se kada nivo baterije padne ispod praga"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Окида се када комбиновано горе/доле премаши праг"
|
msgstr "Окида се када комбиновано горе/доле премаши праг"
|
||||||
@@ -1546,7 +1597,7 @@ msgstr "Преференце јединица"
|
|||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Universal token"
|
msgid "Universal token"
|
||||||
msgstr ""
|
msgstr "Универзални токен"
|
||||||
|
|
||||||
#. Context: Battery state
|
#. Context: Battery state
|
||||||
#: src/lib/i18n.ts
|
#: src/lib/i18n.ts
|
||||||
@@ -1559,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Неограничено"
|
msgstr "Неограничено"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Укључен"
|
msgstr "Укључен"
|
||||||
@@ -1576,7 +1627,7 @@ msgstr "Ажурирај"
|
|||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
msgid "Updated"
|
msgid "Updated"
|
||||||
msgstr ""
|
msgstr "Ажурирано"
|
||||||
|
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Updated every 10 minutes."
|
msgid "Updated every 10 minutes."
|
||||||
@@ -1584,9 +1635,9 @@ msgstr "Ажурира се сваких 10 минута."
|
|||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
#: src/components/routes/system/network-sheet.tsx
|
||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr ""
|
msgstr "Отпреми"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Време рада"
|
msgstr "Време рада"
|
||||||
|
|
||||||
@@ -1596,7 +1647,7 @@ msgstr "Време рада"
|
|||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr ""
|
msgstr "Употреба"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Usage of root partition"
|
msgid "Usage of root partition"
|
||||||
@@ -1605,7 +1656,7 @@ msgstr "Употреба root партиције"
|
|||||||
#: src/components/charts/mem-chart.tsx
|
#: src/components/charts/mem-chart.tsx
|
||||||
#: src/components/charts/swap-chart.tsx
|
#: src/components/charts/swap-chart.tsx
|
||||||
msgid "Used"
|
msgid "Used"
|
||||||
msgstr ""
|
msgstr "Коришћено"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/navbar.tsx
|
#: src/components/navbar.tsx
|
||||||
@@ -1647,7 +1698,7 @@ msgstr "Жели"
|
|||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Warning (%)"
|
msgid "Warning (%)"
|
||||||
msgstr ""
|
msgstr "Упозорење (%)"
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Warning thresholds"
|
msgid "Warning thresholds"
|
||||||
@@ -1655,27 +1706,27 @@ msgstr "Прагове упозорења"
|
|||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Webhook / Push notifications"
|
msgid "Webhook / Push notifications"
|
||||||
msgstr ""
|
msgstr "Webhook / Push обавештења"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Када је омогућено, овај токен омогућава агентима да се сами региструју без претходног креирања система. Истиче након једног сата или при поновном покретању хаба."
|
msgstr "Када је омогућен, овај токен омогућава агентима да се сами региструју без претходног креирања система."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgctxt "Button to copy install command"
|
msgctxt "Button to copy install command"
|
||||||
msgid "Windows command"
|
msgid "Windows command"
|
||||||
msgstr ""
|
msgstr "Windows команда"
|
||||||
|
|
||||||
#. Disk write
|
#. Disk write
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Write"
|
msgid "Write"
|
||||||
msgstr ""
|
msgstr "Писање"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "YAML Config"
|
msgid "YAML Config"
|
||||||
msgstr ""
|
msgstr "YAML конфигурација"
|
||||||
|
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
msgid "YAML Configuration"
|
msgid "YAML Configuration"
|
||||||
@@ -1685,7 +1736,7 @@ msgstr "YAML конфигурација"
|
|||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr ""
|
msgstr "Да"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Your user settings have been updated."
|
msgid "Your user settings have been updated."
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: sv\n"
|
"Language: sv\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-05 20:24\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Swedish\n"
|
"Language-Team: Swedish\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{0} av {1} rad(er) valda."
|
msgstr "{0} av {1} rad(er) valda."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# kärna} other {# kärnor}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} dag} other {{countString} dagar}}"
|
msgstr "{count, plural, one {{countString} dag} other {{countString} dagar}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} timme} other {{countString} timmar}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} minut} few {{countString} minuter} many {{countString} minuter} other {{countString} minuter}}"
|
msgstr "{count, plural, one {{countString} minut} few {{countString} minuter} many {{countString} minuter} other {{countString} minuter}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# tråd} other {# trådar}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 timme"
|
msgstr "1 timme"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Genomsnitt"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Genomsnittlig CPU-användning för containrar"
|
msgstr "Genomsnittlig CPU-användning för containrar"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Genomsnittet sjunker under <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Säkerhetskopior"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bandbredd"
|
msgstr "Bandbredd"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Batteri"
|
msgstr "Batteri"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Blev inaktiv"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Före"
|
msgstr "Före"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Under {0}{1} under de senaste {2, plural, one {# minuten} other {# minuterna}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel stöder OpenID Connect och många OAuth2-autentiseringsleverantörer."
|
msgstr "Beszel stöder OpenID Connect och många OAuth2-autentiseringsleverantörer."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokumentation"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Ange e-postadress..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Ange ditt engångslösenord."
|
msgstr "Ange ditt engångslösenord."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Flyktig"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Befintliga system som inte definieras i <0>config.yml</0> kommer att tas
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Avslutades aktivt"
|
msgstr "Avslutades aktivt"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Upphör efter en timme eller vid hub-omstart."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Exportera"
|
msgstr "Exportera"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Inaktiv"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Ogiltig e-postadress."
|
msgstr "Ogiltig e-postadress."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kärna"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Språk"
|
msgstr "Språk"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Max 1 min"
|
msgstr "Max 1 min"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Genomsnittlig användning per kärna"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Procentandel av tid spenderad i varje tillstånd"
|
msgstr "Procentandel av tid spenderad i varje tillstånd"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Permanent"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Beständighet"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Vänligen <0>konfigurera en SMTP-server</0> för att säkerställa att larm levereras."
|
msgstr "Vänligen <0>konfigurera en SMTP-server</0> för att säkerställa att larm levereras."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Spara inställningar"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Spara system"
|
msgstr "Spara system"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Sparad i databasen och upphör inte förrän du inaktiverar den."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Schema"
|
msgstr "Schema"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Tidsformat"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Till e-postadress(er)"
|
msgstr "Till e-postadress(er)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Växla rutnät"
|
msgstr "Växla rutnät"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Utlöses när 5-minuters genomsnittlig belastning överskrider ett trös
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Utlöses när någon sensor överskrider ett tröskelvärde"
|
msgstr "Utlöses när någon sensor överskrider ett tröskelvärde"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Utlöses när batteriladdningen sjunker under ett tröskelvärde"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Utlöses när kombinerad upp/ner överskrider ett tröskelvärde"
|
msgstr "Utlöses när kombinerad upp/ner överskrider ett tröskelvärde"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Upp"
|
msgstr "Upp"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Uppdateras var 10:e minut."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Ladda upp"
|
msgstr "Ladda upp"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Drifttid"
|
msgstr "Drifttid"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push-aviseringar"
|
msgstr "Webhook / Push-aviseringar"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "När aktiverad tillåter denna token agenter att självregistrera utan tidigare systemskapande. Upphör efter en timme eller vid hub-omstart."
|
msgstr "När aktiverad tillåter denna token agenter att självregistrera utan föregående systemskapande."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: tr\n"
|
"Language: tr\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Turkish\n"
|
"Language-Team: Turkish\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "{1} satırdan {0} tanesi seçildi."
|
msgstr "{1} satırdan {0} tanesi seçildi."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# çekirdek} other {# çekirdek}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} gün} other {{countString} gün}}"
|
msgstr "{count, plural, one {{countString} gün} other {{countString} gün}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} saat} other {{countString} saat}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} dakika} few {{countString} dakika} many {{countString} dakika} other {{countString} dakika}}"
|
msgstr "{count, plural, one {{countString} dakika} few {{countString} dakika} many {{countString} dakika} other {{countString} dakika}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# iş parçacığı} other {# iş parçacığı}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 saat"
|
msgstr "1 saat"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Ortalama"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Konteynerlerin ortalama CPU kullanımı"
|
msgstr "Konteynerlerin ortalama CPU kullanımı"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Ortalama <0>{value}{0}</0> altına düşüyor"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Yedekler"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Bant Genişliği"
|
msgstr "Bant Genişliği"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Pil"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Pil"
|
msgstr "Pil"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Pasif oldu"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Önce"
|
msgstr "Önce"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Son {2, plural, one {# dakika} other {# dakika}} içinde {0}{1} altında"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel, OpenID Connect ve birçok OAuth2 kimlik doğrulama sağlayıcısını destekler."
|
msgstr "Beszel, OpenID Connect ve birçok OAuth2 kimlik doğrulama sağlayıcısını destekler."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Dokümantasyon"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "E-posta adresini girin..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Tek kullanımlık şifrenizi girin."
|
msgstr "Tek kullanımlık şifrenizi girin."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Geçici"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "<0>config.yml</0> içinde tanımlanmayan mevcut sistemler silinecektir.
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Aktif olarak çıktı"
|
msgstr "Aktif olarak çıktı"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Bir saat sonra veya hub yeniden başlatıldığında sona erer."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Dışa aktar"
|
msgstr "Dışa aktar"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Pasif"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Geçersiz e-posta adresi."
|
msgstr "Geçersiz e-posta adresi."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Çekirdek"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Dil"
|
msgstr "Dil"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Maks 1 dk"
|
msgstr "Maks 1 dk"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Çekirdek başına ortalama kullanım"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Her durumda harcanan zamanın yüzdesi"
|
msgstr "Her durumda harcanan zamanın yüzdesi"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Kalıcı"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Kalıcılık"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Uyarıların teslim edilmesini sağlamak için lütfen bir SMTP sunucusu <0>yapılandırın</0>."
|
msgstr "Uyarıların teslim edilmesini sağlamak için lütfen bir SMTP sunucusu <0>yapılandırın</0>."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Ayarları Kaydet"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Sistemi kaydet"
|
msgstr "Sistemi kaydet"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Veritabanında kaydedilir ve siz devre dışı bırakana kadar süresi dolmaz."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Zamanla"
|
msgstr "Zamanla"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Zaman formatı"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "E-posta(lar)a"
|
msgstr "E-posta(lar)a"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Izgarayı değiştir"
|
msgstr "Izgarayı değiştir"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "5 dakikalık yük ortalaması bir eşiği aştığında tetiklenir"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Herhangi bir sensör bir eşiği aştığında tetiklenir"
|
msgstr "Herhangi bir sensör bir eşiği aştığında tetiklenir"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Pil şarjı bir eşiğin altına düştüğünde tetiklenir"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Birleştirilmiş yukarı/aşağı bir eşiği aştığında tetiklenir"
|
msgstr "Birleştirilmiş yukarı/aşağı bir eşiği aştığında tetiklenir"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Sınırsız"
|
msgstr "Sınırsız"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Açık"
|
msgstr "Açık"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Her 10 dakikada bir güncellenir."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Yükle"
|
msgstr "Yükle"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Çalışma Süresi"
|
msgstr "Çalışma Süresi"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Anlık bildirimler"
|
msgstr "Webhook / Anlık bildirimler"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Etkinleştirildiğinde, bu token agentların önceden sistem oluşturmadan kendilerini kaydetmelerine izin verir. Bir saat sonra veya hub yeniden başlatıldığında sona erer."
|
msgstr "Etkinleştirildiğinde, bu token aracıların önceden sistem oluşturmadan kendilerini kaydetmelerine izin verir."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: uk\n"
|
"Language: uk\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Ukrainian\n"
|
"Language-Team: Ukrainian\n"
|
||||||
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "Вибрано {0} з {1} рядків."
|
msgstr "Вибрано {0} з {1} рядків."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# ядро} few {# ядра} many {# ядер} other {# ядер}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} день} few {{countString} дні} many {{countString} днів} other {{countString} дня}}"
|
msgstr "{count, plural, one {{countString} день} few {{countString} дні} many {{countString} днів} other {{countString} дня}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} година} few {{countString} го
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} хвилина} few {{countString} хвилини} many {{countString} хвилин} other {{countString} хвилини}}"
|
msgstr "{count, plural, one {{countString} хвилина} few {{countString} хвилини} many {{countString} хвилин} other {{countString} хвилини}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# потік} few {# потоки} many {# потоків} other {# потоків}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 година"
|
msgstr "1 година"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Середнє"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Середнє використання CPU контейнерами"
|
msgstr "Середнє використання CPU контейнерами"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Середнє опускається нижче <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Резервні копії"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Пропускна здатність"
|
msgstr "Пропускна здатність"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Bat"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Батарея"
|
msgstr "Батарея"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Стало неактивним"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "До"
|
msgstr "До"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Нижче {0}{1} протягом {2, plural, one {останньої # хвилини} other {останніх # хвилин}}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel підтримує OpenID Connect та багато постачальників автентифікації OAuth2."
|
msgstr "Beszel підтримує OpenID Connect та багато постачальників автентифікації OAuth2."
|
||||||
@@ -568,7 +594,7 @@ msgstr "Документація"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Введіть адресу електронної пошти..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Введіть ваш одноразовий пароль."
|
msgstr "Введіть ваш одноразовий пароль."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Ефемерний"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Існуючі системи, не визначені в <0>config.yml<
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Завершилося активно"
|
msgstr "Завершилося активно"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Закінчується через годину або при перезапуску хаба."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Експорт"
|
msgstr "Експорт"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Неактивне"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Неправильна адреса електронної пошти."
|
msgstr "Неправильна адреса електронної пошти."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Ядро"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Мова"
|
msgstr "Мова"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Макс 1 хв"
|
msgstr "Макс 1 хв"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Середнє використання на ядро"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Відсоток часу, проведеного в кожному стані"
|
msgstr "Відсоток часу, проведеного в кожному стані"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Постійний"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Стійкість"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Будь ласка, <0>налаштуйте SMTP сервер</0>, щоб забезпечити доставку сповіщень."
|
msgstr "Будь ласка, <0>налаштуйте SMTP сервер</0>, щоб забезпечити доставку сповіщень."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Зберегти налаштування"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Зберегти систему"
|
msgstr "Зберегти систему"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Збережено в базі даних і не закінчується, поки ви його не вимкнете."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Розклад"
|
msgstr "Розклад"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Формат часу"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "На електронну пошту"
|
msgstr "На електронну пошту"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Перемкнути сітку"
|
msgstr "Перемкнути сітку"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Спрацьовує, коли середнє навантаження
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Спрацьовує, коли будь-який датчик перевищує поріг"
|
msgstr "Спрацьовує, коли будь-який датчик перевищує поріг"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Спрацьовує, коли заряд батареї опускається нижче порогу"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Спрацьовує, коли відправлення/отримання сумарно перевищує поріг"
|
msgstr "Спрацьовує, коли відправлення/отримання сумарно перевищує поріг"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Необмежено"
|
msgstr "Необмежено"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Працює"
|
msgstr "Працює"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Оновлюється кожні 10 хвилин."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Відвантажити"
|
msgstr "Відвантажити"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Час роботи"
|
msgstr "Час роботи"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / Push сповіщення"
|
msgstr "Webhook / Push сповіщення"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Коли увімкнено, цей токен дозволяє агентам самостійно реєструватися без попереднього створення системи. Термін дії закінчується через годину або при перезапуску хабу."
|
msgstr "При ввімкненні цей токен дозволяє агентам самостійно реєструватися без попереднього створення системи."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: vi\n"
|
"Language: vi\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Vietnamese\n"
|
"Language-Team: Vietnamese\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "Đã chọn {0} trên {1} hàng."
|
msgstr "Đã chọn {0} trên {1} hàng."
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# nhân} other {# nhân}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} ngày} other {{countString} ngày}}"
|
msgstr "{count, plural, one {{countString} ngày} other {{countString} ngày}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} giờ} other {{countString} giờ}}"
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} phút} few {{countString} phút} many {{countString} phút} other {{countString} phút}}"
|
msgstr "{count, plural, one {{countString} phút} few {{countString} phút} many {{countString} phút} other {{countString} phút}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# luồng} other {# luồng}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 giờ"
|
msgstr "1 giờ"
|
||||||
@@ -101,7 +109,7 @@ msgstr "Trạng thái hoạt động"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Add {foo}"
|
msgid "Add {foo}"
|
||||||
msgstr ""
|
msgstr "Thêm {foo}"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Add <0>System</0>"
|
msgid "Add <0>System</0>"
|
||||||
@@ -182,6 +190,11 @@ msgstr "Trung bình"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "Sử dụng CPU trung bình của các container"
|
msgstr "Sử dụng CPU trung bình của các container"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "Trung bình giảm xuống dưới <0>{value}{0}</0>"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "Sao lưu"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "Băng thông"
|
msgstr "Băng thông"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "Pin"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "Pin"
|
msgstr "Pin"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "Đã trở thành không hoạt động"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "Trước"
|
msgstr "Trước"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "Dưới {0}{1} trong {2, plural, one {# phút} other {# phút}} qua"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel hỗ trợ OpenID Connect và nhiều nhà cung cấp xác thực OAuth2."
|
msgstr "Beszel hỗ trợ OpenID Connect và nhiều nhà cung cấp xác thực OAuth2."
|
||||||
@@ -430,7 +456,7 @@ msgstr "Sao chép YAML"
|
|||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "CPU"
|
msgid "CPU"
|
||||||
msgstr ""
|
msgstr "CPU"
|
||||||
|
|
||||||
#: src/components/routes/system/cpu-sheet.tsx
|
#: src/components/routes/system/cpu-sheet.tsx
|
||||||
msgid "CPU Cores"
|
msgid "CPU Cores"
|
||||||
@@ -568,7 +594,7 @@ msgstr "Tài liệu"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -594,13 +620,13 @@ msgstr "Chỉnh sửa"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Edit {foo}"
|
msgid "Edit {foo}"
|
||||||
msgstr ""
|
msgstr "Chỉnh sửa {foo}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
#: src/components/login/otp-forms.tsx
|
#: src/components/login/otp-forms.tsx
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr "Email"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Email notifications"
|
msgid "Email notifications"
|
||||||
@@ -628,6 +654,10 @@ msgstr "Nhập địa chỉ email..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "Nhập mật khẩu một lần của bạn."
|
msgstr "Nhập mật khẩu một lần của bạn."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "Tạm thời"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "Các hệ thống hiện có không được định nghĩa trong <0>con
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "Đã thoát khi hoạt động"
|
msgstr "Đã thoát khi hoạt động"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "Hết hạn sau một giờ hoặc khi khởi động lại hub."
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "Xuất"
|
msgstr "Xuất"
|
||||||
@@ -803,11 +837,6 @@ msgstr "Không hoạt động"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "Địa chỉ email không hợp lệ."
|
msgstr "Địa chỉ email không hợp lệ."
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Nhân"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Ngôn ngữ"
|
msgstr "Ngôn ngữ"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "Tối đa 1 phút"
|
msgstr "Tối đa 1 phút"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "Tỷ lệ sử dụng trung bình mỗi nhân"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "Phần trăm thời gian dành cho mỗi trạng thái"
|
msgstr "Phần trăm thời gian dành cho mỗi trạng thái"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "Vĩnh viễn"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "Tính bền vững"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "Vui lòng <0>cấu hình máy chủ SMTP</0> để đảm bảo cảnh báo được gửi đi."
|
msgstr "Vui lòng <0>cấu hình máy chủ SMTP</0> để đảm bảo cảnh báo được gửi đi."
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "Lưu Cài đặt"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "Lưu hệ thống"
|
msgstr "Lưu hệ thống"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "Được lưu trong cơ sở dữ liệu và không hết hạn cho đến khi bạn tắt nó."
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Lịch trình"
|
msgstr "Lịch trình"
|
||||||
@@ -1269,7 +1311,7 @@ msgstr "Xem <0>cài đặt thông báo</0> để cấu hình cách bạn nhận
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Select {foo}"
|
msgid "Select {foo}"
|
||||||
msgstr ""
|
msgstr "Chọn {foo}"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Sent"
|
msgid "Sent"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "Định dạng thời gian"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Đến email(s)"
|
msgstr "Đến email(s)"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "Chuyển đổi lưới"
|
msgstr "Chuyển đổi lưới"
|
||||||
|
|
||||||
@@ -1451,7 +1493,7 @@ msgstr "Chuyển đổi chủ đề"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Token"
|
msgid "Token"
|
||||||
msgstr ""
|
msgstr "Token"
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "Kích hoạt khi tải trung bình 5 phút vượt quá ngưỡng"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "Kích hoạt khi bất kỳ cảm biến nào vượt quá ngưỡng"
|
msgstr "Kích hoạt khi bất kỳ cảm biến nào vượt quá ngưỡng"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "Kích hoạt khi mức pin giảm xuống dưới ngưỡng"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "Kích hoạt khi kết hợp lên/xuống vượt quá ngưỡng"
|
msgstr "Kích hoạt khi kết hợp lên/xuống vượt quá ngưỡng"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "Không giới hạn"
|
msgstr "Không giới hạn"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "Hoạt động"
|
msgstr "Hoạt động"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "Cập nhật mỗi 10 phút."
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Tải lên"
|
msgstr "Tải lên"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "Thời gian hoạt động"
|
msgstr "Thời gian hoạt động"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Thông báo Webhook / Push"
|
msgstr "Thông báo Webhook / Push"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "Khi được bật, token này cho phép các tác nhân tự đăng ký mà không cần tạo hệ thống trước. Hết hạn sau một giờ hoặc khi khởi động lại trung tâm."
|
msgstr "Khi được bật, token này cho phép các tác nhân tự đăng ký mà không cần tạo hệ thống trước."
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: zh\n"
|
"Language: zh\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Chinese Simplified\n"
|
"Language-Team: Chinese Simplified\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "已选择 {0} / {1} 行"
|
msgstr "已选择 {0} / {1} 行"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} 小时} other {{countString} 小时}}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} 分钟} few {{countString} 分钟} many {{countString} 分钟} other {{countString} 分钟}}"
|
msgstr "{count, plural, one {{countString} 分钟} few {{countString} 分钟} many {{countString} 分钟} other {{countString} 分钟}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# 线程} other {# 线程}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1 小时"
|
msgstr "1 小时"
|
||||||
@@ -182,6 +190,11 @@ msgstr "平均"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "容器的平均 CPU 使用率"
|
msgstr "容器的平均 CPU 使用率"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "平均值降至<0>{value}{0}</0>以下"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "备份"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "带宽"
|
msgstr "带宽"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "电池"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "电池"
|
msgstr "电池"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "变为非活动"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "之前"
|
msgstr "之前"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "在过去的{2, plural, one {# 分钟} other {# 分钟}}中低于{0}{1}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel 支持 OpenID Connect 和其他 OAuth2 认证方式。"
|
msgstr "Beszel 支持 OpenID Connect 和其他 OAuth2 认证方式。"
|
||||||
@@ -568,7 +594,7 @@ msgstr "文档"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "输入电子邮件地址..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "输入您的一次性密码。"
|
msgstr "输入您的一次性密码。"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "临时"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "未在<0>config.yml</0>中定义的客户端将被删除。请定期备
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "退出活动状态"
|
msgstr "退出活动状态"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "一小时后或重新启动集线器时过期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "导出"
|
msgstr "导出"
|
||||||
@@ -803,11 +837,6 @@ msgstr "非活跃"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "无效的电子邮件地址。"
|
msgstr "无效的电子邮件地址。"
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "内核"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "语言"
|
msgstr "语言"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "1分钟内最大值"
|
msgstr "1分钟内最大值"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "每个核心的平均利用率"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "在每个状态下花费的时间百分比"
|
msgstr "在每个状态下花费的时间百分比"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "永久"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "持久性"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "请<0>配置 SMTP 服务器</0>以确保警报被传递。"
|
msgstr "请<0>配置 SMTP 服务器</0>以确保警报被传递。"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "保存设置"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "保存系统"
|
msgstr "保存系统"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "保存在数据库中,在您禁用之前不会过期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "计划"
|
msgstr "计划"
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "时间格式"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "发送到电子邮件"
|
msgstr "发送到电子邮件"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "切换网格"
|
msgstr "切换网格"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "当 5 分钟内的平均负载超过阈值时触发"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "当任何传感器超过阈值时触发"
|
msgstr "当任何传感器超过阈值时触发"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "当电池电量降至阈值以下时触发"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "当网络的上/下行速度超过阈值时触发"
|
msgstr "当网络的上/下行速度超过阈值时触发"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "无限制"
|
msgstr "无限制"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "在线"
|
msgstr "在线"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "每 10 分钟更新一次。"
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "上传"
|
msgstr "上传"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "正常运行时间"
|
msgstr "正常运行时间"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / 推送通知"
|
msgstr "Webhook / 推送通知"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "启用时,此令牌允许客户端在无需预先创建系统的情况下自动注册。在一小时后或中心重启时过期。"
|
msgstr "启用后,此令牌允许代理无需事先创建系统即可自行注册。"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: zh\n"
|
"Language: zh\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-11-14 22:51\n"
|
"PO-Revision-Date: 2025-12-02 23:18\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Chinese Traditional, Hong Kong\n"
|
"Language-Team: Chinese Traditional, Hong Kong\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "已選擇 {1} 個項目中的 {0} 個"
|
msgstr "已選擇 {1} 個項目中的 {0} 個"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} 小時} other {{countString} 小時}}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
|
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# 執行緒} other {# 執行緒}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1小時"
|
msgstr "1小時"
|
||||||
@@ -182,6 +190,11 @@ msgstr "平均"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "容器的平均 CPU 使用率"
|
msgstr "容器的平均 CPU 使用率"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "平均值降至<0>{value}{0}</0>以下"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "備份"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "帶寬"
|
msgstr "帶寬"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "電池"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "電池"
|
msgstr "電池"
|
||||||
|
|
||||||
@@ -230,6 +249,13 @@ msgstr "變為非活動"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "之前"
|
msgstr "之前"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中低於{0}{1}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel支持OpenID Connect和許多OAuth2認證提供者。"
|
msgstr "Beszel支持OpenID Connect和許多OAuth2認證提供者。"
|
||||||
@@ -568,7 +594,7 @@ msgstr "文件"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -628,6 +654,10 @@ msgstr "輸入電子郵件地址..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "輸入您的一次性密碼。"
|
msgstr "輸入您的一次性密碼。"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "臨時"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "未在<0>config.yml</0>中定義的現有系統將被刪除。請定期
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "退出活動狀態"
|
msgstr "退出活動狀態"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "一小時後或重新啟動集線器時過期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "匯出"
|
msgstr "匯出"
|
||||||
@@ -803,11 +837,6 @@ msgstr "未啟用"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "無效的電子郵件地址。"
|
msgstr "無效的電子郵件地址。"
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "核心"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "語言"
|
msgstr "語言"
|
||||||
@@ -900,6 +929,7 @@ msgid "Max 1 min"
|
|||||||
msgstr "一分鐘內最大值"
|
msgstr "一分鐘內最大值"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1087,6 +1117,14 @@ msgstr "每個核心的平均使用率"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "在每個狀態下花費的時間百分比"
|
msgstr "在每個狀態下花費的時間百分比"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "永久"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "持久性"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "請<0>配置SMTP伺服器</0>以確保警報被傳送。"
|
msgstr "請<0>配置SMTP伺服器</0>以確保警報被傳送。"
|
||||||
@@ -1243,6 +1281,10 @@ msgstr "儲存設定"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "儲存系統"
|
msgstr "儲存系統"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "儲存在資料庫中,在您停用之前不會過期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "時間格式"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "發送到電子郵件"
|
msgstr "發送到電子郵件"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "切換網格"
|
msgstr "切換網格"
|
||||||
|
|
||||||
@@ -1509,6 +1551,10 @@ msgstr "當 5 分鐘平均負載超過閾值時觸發"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "當任何傳感器超過閾值時觸發"
|
msgstr "當任何傳感器超過閾值時觸發"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "當電池電量降至閾值以下時觸發"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "當組合的上/下超過閾值時觸發"
|
msgstr "當組合的上/下超過閾值時觸發"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "無限制"
|
msgstr "無限制"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "上線"
|
msgstr "上線"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "每 10 分鐘更新一次。"
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "上傳"
|
msgstr "上傳"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "正常運行時間"
|
msgstr "正常運行時間"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / 推送通知"
|
msgstr "Webhook / 推送通知"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "啟用時,此令牌允許代理程式在無需預先創建系統的情況下自動註冊。在一小時後或中心重啟時過期。"
|
msgstr "啟用後,此權杖允許代理無需事先建立系統即可自行註冊。"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Language: zh\n"
|
"Language: zh\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-12-01 23:32\n"
|
"PO-Revision-Date: 2026-01-10 17:34\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Chinese Traditional\n"
|
"Language-Team: Chinese Traditional\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
@@ -24,6 +24,10 @@ msgstr ""
|
|||||||
msgid "{0} of {1} row(s) selected."
|
msgid "{0} of {1} row(s) selected."
|
||||||
msgstr "已選取 {1} 個項目中的 {0} 個"
|
msgstr "已選取 {1} 個項目中的 {0} 個"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{cores, plural, one {# core} other {# cores}}"
|
||||||
|
msgstr "{cores, plural, one {# 核心} other {# 核心}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
|
||||||
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
msgstr "{count, plural, one {{countString} 天} other {{countString} 天}}"
|
||||||
@@ -36,6 +40,10 @@ msgstr "{count, plural, one {{countString} 小時} other {{countString} 小時}}
|
|||||||
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
|
||||||
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
|
msgstr "{count, plural, one {{countString} 分鐘} few {{countString} 分鐘} many {{countString} 分鐘} other {{countString} 分鐘}}"
|
||||||
|
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
|
msgid "{threads, plural, one {# thread} other {# threads}}"
|
||||||
|
msgstr "{threads, plural, one {# 執行緒} other {# 執行緒}}"
|
||||||
|
|
||||||
#: src/lib/utils.ts
|
#: src/lib/utils.ts
|
||||||
msgid "1 hour"
|
msgid "1 hour"
|
||||||
msgstr "1小時"
|
msgstr "1小時"
|
||||||
@@ -101,7 +109,7 @@ msgstr "活動狀態"
|
|||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Add {foo}"
|
msgid "Add {foo}"
|
||||||
msgstr ""
|
msgstr "新增{foo}"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Add <0>System</0>"
|
msgid "Add <0>System</0>"
|
||||||
@@ -172,7 +180,7 @@ msgstr "您確定嗎?"
|
|||||||
|
|
||||||
#: src/components/copy-to-clipboard.tsx
|
#: src/components/copy-to-clipboard.tsx
|
||||||
msgid "Automatic copy requires a secure context."
|
msgid "Automatic copy requires a secure context."
|
||||||
msgstr "只有在受保護的環境才能自動複製。"
|
msgstr "只有在受保護的環境(HTTPS)才能自動複製。"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Average"
|
msgid "Average"
|
||||||
@@ -182,6 +190,11 @@ msgstr "平均"
|
|||||||
msgid "Average CPU utilization of containers"
|
msgid "Average CPU utilization of containers"
|
||||||
msgstr "容器的平均 CPU 使用率"
|
msgstr "容器的平均 CPU 使用率"
|
||||||
|
|
||||||
|
#. placeholder {0}: alertData.unit
|
||||||
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
|
msgid "Average drops below <0>{value}{0}</0>"
|
||||||
|
msgstr "平均值降至<0>{value}{0}</0>以下"
|
||||||
|
|
||||||
#. placeholder {0}: alertData.unit
|
#. placeholder {0}: alertData.unit
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Average exceeds <0>{value}{0}</0>"
|
msgid "Average exceeds <0>{value}{0}</0>"
|
||||||
@@ -214,7 +227,13 @@ msgstr "備份"
|
|||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "網路流量"
|
msgstr "網路流量"
|
||||||
|
|
||||||
|
#. Battery label in systems table header
|
||||||
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
|
msgid "Bat"
|
||||||
|
msgstr "電池"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
|
#: src/lib/alerts.ts
|
||||||
msgid "Battery"
|
msgid "Battery"
|
||||||
msgstr "電池"
|
msgstr "電池"
|
||||||
|
|
||||||
@@ -230,9 +249,16 @@ msgstr "停用"
|
|||||||
msgid "Before"
|
msgid "Before"
|
||||||
msgstr "之前"
|
msgstr "之前"
|
||||||
|
|
||||||
|
#. placeholder {0}: alert.value
|
||||||
|
#. placeholder {1}: info.unit
|
||||||
|
#. placeholder {2}: alert.min
|
||||||
|
#: src/components/active-alerts.tsx
|
||||||
|
msgid "Below {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
|
||||||
|
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中低於{0}{1}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
|
||||||
msgstr "Beszel支援OpenID Connect和許多OAuth2認證提供者。"
|
msgstr "Beszel 支援 OpenID Connect 和許多 OAuth2 認證提供者。"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
|
||||||
@@ -317,7 +343,7 @@ msgstr "圖表選項"
|
|||||||
|
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
msgid "Check {email} for a reset link."
|
msgid "Check {email} for a reset link."
|
||||||
msgstr "檢查{email}以取得重設連結。"
|
msgstr "檢查 {email} 以取得重設連結。"
|
||||||
|
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Check logs for more details."
|
msgid "Check logs for more details."
|
||||||
@@ -331,7 +357,7 @@ msgstr "檢查您的通知服務"
|
|||||||
#: src/components/routes/system/smart-table.tsx
|
#: src/components/routes/system/smart-table.tsx
|
||||||
#: src/components/systems-table/systems-table.tsx
|
#: src/components/systems-table/systems-table.tsx
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr ""
|
msgstr "清除"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table.tsx
|
#: src/components/containers-table/containers-table.tsx
|
||||||
msgid "Click on a container to view more information."
|
msgid "Click on a container to view more information."
|
||||||
@@ -424,7 +450,7 @@ msgstr "複製下面的代理程式<0>docker-compose.yml</0>內容,或使用<1
|
|||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "Copy YAML"
|
msgid "Copy YAML"
|
||||||
msgstr "複製YAML"
|
msgstr "複製 YAML"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
@@ -568,7 +594,7 @@ msgstr "文件"
|
|||||||
|
|
||||||
#. Context: System is down
|
#. Context: System is down
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Down"
|
msgid "Down"
|
||||||
@@ -594,7 +620,7 @@ msgstr "編輯"
|
|||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Edit {foo}"
|
msgid "Edit {foo}"
|
||||||
msgstr ""
|
msgstr "編輯{foo}"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
@@ -628,6 +654,10 @@ msgstr "輸入電子郵件地址..."
|
|||||||
msgid "Enter your one-time password."
|
msgid "Enter your one-time password."
|
||||||
msgstr "輸入您的一次性密碼。"
|
msgstr "輸入您的一次性密碼。"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Ephemeral"
|
||||||
|
msgstr "臨時"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -658,6 +688,10 @@ msgstr "未在 <0>config.yml</0> 中定義的現有系統將會被刪除。請
|
|||||||
msgid "Exited active"
|
msgid "Exited active"
|
||||||
msgstr "結束"
|
msgstr "結束"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Expires after one hour or on hub restart."
|
||||||
|
msgstr "一小時後或重新啟動集線器時過期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr "匯出"
|
msgstr "匯出"
|
||||||
@@ -803,11 +837,6 @@ msgstr "未啟用"
|
|||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "無效的電子郵件地址。"
|
msgstr "無效的電子郵件地址。"
|
||||||
|
|
||||||
#. Linux kernel
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Kernel"
|
|
||||||
msgstr "Kernel"
|
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "語言"
|
msgstr "語言"
|
||||||
@@ -897,9 +926,10 @@ msgstr "手動設定說明"
|
|||||||
#. Chart select field. Please try to keep this short.
|
#. Chart select field. Please try to keep this short.
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Max 1 min"
|
msgid "Max 1 min"
|
||||||
msgstr "最多1分鐘"
|
msgstr "最多 1 分鐘"
|
||||||
|
|
||||||
#: src/components/containers-table/containers-table-columns.tsx
|
#: src/components/containers-table/containers-table-columns.tsx
|
||||||
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||||
#: src/components/systemd-table/systemd-table.tsx
|
#: src/components/systemd-table/systemd-table.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -1052,7 +1082,7 @@ msgstr "密碼"
|
|||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Password must be at least 8 characters."
|
msgid "Password must be at least 8 characters."
|
||||||
msgstr "密碼需要至少8個字元"
|
msgstr "密碼需要至少 8 個字元。"
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
msgid "Password must be less than 72 bytes."
|
msgid "Password must be less than 72 bytes."
|
||||||
@@ -1064,7 +1094,7 @@ msgstr "已收到密碼重設請求"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Past"
|
msgid "Past"
|
||||||
msgstr ""
|
msgstr "已過期"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Pause"
|
msgid "Pause"
|
||||||
@@ -1087,9 +1117,17 @@ msgstr "核心平均使用率"
|
|||||||
msgid "Percentage of time spent in each state"
|
msgid "Percentage of time spent in each state"
|
||||||
msgstr "狀態時間佔比"
|
msgstr "狀態時間佔比"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Permanent"
|
||||||
|
msgstr "永久"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Persistence"
|
||||||
|
msgstr "持久性"
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
|
||||||
msgstr "請<0>設定一個SMTP 伺服器</0>以確保能傳送警報。"
|
msgstr "請<0>設定一個 SMTP 伺服器</0>以確保能傳送警報。"
|
||||||
|
|
||||||
#: src/components/alerts/alerts-sheet.tsx
|
#: src/components/alerts/alerts-sheet.tsx
|
||||||
msgid "Please check logs for more details."
|
msgid "Please check logs for more details."
|
||||||
@@ -1243,9 +1281,13 @@ msgstr "儲存設定"
|
|||||||
msgid "Save system"
|
msgid "Save system"
|
||||||
msgstr "儲存系統"
|
msgstr "儲存系統"
|
||||||
|
|
||||||
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
msgid "Saved in the database and does not expire until you disable it."
|
||||||
|
msgstr "保存在資料庫中,在您停用之前不會過期。"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr ""
|
msgstr "排程"
|
||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Schedule quiet hours where notifications will not be sent, such as during maintenance periods."
|
msgid "Schedule quiet hours where notifications will not be sent, such as during maintenance periods."
|
||||||
@@ -1269,7 +1311,7 @@ msgstr "查看<0>通知設定</0>以設定您如何接收警報。"
|
|||||||
|
|
||||||
#: src/components/routes/settings/quiet-hours.tsx
|
#: src/components/routes/settings/quiet-hours.tsx
|
||||||
msgid "Select {foo}"
|
msgid "Select {foo}"
|
||||||
msgstr ""
|
msgstr "選取{foo}"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Sent"
|
msgid "Sent"
|
||||||
@@ -1344,7 +1386,7 @@ msgstr "系統的虛擬記憶體使用量"
|
|||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Swap Usage"
|
msgid "Swap Usage"
|
||||||
msgstr "虛擬記憶體使用量"
|
msgstr "交換空間使用量"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
@@ -1439,8 +1481,8 @@ msgstr "時間格式"
|
|||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "發送到電子郵件"
|
msgstr "發送到電子郵件"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Toggle grid"
|
msgid "Toggle grid"
|
||||||
msgstr "切換網格"
|
msgstr "切換網格"
|
||||||
|
|
||||||
@@ -1509,13 +1551,17 @@ msgstr "當 5 分鐘平均負載超過閾值時觸發"
|
|||||||
msgid "Triggers when any sensor exceeds a threshold"
|
msgid "Triggers when any sensor exceeds a threshold"
|
||||||
msgstr "當任何感應器超過閾值時觸發"
|
msgstr "當任何感應器超過閾值時觸發"
|
||||||
|
|
||||||
|
#: src/lib/alerts.ts
|
||||||
|
msgid "Triggers when battery charge drops below a threshold"
|
||||||
|
msgstr "當電池電量降至閾值以下時觸發"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when combined up/down exceeds a threshold"
|
msgid "Triggers when combined up/down exceeds a threshold"
|
||||||
msgstr "當總流量超過閾值時觸發"
|
msgstr "當總流量超過閾值時觸發"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when CPU usage exceeds a threshold"
|
msgid "Triggers when CPU usage exceeds a threshold"
|
||||||
msgstr "當CPU使用率超過閾值時觸發"
|
msgstr "當 CPU 使用率超過閾值時觸發"
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when GPU usage exceeds a threshold"
|
msgid "Triggers when GPU usage exceeds a threshold"
|
||||||
@@ -1564,7 +1610,7 @@ msgid "Unlimited"
|
|||||||
msgstr "無限制"
|
msgstr "無限制"
|
||||||
|
|
||||||
#. Context: System is up
|
#. Context: System is up
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Up"
|
msgid "Up"
|
||||||
msgstr "上線"
|
msgstr "上線"
|
||||||
@@ -1591,7 +1637,7 @@ msgstr "每 10 分鐘更新一次。"
|
|||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "上傳"
|
msgstr "上傳"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system/info-bar.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr "運行時間"
|
msgstr "運行時間"
|
||||||
|
|
||||||
@@ -1663,8 +1709,8 @@ msgid "Webhook / Push notifications"
|
|||||||
msgstr "Webhook / 推送通知"
|
msgstr "Webhook / 推送通知"
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
msgid "When enabled, this token allows agents to self-register without prior system creation. Expires after one hour or on hub restart."
|
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||||
msgstr "啟用時,此令牌允許代理程式在沒有預先建立系統的情況下自動註冊。在一小時後或 Hub 重啟時過期。"
|
msgstr "啟用後,此令牌允許代理無需事先建立系統即可自行註冊。"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
|
|||||||
@@ -1,8 +1,58 @@
|
|||||||
|
## 0.18.2
|
||||||
|
|
||||||
|
- Add separate dynamically linked glibc build for Linux. (#1618)
|
||||||
|
|
||||||
|
- Fix GPU ID collision between Intel and NVIDIA collectors. (#1522)
|
||||||
|
|
||||||
|
- Only hide GPU engine graph if entire usage is 0%. (#1624)
|
||||||
|
|
||||||
|
- Add Jetson tegrastats regex support for pre-Jetpack 5 versions. (#1631)
|
||||||
|
|
||||||
|
- Improve Indonesian translations. (#1625)
|
||||||
|
|
||||||
|
## 0.18.1
|
||||||
|
|
||||||
|
- Fix bug in 0.18.0 where all containers were cleared from the "All Containers" page when any system returned no containers.
|
||||||
|
|
||||||
## 0.18.0
|
## 0.18.0
|
||||||
|
|
||||||
- Remove `la1`, `la5`, `la15` fields from `Info` struct in favor of `la` array.
|
- Add experimental NVML GPU collector. (#1522, #1587)
|
||||||
|
|
||||||
- Remove `MB` bandwidth values in favor of bytes.
|
- Add low battery alerts. (#1507)
|
||||||
|
|
||||||
|
- Add battery charge to systems table.
|
||||||
|
|
||||||
|
- Add option to make universal token permanent. (#1097, #1614)
|
||||||
|
|
||||||
|
- Add `--url` and `--token` command line arguments to the agent. (#1524)
|
||||||
|
|
||||||
|
- Collect S.M.A.R.T. data in the background every hour.
|
||||||
|
|
||||||
|
- Add `SMART_INTERVAL` environment variable to customize S.M.A.R.T. data collection interval.
|
||||||
|
|
||||||
|
- Collect system distribution and architecture.
|
||||||
|
|
||||||
|
- Add `system_details` collection to store infrequently updated system information.
|
||||||
|
|
||||||
|
- Improve S.M.A.R.T. device path lookup for NVMe devices. (#1504)
|
||||||
|
|
||||||
|
- Use origin country flags for Spanish, Portuguese, English languages. (#1571)
|
||||||
|
|
||||||
|
- Raise `smartctl` timeout to 15 seconds. (#1465)
|
||||||
|
|
||||||
|
- Skip known non-unique product UUID when generating fingerprints. (#1556)
|
||||||
|
|
||||||
|
- Fix container logs decoding for raw streams. (#1535)
|
||||||
|
|
||||||
|
- Fix capacity sorting in S.M.A.R.T. table. (#1551)
|
||||||
|
|
||||||
|
- Fix loader visibility when no systems are present. (#1511)
|
||||||
|
|
||||||
|
- Rename login honeypot field to prevent password manager autofill (#1011).
|
||||||
|
|
||||||
|
- Add Serbian and Bahasa Indonesia translations.
|
||||||
|
|
||||||
|
- Update Go dependencies.
|
||||||
|
|
||||||
## 0.17.0
|
## 0.17.0
|
||||||
|
|
||||||
@@ -288,4 +338,4 @@ Note that the default memory calculation changed in this release, which may caus
|
|||||||
|
|
||||||
## Older
|
## Older
|
||||||
|
|
||||||
Release notes are available at https://github.com/henrygd/beszel/releases
|
Release notes are available at <https://github.com/henrygd/beszel/releases>
|
||||||
|
|||||||
Reference in New Issue
Block a user