Compare commits

...
51 Commits
Author SHA1 Message Date
hank 6914f01b92 New translations en.po (German)
[ci skip]
2026-09-09 21:46:10 -04:00
hank b1b13c3102 New translations en.po (Arabic)
[ci skip]
2026-09-09 21:46:09 -04:00
hank 4f22bf0246 New translations en.po (Uzbek)
[ci skip]
2026-09-09 21:46:08 -04:00
hank c8e4ff6936 New translations en.po (Chinese Traditional, Hong Kong)
[ci skip]
2026-09-09 21:46:06 -04:00
hank 009a47be93 New translations en.po (Croatian)
[ci skip]
2026-09-09 21:46:05 -04:00
hank 100512bcfe New translations en.po (Persian)
[ci skip]
2026-09-09 21:46:04 -04:00
hank d3364d5658 New translations en.po (Indonesian)
[ci skip]
2026-09-09 21:46:02 -04:00
hank c9e4aeefa5 New translations en.po (Vietnamese)
[ci skip]
2026-09-09 21:46:01 -04:00
hank 6cdc829acd New translations en.po (Chinese Traditional)
[ci skip]
2026-09-09 21:46:00 -04:00
hank 791a9ffa05 New translations en.po (Chinese Simplified)
[ci skip]
2026-09-09 21:45:58 -04:00
hank d8a5a91413 New translations en.po (Ukrainian)
[ci skip]
2026-09-09 21:45:57 -04:00
hank 2fde2c204e New translations en.po (Turkish)
[ci skip]
2026-09-09 21:45:55 -04:00
hank fad6e33604 New translations en.po (Swedish)
[ci skip]
2026-09-09 21:45:54 -04:00
hank 444ea9d8f7 New translations en.po (Serbian (Cyrillic))
[ci skip]
2026-09-09 21:45:53 -04:00
hank 4848335c31 New translations en.po (Slovenian)
[ci skip]
2026-09-09 21:45:51 -04:00
hank bbaedb6a06 New translations en.po (Russian)
[ci skip]
2026-09-09 21:45:50 -04:00
hank 3a3cc6811a New translations en.po (Portuguese)
[ci skip]
2026-09-09 21:45:48 -04:00
hank 3a982dbbb7 New translations en.po (Polish)
[ci skip]
2026-09-09 21:45:47 -04:00
hank 7874378682 New translations en.po (Norwegian)
[ci skip]
2026-09-09 21:45:46 -04:00
hank 8bd484ea61 New translations en.po (Dutch)
[ci skip]
2026-09-09 21:45:44 -04:00
hank 643db14caa New translations en.po (Korean)
[ci skip]
2026-09-09 21:45:43 -04:00
hank db12911578 New translations en.po (Japanese)
[ci skip]
2026-09-09 21:45:42 -04:00
hank d7dcfbf49e New translations en.po (Italian)
[ci skip]
2026-09-09 21:45:40 -04:00
hank f17a7320d4 New translations en.po (Hungarian)
[ci skip]
2026-09-09 21:45:39 -04:00
hank 815a207509 New translations en.po (Hebrew)
[ci skip]
2026-09-09 21:45:37 -04:00
hank 31dacaff38 New translations en.po (Greek)
[ci skip]
2026-09-09 21:45:36 -04:00
hank fd4e03de08 New translations en.po (Danish)
[ci skip]
2026-09-09 21:45:35 -04:00
hank 6453869371 New translations en.po (Czech)
[ci skip]
2026-09-09 21:45:33 -04:00
hank e0de0b3260 New translations en.po (Bulgarian)
[ci skip]
2026-09-09 21:45:32 -04:00
hank 73b9b86cb7 New translations en.po (Spanish)
[ci skip]
2026-09-09 21:45:30 -04:00
hank 8db92a72ef New translations en.po (French)
[ci skip]
2026-09-09 21:45:29 -04:00
henrygd bb270e02a8 i18n: add translations for new strings and remove source matching translations 2026-09-09 20:53:52 -04:00
hankandGitHub 312c109138 i18n: New Crowdin updates (#2322) 2026-09-09 20:34:47 -04:00
henrygd c938368089 i18n: update translation strings 2026-09-09 20:27:22 -04:00
8d6a5d5f6e feat(agent): report btrfs filesystems as storage pools (#2315)
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-09 19:53:39 -04:00
henrygd 98687be2f2 fix(hub): reject null systemd service entries to prevent hub panic 2026-09-08 10:08:33 -04:00
henrygd e39e153ca0 fix(hub): prevent readonly users listing tokens of their shared systems via api 2026-09-08 09:57:58 -04:00
5b87f7d7cb fix(hub): always clear auth store when encountring 4xx after token expires (#2310)
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-08 08:21:00 -04:00
hankandGitHub 9a0aa5a89e fix: prevent possible dns rebinding for alert notifications directing to internal sevices (#2314)
- Validate resolved IPs immediately before connecting.
- Guard Shoutrrr requests during initialization and delivery.
- Require admins for services without HTTP client support.
- Test DNS rebinding, redirects, internal hosts, and authorization.
- Upgrade Shoutrrr to 0.20.0 to support custom dialcontext
2026-09-08 08:05:47 -04:00
henrygd 997adc19bb fix: show idle GPU utilization in systems table (#2312) 2026-09-07 13:13:05 -04:00
Sven van GinkelandGitHub 08d813620c Add ZFS pool/dataset utilities (zpool, zfs) to the full and slim nvidia agent images (#2311) 2026-09-07 11:05:02 -04:00
henrygd 6cb302fcf6 fix(hub): bound realtime metric fetching and enforce access control by system
- synchronize realtime subscription state
- prevent overlapping fetches per system
- add realtime worker lifecycle tests
- reject subscriptions without system access
- test access revocation and shared-system permissions
2026-09-06 13:24:53 -04:00
59eed073c3 fix(install): add beszel to operator group on FreeBSD for SMART device access (#2286)
On FreeBSD the beszel agent needs to be a member of the operator group
to access SMART-capable devices via smartctl (e.g. /dev/nvme*,
/dev/xpt0*). The wheel group alone does not grant that access, so the
install script now adds the beszel user to operator when that group
exists, mirroring the Linux disk-group handling.

Fixes #1431

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-06 11:34:03 -04:00
hankandGitHub 266a74bab8 Update security policy for vulnerability reporting 2026-09-06 10:16:40 -04:00
Matthew D'SouzaandGitHub ad24484caa feat(site): display NVMe data units as human-readable GB/TB (#2303) 2026-09-05 14:44:03 -04:00
Ryan ChouandGitHub 027d0c204d fix(agent): extend WebSocket deadline for slow collections (#2297)
The agent resets its WebSocket deadline to 70s, but the hub's default
collection interval is 60s, so a single slow collection cycle is enough to
trip the deadline and start a reconnect loop even though the hub is still
serving the agent. Raise the deadline to 120s and add a regression test that
keeps the slow-collection window from being lowered below two minutes.

Verified with go test -tags=testing ./agent (focused tests and the full agent
suite minus the container-only TestDirectoryIsWritable case), go vet, the
agent build and gofmt.

Closes #2294
2026-09-05 13:09:25 -04:00
henrygdandhank 46d94a9804 fix: improve agent installer error handling (#1971, #1972)
- Enable set -eu and handle expected failures explicitly
- Validate platform and service manager before making changes
- Fix argument parsing, version fallback, cron setup, and prompt EOF
- Verify downloads before stopping the existing agent
- Add atomic binary replacement, rollback, and cleanup
- Add regression tests for installation failure paths
2026-09-05 13:06:34 -04:00
Elan Ruusamäeandhank 82fc772882 Fix: Enable immediate exit on errors in install-agent.sh (#1972)
Add error handling to ensure script exits on errors.
2026-09-05 13:06:34 -04:00
henrygd c157c2026d fix(agent): include root CA certificates in base image (#2291) 2026-09-03 14:32:59 -04:00
ArnoandGitHub e1d9ebc61d chore: add zfs tools to intel agent image (#2288) 2026-09-03 14:19:49 -04:00
hankGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
5af6b6b184 chore(helm): update app version to 0.19.0 (#2287)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-03 11:44:34 -04:00
102 changed files with 5326 additions and 2422 deletions
+4 -2
View File
@@ -2,6 +2,8 @@
## Reporting a Vulnerability
If you find a vulnerability in the latest version, please [submit a private advisory](https://github.com/henrygd/beszel/security/advisories/new).
**PLEASE ONLY USE SECURITY ADVISORIES FOR REAL HIGH SEVERITY VULNERABILITIES.**
If it's low severity (use best judgement) you may open an issue instead of an advisory.
If you find a vulnerability in the latest version, and it is not high severity, open an issue instead of an advisory.
I am overwhelmed with advisories, often erroneous, which are clearly found and written by AI. I don't have the capacity to review all of them.
+4 -4
View File
@@ -48,7 +48,7 @@ type Agent struct {
keys []gossh.PublicKey // SSH public keys
smartManager *SmartManager // Manages SMART data
systemdManager *systemdManager // Manages systemd services
zfsManager *ZfsManager // Manages ZFS pool and dataset data
storagePoolManager *StoragePoolManager // Manages storage pool and dataset data
}
// NewAgent creates a new agent with the given data directory for persisting data.
@@ -122,12 +122,12 @@ func NewAgent(dataDir ...string) (agent *Agent, err error) {
// initialize handler registry
agent.handlerRegistry = NewHandlerRegistry()
agent.zfsManager = newZfsManager()
agent.storagePoolManager = newStoragePoolManager()
// ZFS_INTERVAL env var to update ZFS detail data at this interval
// Retain ZFS_INTERVAL for the shared storage pool detail refresh interval.
if zfsIntervalEnv, exists := utils.GetEnv("ZFS_INTERVAL"); exists {
if duration, err := time.ParseDuration(zfsIntervalEnv); err == nil && duration > 0 {
agent.zfsManager.detailInterval = duration
agent.storagePoolManager.detailInterval = duration
agent.systemDetails.ZfsInterval = duration
slog.Info("ZFS_INTERVAL", "duration", duration)
} else {
+26
View File
@@ -0,0 +1,26 @@
// Package btrfs reads btrfs filesystem state from sysfs.
package btrfs
// Filesystem is a mounted btrfs filesystem read from /sys/fs/btrfs/<uuid>.
type Filesystem struct {
UUID string // stable filesystem UUID from sysfs
MountID string // kernel filesystem identity for matching monitored mounts
IODevice string // sole member block-device name, empty for multi-device/unknown pools
Name string // label, else first mountpoint, else UUID
Size uint64 // effective usable capacity, or raw member capacity when Raw
Raw bool // capacity and usage are physical bytes, unsuitable for disk alerts
Alloc uint64 // raw bytes allocated to data, metadata and system chunks
Health string // ONLINE, or DEGRADED when a device is missing
NRead uint64 // cumulative bytes read across member devices
NWrite uint64 // cumulative bytes written across member devices
Devices []Device
}
// Device is one member device (devinfo/<devid>) with its error counters.
type Device struct {
Name string // "devid N"; sysfs does not expose the block device path
State string // ONLINE or MISSING
ReadErrs uint64
WriteErrs uint64
CorruptionErrs uint64
}
+285
View File
@@ -0,0 +1,285 @@
//go:build linux
package btrfs
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"unsafe"
"github.com/henrygd/beszel/agent/utils"
"golang.org/x/sys/unix"
)
var (
sysfsPath = "/sys/fs/btrfs"
mountsPath = "/proc/self/mounts"
mountinfoPath = "/proc/self/mountinfo"
mountUUID = MountID
deviceSize = ioctlDeviceSize
filesystemUsage = statfsUsage
)
// Filesystems returns all mounted btrfs filesystems, or nil when there are none.
func Filesystems() ([]Filesystem, error) {
entries, err := os.ReadDir(sysfsPath)
if errors.Is(err, os.ErrNotExist) {
return nil, nil
}
if err != nil {
return nil, err
}
mounts := mountpointsByDevice()
var filesystems []Filesystem
for _, entry := range entries {
if !entry.IsDir() || entry.Name() == "features" {
continue
}
fs, err := readFilesystem(filepath.Join(sysfsPath, entry.Name()), mounts)
if err != nil {
return nil, fmt.Errorf("btrfs %s: %w", entry.Name(), err)
}
filesystems = append(filesystems, fs)
}
return filesystems, nil
}
func readFilesystem(dir string, mounts map[string]string) (Filesystem, error) {
fs := Filesystem{UUID: filepath.Base(dir), Name: utils.ReadStringFile(filepath.Join(dir, "label")), Health: "UNKNOWN"}
for _, kind := range []string{"data", "metadata", "system"} {
if value, ok := utils.ReadUintFile(filepath.Join(dir, "allocation", kind, "disk_used")); ok {
fs.Alloc += value
}
}
// devices/<name> links to the block device's sysfs directory.
devices, err := os.ReadDir(filepath.Join(dir, "devices"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return fs, err
}
mountpoint := mounts["uuid:"+fs.UUID]
if fs.Name == "" {
fs.Name = mountpoint
}
var backingSize uint64
for _, dev := range devices {
if mountpoint == "" {
mountpoint = mounts[dev.Name()]
}
if fs.Name == "" {
fs.Name = mountpoint
}
devDir := filepath.Join(dir, "devices", dev.Name())
if size, ok := utils.ReadUintFile(filepath.Join(devDir, "size")); ok {
backingSize += size * 512
}
if stat := strings.Fields(utils.ReadStringFile(filepath.Join(devDir, "stat"))); len(stat) >= 7 {
fs.NRead += parseUint(stat[2]) * 512
fs.NWrite += parseUint(stat[6]) * 512
}
}
devids, err := os.ReadDir(filepath.Join(dir, "devinfo"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return fs, err
}
capacityAvailable := len(devids) > 0
healthKnown := len(devids) > 0
for _, devid := range devids {
devDir := filepath.Join(dir, "devinfo", devid.Name())
// Replacement targets do not add filesystem capacity.
replaceTarget, _ := utils.ReadUintFile(filepath.Join(devDir, "replace_target"))
if replaceTarget != 1 {
devid, err := strconv.ParseUint(devid.Name(), 10, 64)
if err != nil {
return fs, err
}
size, err := deviceSize(mountpoint, devid)
if err != nil {
capacityAvailable = false
}
fs.Size += size
}
dev := Device{Name: "devid " + devid.Name(), State: "ONLINE"}
missing := utils.ReadStringFile(filepath.Join(devDir, "missing"))
if missing != "0" && missing != "1" {
healthKnown = false
dev.State = "UNKNOWN"
}
if missing == "1" {
dev.State = "MISSING"
fs.Health = "DEGRADED"
}
for line := range strings.Lines(utils.ReadStringFile(filepath.Join(devDir, "error_stats"))) {
if fields := strings.Fields(line); len(fields) == 2 {
switch fields[0] {
case "read_errs":
dev.ReadErrs = parseUint(fields[1])
case "write_errs":
dev.WriteErrs = parseUint(fields[1])
case "corruption_errs":
dev.CorruptionErrs = parseUint(fields[1])
}
}
}
fs.Devices = append(fs.Devices, dev)
}
// Use one capacity source for the whole filesystem: device IDs cannot be
// reliably matched to block-device names in sysfs. A partial ioctl result
// must not be added to the complete backing-device total.
if !capacityAvailable {
fs.Size = backingSize
}
if fs.Health != "DEGRADED" && healthKnown {
fs.Health = "ONLINE"
}
fs.MountID = mountUUID(mountpoint)
if len(devices) == 1 && len(devids) == 1 && fs.Health == "ONLINE" {
fs.IODevice = devices[0].Name()
}
fs.Raw = true
if used, available, err := filesystemUsage(mountpoint); err == nil {
// Effective capacity excludes reserved/unavailable space, so Size-Alloc
// is available to applications and the usage ratio matches df.
fs.Size, fs.Alloc, fs.Raw = used+available, used, false
}
if fs.Name == "" {
fs.Name = filepath.Base(dir)
}
return fs, nil
}
// mountpointsByDevice prefers UUID matches from mountinfo and retains source
// device names as a fallback for environments where FS_INFO is unavailable.
func mountpointsByDevice() map[string]string {
mounts := mountpointsByUUID(utils.ReadStringFile(mountinfoPath), mountUUID)
for line := range strings.Lines(utils.ReadStringFile(mountsPath)) {
fields := strings.Fields(line)
if len(fields) < 3 || fields[2] != "btrfs" {
continue
}
device := fields[0]
if resolved, err := filepath.EvalSymlinks(device); err == nil {
device = resolved
}
if _, seen := mounts[filepath.Base(device)]; !seen {
mounts[filepath.Base(device)] = unescapeMountPath(fields[1])
}
}
return mounts
}
func parseUint(s string) uint64 {
n, _ := strconv.ParseUint(s, 10, 64)
return n
}
// ioctlDeviceSize reads Btrfs's recorded device size, which can be smaller
// than the block device after a filesystem resize. BTRFS_IOC_DEV_INFO is
// _IOWR(0x94, 30, struct btrfs_ioctl_dev_info_args), a 4096-byte ABI structure.
func ioctlDeviceSize(mountpoint string, devid uint64) (uint64, error) {
if mountpoint == "" {
return 0, errors.New("no accessible mountpoint")
}
f, err := os.Open(mountpoint)
if err != nil {
return 0, err
}
defer f.Close()
args := struct {
Devid uint64
UUID [16]byte
BytesUsed uint64
TotalBytes uint64
Reserved [4096 - 40]byte
}{Devid: devid}
_, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(), 0xd000941e, uintptr(unsafe.Pointer(&args)))
if errno != 0 {
return 0, errno
}
return args.TotalBytes, nil
}
// The filesystem magic is unsigned even when Statfs_t.Type is int32.
func isBtrfs(stat *unix.Statfs_t) bool {
return uint32(stat.Type) == unix.BTRFS_SUPER_MAGIC
}
func statfsUsage(path string) (used, available uint64, err error) {
if path == "" {
return 0, 0, errors.New("no accessible mountpoint")
}
var stat unix.Statfs_t
if err = unix.Statfs(path, &stat); err != nil {
return
}
if !isBtrfs(&stat) {
return 0, 0, errors.New("mountpoint is not Btrfs")
}
blockSize := uint64(stat.Bsize)
return (stat.Blocks - min(stat.Blocks, stat.Bfree)) * blockSize, min(stat.Blocks, stat.Bavail) * blockSize, nil
}
// MountID returns the filesystem UUID via BTRFS_IOC_FS_INFO. Unlike statfs
// f_fsid, this identity is shared by all subvolumes and bind mounts.
func MountID(path string) string {
if path == "" {
return ""
}
var stat unix.Statfs_t
if unix.Statfs(path, &stat) != nil || !isBtrfs(&stat) {
return ""
}
f, err := os.Open(path)
if err != nil {
return ""
}
defer f.Close()
args := struct {
MaxID uint64
NumDevices uint64
FSID [16]byte
Reserved [992]byte
}{}
// _IOR(0x94, 31, 1024). Reuse the platform's read-direction bits;
// MIPS/PowerPC use a different encoding than asm-generic.
request := uintptr(unix.FS_IOC_GETFLAGS&0xe0000000) | 0x0400941f
_, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(), request, uintptr(unsafe.Pointer(&args)))
if errno != 0 {
return ""
}
id := args.FSID
return fmt.Sprintf("%x-%x-%x-%x-%x", id[:4], id[4:6], id[6:8], id[8:10], id[10:])
}
// Btrfs mountinfo device numbers can be virtual (0:N), so query the UUID
// through the mount instead of comparing those numbers with sysfs block devs.
// Retry another path when a bind mount is inaccessible. Once resolved, reuse
// the result for that mount device to avoid opening every Docker bind mount.
func mountpointsByUUID(mountinfo string, identify func(string) string) map[string]string {
mounts := make(map[string]string)
resolved := make(map[string]bool)
for line := range strings.Lines(mountinfo) {
before, after, ok := strings.Cut(line, " - ")
fields, fs := strings.Fields(before), strings.Fields(after)
if !ok || len(fields) < 6 || len(fs) < 3 || fs[0] != "btrfs" || resolved[fields[2]] {
continue
}
path := unescapeMountPath(fields[4])
uuid := identify(path)
if uuid == "" {
continue
}
resolved[fields[2]] = true
if mounts["uuid:"+uuid] == "" {
mounts["uuid:"+uuid] = path
}
}
return mounts
}
func unescapeMountPath(path string) string {
return strings.NewReplacer(`\040`, " ", `\011`, "\t", `\012`, "\n", `\134`, `\`).Replace(path)
}
+274
View File
@@ -0,0 +1,274 @@
//go:build testing && linux
package btrfs
import (
"os"
"path/filepath"
"strconv"
"testing"
"github.com/henrygd/beszel/agent/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/unix"
)
func TestFilesystems(t *testing.T) {
root := t.TempDir()
oldSysfs, oldMounts := sysfsPath, mountsPath
sysfsPath, mountsPath = root, filepath.Join(root, "mounts")
t.Cleanup(func() { sysfsPath, mountsPath = oldSysfs, oldMounts })
fsDir := filepath.Join(root, "1b2c3d4e-0000-0000-0000-000000000000")
write := func(rel, content string) {
path := filepath.Join(fsDir, rel)
require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
require.NoError(t, os.WriteFile(path, []byte(content), 0o644))
}
require.NoError(t, os.MkdirAll(filepath.Join(root, "features"), 0o755))
oldUsage := filesystemUsage
filesystemUsage = func(string) (uint64, uint64, error) { return 0, 0, os.ErrNotExist }
t.Cleanup(func() { filesystemUsage = oldUsage })
oldDeviceSize := deviceSize
t.Cleanup(func() { deviceSize = oldDeviceSize })
deviceSize = func(_ string, devid uint64) (uint64, error) {
value, _ := utils.ReadUintFile(filepath.Join(fsDir, "recorded-size", strconv.FormatUint(devid, 10)))
return value, nil
}
// Recorded member capacities differ from the unchanged backing devices.
write("recorded-size/1", "256000\n")
write("recorded-size/2", "128000\n")
write("label", "tank\n")
write("allocation/data/disk_used", "4096\n")
write("allocation/metadata/disk_used", "2048\n")
write("allocation/system/disk_used", "1024\n")
write("devices/sda/size", "1000\n")
write("devices/sda/stat", "10 0 200 0 20 0 400 0 0 0 0\n")
write("devices/sdb/size", "1000\n")
write("devices/sdb/stat", "10 0 100 0 20 0 100 0 0 0 0\n")
write("devinfo/1/missing", "0\n")
write("devinfo/1/error_stats", "write_errs 1\nread_errs 2\nflush_errs 0\ncorruption_errs 3\ngeneration_errs 0\n")
write("devinfo/2/missing", "1\n")
filesystems, err := Filesystems()
require.NoError(t, err)
require.Len(t, filesystems, 1)
assert.Equal(t, Filesystem{
UUID: "1b2c3d4e-0000-0000-0000-000000000000", Raw: true, Name: "tank", Size: 384000, Alloc: 7168, Health: "DEGRADED", NRead: 153600, NWrite: 256000,
Devices: []Device{
{Name: "devid 1", State: "ONLINE", ReadErrs: 2, WriteErrs: 1, CorruptionErrs: 3},
{Name: "devid 2", State: "MISSING"},
},
}, filesystems[0])
// Unlabeled filesystems fall back to the first mountpoint, then the UUID.
write("label", "\n")
require.NoError(t, os.WriteFile(mountsPath, []byte(
"/dev/sdz1 /other btrfs rw 0 0\n/dev/sdb /mnt/storage btrfs rw 0 0\n/dev/sdb /mnt/storage/sub btrfs rw,subvol=/sub 0 0\n",
), 0o644))
filesystems, err = Filesystems()
require.NoError(t, err)
assert.Equal(t, "/mnt/storage", filesystems[0].Name)
require.NoError(t, os.Remove(mountsPath))
filesystems, err = Filesystems()
require.NoError(t, err)
assert.Equal(t, "1b2c3d4e-0000-0000-0000-000000000000", filesystems[0].Name)
write("devinfo/3/replace_target", "1\n")
write("recorded-size/3", "512000\n")
filesystems, err = Filesystems()
require.NoError(t, err)
assert.Equal(t, uint64(384000), filesystems[0].Size, "replacement target must not inflate capacity")
deviceSize = func(string, uint64) (uint64, error) { return 0, os.ErrPermission }
filesystems, err = Filesystems()
require.NoError(t, err)
require.Len(t, filesystems, 1)
assert.Equal(t, uint64(1024000), filesystems[0].Size)
assert.Equal(t, "DEGRADED", filesystems[0].Health)
assert.Equal(t, uint64(153600), filesystems[0].NRead)
// A partial ioctl result must not be mixed with the backing-device total.
deviceSize = func(_ string, devid uint64) (uint64, error) {
if devid == 2 {
return 0, os.ErrPermission
}
return 256000, nil
}
filesystems, err = Filesystems()
require.NoError(t, err)
assert.Equal(t, uint64(1024000), filesystems[0].Size)
// With no mount visible (e.g. Docker), the real lookup falls back too.
deviceSize = ioctlDeviceSize
filesystems, err = Filesystems()
require.NoError(t, err)
require.Len(t, filesystems, 1)
assert.Equal(t, uint64(1024000), filesystems[0].Size)
filesystemUsage = func(string) (uint64, uint64, error) { return 100, 900, nil }
filesystems, err = Filesystems()
require.NoError(t, err)
assert.Equal(t, uint64(1000), filesystems[0].Size)
assert.Equal(t, uint64(100), filesystems[0].Alloc)
assert.False(t, filesystems[0].Raw)
}
func TestFilesystemsNoBtrfs(t *testing.T) {
oldPath := sysfsPath
sysfsPath = filepath.Join(t.TempDir(), "missing")
t.Cleanup(func() { sysfsPath = oldPath })
filesystems, err := Filesystems()
require.NoError(t, err)
assert.Nil(t, filesystems)
}
func TestIoctlDeviceSizeFailure(t *testing.T) {
_, err := ioctlDeviceSize("", 1)
require.Error(t, err)
_, err = ioctlDeviceSize(t.TempDir(), 1)
require.Error(t, err)
assert.ErrorIs(t, err, unix.ENOTTY)
}
func TestMountpointsDecodeEscapes(t *testing.T) {
oldMounts := mountsPath
mountsPath = filepath.Join(t.TempDir(), "mounts")
t.Cleanup(func() { mountsPath = oldMounts })
require.NoError(t, os.WriteFile(mountsPath, []byte("/dev/test-btrfs /mnt/my\\040data btrfs rw 0 0\n"), 0o644))
assert.Equal(t, "/mnt/my data", mountpointsByDevice()["test-btrfs"])
}
func TestFilesystemWithoutDevinfo(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.MkdirAll(filepath.Join(root, "devices", "sda"), 0755))
require.NoError(t, os.WriteFile(filepath.Join(root, "devices", "sda", "size"), []byte("1000"), 0644))
fs, err := readFilesystem(root, nil)
require.NoError(t, err)
assert.Equal(t, uint64(512000), fs.Size)
assert.True(t, fs.Raw)
assert.Equal(t, "UNKNOWN", fs.Health)
assert.Empty(t, fs.Devices)
require.NoError(t, os.MkdirAll(filepath.Join(root, "devinfo", "1"), 0755))
fs, err = readFilesystem(root, nil)
require.NoError(t, err)
assert.Equal(t, "UNKNOWN", fs.Health)
require.Len(t, fs.Devices, 1)
assert.Equal(t, "UNKNOWN", fs.Devices[0].State)
// Some older interfaces lack the devices directory too.
fs, err = readFilesystem(t.TempDir(), nil)
require.NoError(t, err)
assert.Equal(t, "UNKNOWN", fs.Health)
}
func TestLocalBtrfsUsage(t *testing.T) {
path := os.Getenv("BESZEL_TEST_BTRFS_MOUNT")
if path == "" {
t.Skip("set BESZEL_TEST_BTRFS_MOUNT for read-only live validation")
}
used, available, err := statfsUsage(path)
require.NoError(t, err)
filesystems, err := Filesystems()
require.NoError(t, err)
for _, fs := range filesystems {
if !fs.Raw && fs.Alloc == used && fs.Size == used+available {
t.Logf("pool=%s used=%d available=%d effective_capacity=%d", fs.Name, used, available, fs.Size)
return
}
}
t.Fatal("collector did not report the mounted filesystem's usable capacity")
}
func TestMountID(t *testing.T) {
assert.Empty(t, MountID(""))
assert.Empty(t, MountID(filepath.Join(t.TempDir(), "missing")))
path := os.Getenv("BESZEL_TEST_BTRFS_MOUNT")
if path == "" {
t.Skip("set BESZEL_TEST_BTRFS_MOUNT for live identity validation")
}
id := MountID(path)
require.NotEmpty(t, id)
assert.Equal(t, id, MountID(filepath.Join(path, ".")))
}
func TestMountinfoUUIDLookup(t *testing.T) {
info := `1 0 0:40 /@ /inaccessible ro shared:1 - btrfs /dev/mapper/unavailable rw
2 0 0:40 /@/docker/hosts /etc/hosts ro - btrfs /dev/mapper/unavailable rw
3 0 0:40 /@/docker/hostname /etc/hostname ro - btrfs /dev/mapper/unavailable rw
4 0 0:41 /subvol /extra-filesystems/my\040disk ro master:2 - btrfs /dev/missing rw
5 0 0:42 / /ext4 ro - ext4 /dev/mapper/unavailable rw
malformed
6 0 0:43 / /bad ro - btrfs
`
var calls []string
mounts := mountpointsByUUID(info, func(path string) string {
calls = append(calls, path)
switch path {
case "/etc/hosts":
return "root-uuid"
case "/extra-filesystems/my disk":
return "extra-uuid"
}
return ""
})
assert.Equal(t, map[string]string{"uuid:root-uuid": "/etc/hosts", "uuid:extra-uuid": "/extra-filesystems/my disk"}, mounts)
assert.Equal(t, []string{"/inaccessible", "/etc/hosts", "/extra-filesystems/my disk"}, calls)
}
func TestDockerFilesystemWithoutDeviceNodes(t *testing.T) {
root := t.TempDir()
oldSysfs, oldMounts, oldInfo, oldUUID, oldUsage := sysfsPath, mountsPath, mountinfoPath, mountUUID, filesystemUsage
t.Cleanup(func() {
sysfsPath, mountsPath, mountinfoPath, mountUUID, filesystemUsage = oldSysfs, oldMounts, oldInfo, oldUUID, oldUsage
})
sysfsPath = filepath.Join(root, "sysfs")
mountsPath = filepath.Join(root, "missing-mounts")
mountinfoPath = filepath.Join(root, "mountinfo")
uuid := "11111111-1111-4111-8111-111111111111"
dir := filepath.Join(sysfsPath, uuid)
for path, content := range map[string]string{"devices/dm-0/size": "1000", "devinfo/1/missing": "0"} {
target := filepath.Join(dir, path)
require.NoError(t, os.MkdirAll(filepath.Dir(target), 0755))
require.NoError(t, os.WriteFile(target, []byte(content), 0644))
}
require.NoError(t, os.WriteFile(mountinfoPath, []byte("2 1 0:40 /@/docker/hosts /etc/hosts ro - btrfs /dev/mapper/not-in-container rw\n"), 0644))
mountUUID = func(path string) string {
if path == "/etc/hosts" {
return uuid
}
return ""
}
filesystemUsage = func(path string) (uint64, uint64, error) { require.Equal(t, "/etc/hosts", path); return 100, 900, nil }
fs, err := Filesystems()
require.NoError(t, err)
require.Len(t, fs, 1)
assert.Equal(t, uuid, fs[0].MountID)
assert.Equal(t, "dm-0", fs[0].IODevice)
assert.False(t, fs[0].Raw)
assert.Equal(t, uint64(1000), fs[0].Size)
}
func TestLivePoolMountIdentity(t *testing.T) {
path := os.Getenv("BESZEL_TEST_BTRFS_MOUNT")
if path == "" {
t.Skip("set BESZEL_TEST_BTRFS_MOUNT for live validation")
}
id := MountID(path)
require.NotEmpty(t, id)
pools, err := Filesystems()
require.NoError(t, err)
for _, pool := range pools {
if pool.UUID != id {
continue
}
assert.Equal(t, id, pool.MountID)
assert.False(t, pool.Raw)
t.Logf("uuid=%s mount_identity=%s io_device=%s raw=%v", pool.UUID, pool.MountID, pool.IODevice, pool.Raw)
return
}
t.Fatal("mounted Btrfs filesystem was not discovered")
}
+11
View File
@@ -0,0 +1,11 @@
//go:build !linux
package btrfs
import "errors"
func Filesystems() ([]Filesystem, error) {
return nil, errors.ErrUnsupported
}
func MountID(string) string { return "" }
+3 -1
View File
@@ -25,7 +25,9 @@ import (
)
const (
wsDeadline = 70 * time.Second
// Keep the connection alive long enough for a slow collection cycle to
// finish before the hub considers the agent disconnected.
wsDeadline = 120 * time.Second
)
type caCertFileError struct {
+8
View File
@@ -700,3 +700,11 @@ func TestGetToken(t *testing.T) {
assert.Equal(t, expectedToken, token, "Whitespace should be stripped from token file content")
})
}
func TestWebSocketDeadlineCoversSlowCollection(t *testing.T) {
const minimumDeadline = 120 * time.Second
if wsDeadline < minimumDeadline {
t.Fatalf("WebSocket deadline %s is shorter than the slow-collection window of %s", wsDeadline, minimumDeadline)
}
}
+14 -14
View File
@@ -18,11 +18,11 @@ import (
// fsRegistrationContext holds the shared lookup state needed to resolve a
// filesystem into the tracked fsStats key and metadata.
type fsRegistrationContext struct {
filesystem string // device part of optional FILESYSTEM env var
filesystemName string // optional custom name from FILESYSTEM=device__name
isWindows bool
efPath string // path to extra filesystems (default "/extra-filesystems")
diskIoCounters map[string]disk.IOCountersStat
filesystem string // device part of optional FILESYSTEM env var
filesystemName string // optional custom name from FILESYSTEM=device__name
isWindows bool
efPath string // path to extra filesystems (default "/extra-filesystems")
diskIoCounters map[string]disk.IOCountersStat
}
// diskDiscovery groups the transient state for a single initializeDiskInfo run so
@@ -325,11 +325,11 @@ func (a *Agent) initializeDiskInfo() {
}
slog.Debug("Disk I/O", "diskstats", diskIoCounters)
ctx := fsRegistrationContext{
filesystem: filesystem,
filesystemName: filesystemName,
isWindows: isWindows,
diskIoCounters: diskIoCounters,
efPath: "/extra-filesystems",
filesystem: filesystem,
filesystemName: filesystemName,
isWindows: isWindows,
diskIoCounters: diskIoCounters,
efPath: "/extra-filesystems",
}
// Get the appropriate root mount point for this system
@@ -540,8 +540,8 @@ func (a *Agent) initializeDiskIoStats(diskIoCounters map[string]disk.IOCountersS
// ZFS datasets have no /proc/diskstats entry, so they are excluded from
// I/O tracking instead of warning about a missing device (#1541).
var zfsMountpoints map[string]bool
if a.zfsManager != nil {
zfsMountpoints = a.zfsManager.ZfsMountpoints()
if a.storagePoolManager != nil {
zfsMountpoints = a.storagePoolManager.ZfsMountpoints()
}
for device, stats := range a.fsStats {
if zfsMountpoints[stats.Mountpoint] {
@@ -574,8 +574,8 @@ func (a *Agent) updateDiskUsage(systemStats *system.Stats) {
// ZFS dataset mountpoints use `zfs list` values because statfs(2) reports
// dataset-level usage that excludes child datasets (#1541).
var zfsUsage map[string]zfsDatasetUsage
if a.zfsManager != nil {
zfsUsage = a.zfsManager.DatasetUsage()
if a.storagePoolManager != nil {
zfsUsage = a.storagePoolManager.DatasetUsage()
}
// disk usage
+11 -10
View File
@@ -4,6 +4,7 @@ package agent
import (
"testing"
"time"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/system"
@@ -16,8 +17,8 @@ import (
// is a ZFS dataset reports `zfs list` usage (which includes child datasets)
// instead of the dataset-scoped statfs values (#1541).
func TestUpdateDiskUsageZfsMountpoint(t *testing.T) {
zm := &ZfsManager{}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "tank", Used: 12000000000000, Avail: 11999000000000, Mountpoint: "/tank"},
}, nil
@@ -26,7 +27,7 @@ func TestUpdateDiskUsageZfsMountpoint(t *testing.T) {
fsStats: map[string]*system.FsStats{
"tank": {Root: false, Mountpoint: "/tank"},
},
zfsManager: zm,
storagePoolManager: zm,
}
var stats system.Stats
@@ -43,8 +44,8 @@ func TestUpdateDiskUsageZfsMountpoint(t *testing.T) {
// TestUpdateDiskUsageZfsRootPopulatesSystemStats verifies the root disk values
// are derived from ZFS usage when the root mountpoint is a ZFS dataset.
func TestUpdateDiskUsageZfsRootPopulatesSystemStats(t *testing.T) {
zm := &ZfsManager{}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "rpool/ROOT/pve-1", Used: 900000000000, Avail: 300000000000, Mountpoint: "/"},
}, nil
@@ -53,7 +54,7 @@ func TestUpdateDiskUsageZfsRootPopulatesSystemStats(t *testing.T) {
fsStats: map[string]*system.FsStats{
"rpool/ROOT/pve-1": {Root: true, Mountpoint: "/"},
},
zfsManager: zm,
storagePoolManager: zm,
}
var stats system.Stats
@@ -85,8 +86,8 @@ func TestUpdateDiskUsageWithoutZfsManager(t *testing.T) {
// TestInitializeDiskIoStatsSkipsZfsMountpoints verifies ZFS filesystems are
// excluded from diskstats I/O tracking instead of warning about a missing device.
func TestInitializeDiskIoStatsSkipsZfsMountpoints(t *testing.T) {
zm := &ZfsManager{}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank", Mountpoint: "/tank"}}, nil
}
agent := &Agent{
@@ -94,8 +95,8 @@ func TestInitializeDiskIoStatsSkipsZfsMountpoints(t *testing.T) {
"tank": {Root: false, Mountpoint: "/tank"},
"sda1": {Root: false, Mountpoint: "/mnt/data"},
},
zfsManager: zm,
diskPrev: make(map[uint16]map[string]prevDisk),
storagePoolManager: zm,
diskPrev: make(map[uint16]map[string]prevDisk),
}
agent.initializeDiskIoStats(map[string]disk.IOCountersStat{
+2 -2
View File
@@ -186,14 +186,14 @@ func (h *GetSmartDataHandler) Handle(hctx *HandlerContext) error {
type GetZfsDataHandler struct{}
func (h *GetZfsDataHandler) Handle(hctx *HandlerContext) error {
if hctx.Agent.zfsManager == nil {
if hctx.Agent.storagePoolManager == nil {
return hctx.SendResponse(nil, hctx.RequestID)
}
var req common.ZfsDataRequest
if err := cbor.Unmarshal(hctx.Request.Data, &req); err != nil {
return err
}
return hctx.SendResponse(hctx.Agent.zfsManager.GetDetail(req.Force), hctx.RequestID)
return hctx.SendResponse(hctx.Agent.storagePoolManager.GetDetail(req.Force), hctx.RequestID)
}
////////////////////////////////////////////////////////////////////////////
+5 -5
View File
@@ -34,19 +34,19 @@ func TestNewAgentResponseSmartData(t *testing.T) {
func TestGetZfsDataHandlerForceRefresh(t *testing.T) {
poolCalls := 0
zm := &ZfsManager{detailInterval: time.Hour}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
poolCalls++
return []zfs.PoolStat{{Name: "tank", Alloc: uint64(poolCalls)}}, nil
}
zm.poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.backends[0].poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.GetDetail(false)
requestData, err := cbor.Marshal(common.ZfsDataRequest{Force: true})
assert.NoError(t, err)
ctx := &HandlerContext{
Agent: &Agent{zfsManager: zm},
Agent: &Agent{storagePoolManager: zm},
Request: &common.HubRequest[cbor.RawMessage]{
Action: common.GetZfsData,
Data: requestData,
+462
View File
@@ -0,0 +1,462 @@
package agent
import (
"errors"
"log/slog"
"os/exec"
"strings"
"sync"
"time"
"github.com/henrygd/beszel/agent/btrfs"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/system"
zfsentity "github.com/henrygd/beszel/internal/entities/zfs"
)
// zfsDatasetUsage holds usage values for a ZFS dataset mountpoint.
type zfsDatasetUsage struct {
used uint64
avail uint64
}
// datasetUsageRefreshInterval controls how often `zfs list` is re-run for the
// mountpoint usage map. Dataset inventory changes rarely.
const datasetUsageRefreshInterval = 5 * time.Minute
// poolStatsRefreshInterval controls how often `zpool list` is re-run for pool
// capacity. Health and I/O are read from procfs on Linux, so the utility only
// needs to refresh slow-moving space accounting.
const poolStatsRefreshInterval = time.Minute
// btrfsFilesystems is the btrfs source; overridable in tests.
var btrfsFilesystems = btrfs.Filesystems
type poolKernelSample struct {
nread uint64
nwrite uint64
at time.Time
}
// StoragePoolManager combines independent backend inventories. Metrics and
// dataset usage require the agent lock; GetDetail is safe for concurrent calls.
type StoragePoolManager struct {
backends []*poolBackend
detailInterval time.Duration
}
// poolBackend owns one backend's collectors and caches. Collector functions
// are immutable after construction and may run concurrently for metrics/details.
type poolBackend struct {
name string
poolStatsFn func() ([]zfs.PoolStat, error) // capacity/health source
datasetsFn func() ([]zfs.Dataset, error) // dataset inventory source
kernelStatsFn func() ([]zfs.PoolKernelStat, error) // procfs pool state/I/O source
poolStatusesFn func() ([]zfs.PoolStatus, error) // scrub/vdev detail source
poolData []zfs.PoolStat // cached pool inventory (TTL below)
lastPoolStats time.Time
kernelSamples map[string]poolKernelSample
datasetUsage map[string]zfsDatasetUsage // mountpoint -> usage
lastUsageRefresh time.Time
// Detail data (pools, vdevs, scrub, datasets) is cached and refreshed on
// an interval. Accessed from handler goroutines, so it is mutex-protected.
detailMu sync.Mutex
detail *zfsentity.ZfsData
lastDetailRefresh time.Time
detailFailed bool
}
func newStoragePoolManager() *StoragePoolManager {
return &StoragePoolManager{
backends: []*poolBackend{newZfsBackend(), newBtrfsBackend()},
detailInterval: time.Hour,
}
}
func newZfsBackend() *poolBackend {
return &poolBackend{
name: "zfs",
poolStatsFn: optionalPoolSource(zfs.PoolStats),
datasetsFn: zfs.Datasets,
kernelStatsFn: optionalPoolSource(zfs.PoolKernelStats),
poolStatusesFn: optionalPoolSource(zfs.PoolStatuses),
}
}
func newBtrfsBackend() *poolBackend {
return &poolBackend{
name: "btrfs",
poolStatsFn: btrfsSource(btrfsPoolStats),
kernelStatsFn: btrfsSource(btrfsKernelStats),
poolStatusesFn: btrfsSource(btrfsPoolStatuses),
}
}
// datasets is optional: only backends that expose datasets provide a collector.
func (b *poolBackend) datasets() ([]zfs.Dataset, error) {
if b.datasetsFn == nil {
return nil, nil
}
return b.datasetsFn()
}
// A missing utility/interface is a successfully observed absent backend.
func optionalPoolSource[T any](source func() ([]T, error)) func() ([]T, error) {
return func() ([]T, error) {
items, err := source()
if errors.Is(err, zfs.ErrNoZfs) || errors.Is(err, exec.ErrNotFound) || errors.Is(err, errors.ErrUnsupported) {
return nil, nil
}
return items, err
}
}
func btrfsSource[T any](convert func(btrfs.Filesystem) T) func() ([]T, error) {
return func() ([]T, error) {
filesystems, err := optionalPoolSource(btrfsFilesystems)()
if err != nil {
return nil, err
}
items := make([]T, 0, len(filesystems))
for _, fs := range filesystems {
items = append(items, convert(fs))
}
return items, nil
}
}
// Update refreshes systemStats.ZfsPools with the latest pool data. I/O
// throughput and health come from inexpensive kernel kstats on Linux. Pool
// capacity and dataset usage come from separately cached utility calls. The
// pool map is empty when both backends are absent.
func (m *StoragePoolManager) Update(systemStats *system.Stats) {
// Rebuild the combined map so successful pool removals clear old samples.
systemStats.ZfsPools = nil
for _, backend := range m.backends {
backend.updateBackendStats(systemStats)
}
}
func (b *poolBackend) updateBackendStats(systemStats *system.Stats) {
pools := b.poolStats()
if len(pools) == 0 {
b.kernelSamples = nil
return
}
kernelStats, ioRates := b.kernelStats()
if systemStats.ZfsPools == nil {
systemStats.ZfsPools = make(map[string]*system.ZfsPool, len(pools))
}
for i := range pools {
pool := &pools[i]
// Full precision, matching the dataset values below; the frontend
// formats any magnitude.
stats := &system.ZfsPool{
DisplayName: pool.DisplayName,
Raw: pool.Raw,
Total: float64(pool.Size) / (1024 * 1024 * 1024),
Used: float64(pool.Alloc) / (1024 * 1024 * 1024),
Health: pool.Health,
}
if kernel, exists := kernelStats[pool.Name]; exists && kernel.Health != "" {
stats.Health = kernel.Health
}
if io, exists := ioRates[pool.Name]; exists {
stats.ReadBytes = io.NRead
stats.WriteBytes = io.NWrite
}
slog.Debug("Storage pool sample", "backend", b.name, "pool", pool.Name, "health", stats.Health, "used_gb", stats.Used, "read_bps", stats.ReadBytes, "write_bps", stats.WriteBytes)
systemStats.ZfsPools[pool.Name] = stats
}
}
// poolStats returns the cached pool inventory, calling its collector at most
// every poolStatsRefreshInterval. On failure the previous inventory is
// retained and the refresh is retried on the next cadence.
func (b *poolBackend) poolStats() []zfs.PoolStat {
if b.lastPoolStats.IsZero() || time.Since(b.lastPoolStats) >= poolStatsRefreshInterval {
pools, err := b.poolStatsFn()
if err != nil {
slog.Debug("Storage pool stats unavailable", "backend", b.name, "err", err)
} else {
b.poolData = pools
}
b.lastPoolStats = time.Now()
}
return b.poolData
}
// kernelStats reads cumulative pool counters and converts them to per-second
// rates. Counter decreases indicate a pool export/import and reset the
// baseline instead of producing an underflow spike.
func (b *poolBackend) kernelStats() (map[string]zfs.PoolKernelStat, map[string]zfs.PoolIoStats) {
if b.kernelStatsFn == nil {
return nil, nil
}
stats, err := b.kernelStatsFn()
if err != nil {
slog.Debug("Storage pool kernel stats unavailable", "backend", b.name, "err", err)
return nil, nil
}
now := time.Now()
byName := make(map[string]zfs.PoolKernelStat, len(stats))
rates := make(map[string]zfs.PoolIoStats, len(stats))
nextSamples := make(map[string]poolKernelSample, len(stats))
for _, stat := range stats {
byName[stat.Name] = stat
if previous, ok := b.kernelSamples[stat.Name]; ok && now.After(previous.at) &&
stat.NRead >= previous.nread && stat.NWrite >= previous.nwrite {
seconds := now.Sub(previous.at).Seconds()
rates[stat.Name] = zfs.PoolIoStats{
NRead: uint64(float64(stat.NRead-previous.nread) / seconds),
NWrite: uint64(float64(stat.NWrite-previous.nwrite) / seconds),
}
}
nextSamples[stat.Name] = poolKernelSample{nread: stat.NRead, nwrite: stat.NWrite, at: now}
}
b.kernelSamples = nextSamples
return byName, rates
}
// refreshDatasetUsage re-runs `zfs list` when the refresh window has elapsed
// and rebuilds the mountpoint-keyed usage map.
func (b *poolBackend) refreshDatasetUsage() {
if !b.lastUsageRefresh.IsZero() && time.Since(b.lastUsageRefresh) < datasetUsageRefreshInterval {
return
}
datasets, err := b.datasets()
if err != nil {
slog.Debug("Storage pool dataset usage unavailable", "backend", b.name, "err", err)
} else {
usage := make(map[string]zfsDatasetUsage, len(datasets))
for _, ds := range datasets {
if ds.Mountpoint != "" && ds.Mountpoint != "-" {
usage[ds.Mountpoint] = zfsDatasetUsage{used: ds.Used, avail: ds.Avail}
}
}
b.datasetUsage = usage
}
b.lastUsageRefresh = time.Now()
}
// DatasetUsage returns ZFS dataset usage keyed by mountpoint, refreshed at
// most every datasetUsageRefreshInterval. On failure the previous map is
// retained and a debug log is emitted.
func (m *StoragePoolManager) DatasetUsage() map[string]zfsDatasetUsage {
for _, backend := range m.backends {
if backend.name == "zfs" {
backend.refreshDatasetUsage()
return backend.datasetUsage
}
}
return nil
}
// GetDetail combines backend snapshots, identifying successful inventories so
// the hub can accept partial updates without deleting failed backend records.
func (m *StoragePoolManager) GetDetail(force bool) *zfsentity.ZfsData {
data := &zfsentity.ZfsData{Complete: true}
for _, backend := range m.backends {
snapshot := backend.getBackendDetail(force, m.detailInterval)
data.Pools = append(data.Pools, snapshot.Pools...)
if snapshot.Complete {
data.CompleteBackends = append(data.CompleteBackends, backend.name)
} else {
data.Complete = false
}
}
return data
}
func (b *poolBackend) getBackendDetail(force bool, interval time.Duration) *zfsentity.ZfsData {
b.detailMu.Lock()
defer b.detailMu.Unlock()
if force || b.detailFailed || b.detail == nil || time.Since(b.lastDetailRefresh) >= interval {
if data, err := b.collectDetail(b.detail); err != nil {
b.detailFailed = true
slog.Debug("Storage pool detail collection failed", "backend", b.name, "err", err)
if b.detail == nil {
return &zfsentity.ZfsData{}
}
return &zfsentity.ZfsData{Pools: b.detail.Pools}
} else {
b.detailFailed = false
b.detail = data
b.lastDetailRefresh = time.Now()
}
}
if b.detail == nil {
return &zfsentity.ZfsData{}
}
return b.detail
}
// collectDetail builds a ZfsData payload from the current system state.
func (b *poolBackend) collectDetail(previous *zfsentity.ZfsData) (*zfsentity.ZfsData, error) {
pools, err := b.poolStatsFn()
if err != nil {
return nil, err
}
if len(pools) == 0 {
return &zfsentity.ZfsData{Pools: []*zfsentity.PoolDetail{}, Complete: true}, nil
}
statuses, statusErr := b.poolStatusesFn()
if statusErr != nil {
slog.Debug("Storage pool status unavailable", "backend", b.name, "err", statusErr)
}
datasets, datasetsErr := b.datasets()
if datasetsErr != nil {
slog.Debug("Storage pool datasets unavailable", "backend", b.name, "err", datasetsErr)
}
statusByPool := make(map[string]zfs.PoolStatus, len(statuses))
for _, st := range statuses {
statusByPool[st.Name] = st
}
previousByPool := make(map[string]*zfsentity.PoolDetail)
if previous != nil {
for _, pool := range previous.Pools {
if pool != nil {
previousByPool[pool.Name] = pool
}
}
}
data := &zfsentity.ZfsData{Pools: make([]*zfsentity.PoolDetail, 0, len(pools)), Complete: true}
for i := range pools {
p := &pools[i]
detail := &zfsentity.PoolDetail{
DisplayName: p.DisplayName,
Raw: p.Raw,
Name: p.Name,
Health: p.Health,
Size: p.Size,
Alloc: p.Alloc,
Free: p.Free,
}
if st, ok := statusByPool[p.Name]; statusErr == nil && ok {
if st.Scrub.State != "" && st.Scrub.State != "NONE" {
detail.Scrub = &zfsentity.Scrub{
State: st.Scrub.State,
Progress: st.Scrub.Progress,
Errors: st.Scrub.Errors,
}
}
for _, v := range st.Vdevs {
detail.Vdevs = append(detail.Vdevs, &zfsentity.Vdev{
Name: v.Name,
State: v.State,
ReadErrs: v.ReadErrs,
WriteErrs: v.WriteErrs,
ChecksumErrs: v.ChecksumErrs,
})
}
} else {
if cached := previousByPool[p.Name]; cached != nil {
detail.Scrub = cached.Scrub
detail.Vdevs = cached.Vdevs
}
}
if datasetsErr == nil {
foundDataset := false
for _, ds := range datasets {
if poolOfDataset(ds.Name) == p.Name {
foundDataset = true
detail.Datasets = append(detail.Datasets, &zfsentity.Dataset{
Name: ds.Name,
Used: ds.Used,
Avail: ds.Avail,
Mountpoint: ds.Mountpoint,
})
}
}
if !foundDataset {
if cached := previousByPool[p.Name]; cached != nil {
detail.Datasets = cached.Datasets
}
}
} else if cached := previousByPool[p.Name]; cached != nil {
detail.Datasets = cached.Datasets
}
data.Pools = append(data.Pools, detail)
}
return data, nil
}
// poolOfDataset returns the pool name for a dataset name (everything before
// the first '/'). Datasets without a separator belong to a pool of the same
// name.
func poolOfDataset(name string) string {
if idx := strings.IndexByte(name, '/'); idx >= 0 {
return name[:idx]
}
return name
}
// ZfsMountpoints returns the set of mountpoints backed by ZFS datasets.
func (m *StoragePoolManager) ZfsMountpoints() map[string]bool {
usage := m.DatasetUsage()
mountpoints := make(map[string]bool, len(usage))
for mountpoint := range usage {
mountpoints[mountpoint] = true
}
return mountpoints
}
func btrfsPoolStats(fs btrfs.Filesystem) zfs.PoolStat {
return zfs.PoolStat{MountID: fs.MountID, IODevice: fs.IODevice, Raw: fs.Raw, DisplayName: fs.Name, Name: "b:" + fs.UUID, Size: fs.Size, Alloc: fs.Alloc, Free: fs.Size - min(fs.Alloc, fs.Size), Health: fs.Health}
}
func btrfsKernelStats(fs btrfs.Filesystem) zfs.PoolKernelStat {
return zfs.PoolKernelStat{Name: "b:" + fs.UUID, Health: fs.Health, NRead: fs.NRead, NWrite: fs.NWrite}
}
func btrfsPoolStatuses(fs btrfs.Filesystem) zfs.PoolStatus {
status := zfs.PoolStatus{Name: "b:" + fs.UUID, State: fs.Health, Scrub: zfs.ScrubStatus{State: "NONE"}}
for _, dev := range fs.Devices {
status.Vdevs = append(status.Vdevs, zfs.VdevStatus{
Name: dev.Name, State: dev.State,
ReadErrs: dev.ReadErrs, WriteErrs: dev.WriteErrs, ChecksumErrs: dev.CorruptionErrs,
})
}
return status
}
// markDuplicateCharts leaves pool telemetry and detail intact, but tells the
// hub which charts already have a filesystem equivalent. Only exact kernel
// filesystem and I/O-device matches qualify; labels are never used.
func (m *StoragePoolManager) markDuplicateCharts(stats *system.Stats, filesystems map[string]*system.FsStats, mountID func(string) string) {
identities := make(map[string]string, len(filesystems))
for device, fs := range filesystems {
if fs.DiskTotal > 0 {
identities[device] = mountID(fs.Mountpoint)
}
}
for _, backend := range m.backends {
for _, pool := range backend.poolData {
sample := stats.ZfsPools[pool.Name]
if sample == nil || pool.MountID == "" {
continue
}
for device, identity := range identities {
if identity != pool.MountID {
continue
}
// Raw physical usage is not equivalent to a filesystem usage chart.
sample.HideUsage = !pool.Raw
if pool.IODevice != "" && pool.IODevice == device {
sample.HideIO = true
}
}
}
}
}
+505
View File
@@ -0,0 +1,505 @@
//go:build testing
package agent
import (
"errors"
"fmt"
"os/exec"
"strings"
"sync"
"testing"
"time"
"github.com/henrygd/beszel/agent/btrfs"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestOptionalPoolSource(t *testing.T) {
failure := errors.New("timeout")
for _, err := range []error{nil, zfs.ErrNoZfs, fmt.Errorf("zpool: %w", exec.ErrNotFound), errors.ErrUnsupported, failure} {
_, got := optionalPoolSource(func() ([]zfs.PoolStat, error) { return nil, err })()
if err == failure {
assert.ErrorIs(t, got, failure)
} else {
assert.NoError(t, got)
}
}
}
type poolTestBackend struct {
name string
err error
alloc uint64
read uint64
empty bool
}
func (state *poolTestBackend) backend() *poolBackend {
name := "zfs"
if strings.HasPrefix(state.name, "b:") {
name = "btrfs"
}
return &poolBackend{
name: name,
poolStatsFn: func() ([]zfs.PoolStat, error) {
if state.empty {
return nil, state.err
}
return []zfs.PoolStat{{Name: state.name, Size: 100, Alloc: state.alloc}}, state.err
},
kernelStatsFn: func() ([]zfs.PoolKernelStat, error) {
return []zfs.PoolKernelStat{{Name: state.name, NRead: state.read}}, state.err
},
poolStatusesFn: func() ([]zfs.PoolStatus, error) { return nil, nil },
datasetsFn: func() ([]zfs.Dataset, error) { return nil, nil },
}
}
func TestIndependentPoolBackendCaches(t *testing.T) {
for _, failed := range []int{0, 1} {
t.Run([]string{"zfs", "btrfs"}[failed], func(t *testing.T) {
states := []*poolTestBackend{{name: "tank", alloc: 10}, {name: "b:uuid", alloc: 10}}
managers := []*poolBackend{states[0].backend(), states[1].backend()}
zm := &StoragePoolManager{backends: managers, detailInterval: time.Hour}
var stats system.Stats
zm.Update(&stats)
require.Len(t, stats.ZfsPools, 2)
require.True(t, zm.GetDetail(true).Complete)
baseline := poolKernelSample{at: time.Now().Add(-time.Second)}
for i, m := range managers {
m.lastPoolStats = time.Time{}
m.kernelSamples[states[i].name] = baseline
states[i].alloc = 20
states[i].read = 100
}
states[failed].err = errors.New("collection failed")
zm.Update(&stats)
healthy := 1 - failed
assert.Equal(t, uint64(10), managers[failed].poolData[0].Alloc)
assert.Equal(t, uint64(20), managers[healthy].poolData[0].Alloc)
assert.Equal(t, baseline, managers[failed].kernelSamples[states[failed].name])
assert.Zero(t, stats.ZfsPools[states[failed].name].ReadBytes)
assert.Positive(t, stats.ZfsPools[states[healthy].name].ReadBytes)
partial := zm.GetDetail(true)
assert.False(t, partial.Complete)
assert.False(t, partial.CanRefreshPool(states[failed].name))
assert.True(t, partial.CanRefreshPool(states[healthy].name))
assert.Equal(t, uint64(10), partial.Pools[failed].Alloc)
assert.Equal(t, uint64(20), partial.Pools[healthy].Alloc)
assert.False(t, zm.GetDetail(false).Complete, "a failed forced refresh must not become complete from cache")
// Successful empty inventory removes only the healthy backend's pool.
states[healthy].empty = true
managers[healthy].lastPoolStats = time.Time{}
zm.Update(&stats)
require.Len(t, stats.ZfsPools, 1)
assert.Contains(t, stats.ZfsPools, states[failed].name)
partial = zm.GetDetail(true)
require.Len(t, partial.Pools, 1)
assert.True(t, partial.CanRefreshPool(states[healthy].name))
// Recovery uses the retained I/O baseline, then normal removal works.
states[failed].err = nil
managers[failed].lastPoolStats = time.Time{}
zm.Update(&stats)
assert.Positive(t, stats.ZfsPools[states[failed].name].ReadBytes)
assert.True(t, zm.GetDetail(true).Complete)
states[failed].empty = true
managers[failed].lastPoolStats = time.Time{}
zm.Update(&stats)
assert.Empty(t, stats.ZfsPools)
assert.Empty(t, zm.GetDetail(true).Pools)
})
}
}
func TestIndependentBackendsWithoutCache(t *testing.T) {
z := &poolTestBackend{name: "tank", err: errors.New("ZFS failure")}
b := &poolTestBackend{name: "b:uuid", alloc: 20}
zm := &StoragePoolManager{backends: []*poolBackend{z.backend(), b.backend()}, detailInterval: time.Hour}
var stats system.Stats
zm.Update(&stats)
require.Len(t, stats.ZfsPools, 1)
assert.Contains(t, stats.ZfsPools, "b:uuid")
detail := zm.GetDetail(true)
require.Len(t, detail.Pools, 1)
assert.False(t, detail.Complete)
assert.Equal(t, []string{"btrfs"}, detail.CompleteBackends)
}
func TestConcurrentBackendDetailsAndMetrics(t *testing.T) {
zm := &StoragePoolManager{backends: []*poolBackend{(&poolTestBackend{name: "tank"}).backend(), (&poolTestBackend{name: "b:uuid"}).backend()}, detailInterval: time.Hour}
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(metrics bool) {
defer wg.Done()
for j := 0; j < 10; j++ {
if metrics {
zm.Update(&system.Stats{})
} else {
zm.GetDetail(true)
}
}
}(i == 0)
}
wg.Wait()
}
func TestStoragePoolBackendOrder(t *testing.T) {
z := (&poolTestBackend{name: "tank"}).backend()
b := (&poolTestBackend{name: "b:uuid"}).backend()
b.datasetsFn = nil // Btrfs does not expose datasets.
z.datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank/data", Mountpoint: "/tank", Used: 10}}, nil
}
m := &StoragePoolManager{backends: []*poolBackend{b, z}, detailInterval: time.Hour}
var stats system.Stats
m.Update(&stats)
require.Len(t, stats.ZfsPools, 2)
detail := m.GetDetail(true)
require.True(t, detail.Complete)
assert.Equal(t, []string{"btrfs", "zfs"}, detail.CompleteBackends)
assert.Empty(t, detail.Pools[0].Datasets)
assert.Len(t, detail.Pools[1].Datasets, 1)
assert.Equal(t, uint64(10), m.DatasetUsage()["/tank"].used)
b.poolData[0].MountID = "uuid"
b.poolData[0].IODevice = "sda"
calls := 0
m.markDuplicateCharts(&stats, map[string]*system.FsStats{
"sda": {Mountpoint: "/", DiskTotal: 100},
}, func(string) string { calls++; return "uuid" })
assert.Equal(t, 1, calls, "resolve each filesystem once across all backends")
assert.True(t, stats.ZfsPools["b:uuid"].HideUsage)
assert.True(t, stats.ZfsPools["b:uuid"].HideIO)
}
func TestUpdatePopulatesZfsPools(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Size: 23999000000000, Alloc: 12000000000000, Free: 11999000000000, Health: "DEGRADED"}}, nil
}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "tank/apps", Used: 5000000000000, Avail: 11999000000000, Mountpoint: "/tank/apps"},
{Name: "tank/backup", Used: 6000000000000, Avail: 11999000000000, Mountpoint: "/tank/backup"},
// Small zvol (Proxmox VM EFI disk): must not round to zero.
{Name: "rpool/vm-100-disk-2", Used: 4194304, Avail: 0, Mountpoint: "-"},
}, nil
}
var kernelCalls int
zm.backends[0].kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
kernelCalls++
return []zfs.PoolKernelStat{{
Name: "tank", Health: "ONLINE",
NRead: uint64(kernelCalls-1) * 1250, NWrite: uint64(kernelCalls-1) * 5120,
}}, nil
}
var stats system.Stats
// The first kernel sample establishes the cumulative-counter baseline.
zm.Update(&stats)
zm.backends[0].kernelSamples["tank"] = poolKernelSample{at: time.Now().Add(-time.Second)}
zm.Update(&stats)
require.NotNil(t, stats.ZfsPools)
require.Contains(t, stats.ZfsPools, "tank")
assert.InDelta(t, 22350.8105, stats.ZfsPools["tank"].Total, 0.0001) // Size in GiB
assert.InDelta(t, 11175.8709, stats.ZfsPools["tank"].Used, 0.0001) // Alloc in GiB
assert.Equal(t, "ONLINE", stats.ZfsPools["tank"].Health)
assert.InDelta(t, 1250, stats.ZfsPools["tank"].ReadBytes, 5)
assert.InDelta(t, 5120, stats.ZfsPools["tank"].WriteBytes, 5)
}
// TestUpdateKernelStatsMissing verifies pools without a kernel sample report zero
// I/O instead of erroring.
func TestUpdateKernelStatsMissing(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Size: 1, Alloc: 1, Health: "ONLINE"}}, nil
}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.backends[0].kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
return nil, zfs.ErrNoZfs
}
var stats system.Stats
zm.Update(&stats)
require.NotNil(t, stats.ZfsPools)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].ReadBytes)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].WriteBytes)
}
func TestUpdateKernelCounterReset(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Health: "ONLINE"}}, nil
}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.backends[0].kernelSamples = map[string]poolKernelSample{
"tank": {nread: 100, nwrite: 200, at: time.Now().Add(-time.Second)},
}
zm.backends[0].kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
return []zfs.PoolKernelStat{{Name: "tank", Health: "ONLINE", NRead: 10, NWrite: 20}}, nil
}
var stats system.Stats
zm.Update(&stats)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].ReadBytes)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].WriteBytes)
}
func TestUpdateNoZfs(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
calls := 0
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
calls++
return nil, zfs.ErrNoZfs
}
var stats system.Stats
zm.Update(&stats)
zm.Update(&stats)
assert.Nil(t, stats.ZfsPools)
assert.Equal(t, 1, calls, "failed pool discovery should be cached until the next refresh interval")
}
func TestUpdateEmptyPools(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
calls := 0
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
calls++
return nil, nil
}
var stats system.Stats
zm.Update(&stats)
zm.Update(&stats)
assert.Nil(t, stats.ZfsPools)
assert.Equal(t, 1, calls, "an empty pool inventory should be cached until the next refresh interval")
}
func TestDatasetUsage(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
calls := 0
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
calls++
return []zfs.Dataset{
{Name: "tank", Used: 12000000000000, Avail: 11999000000000, Mountpoint: "/tank"},
{Name: "tank/apps", Used: 1000000000000, Avail: 11999000000000, Mountpoint: "/tank/apps"},
{Name: "rpool", Used: 900000000000, Avail: 300000000000, Mountpoint: "-"}, // zvol/unmounted: excluded
}, nil
}
usage := zm.DatasetUsage()
require.Len(t, usage, 2)
assert.Equal(t, zfsDatasetUsage{used: 12000000000000, avail: 11999000000000}, usage["/tank"])
assert.Equal(t, zfsDatasetUsage{used: 1000000000000, avail: 11999000000000}, usage["/tank/apps"])
assert.Equal(t, 1, calls)
// Second call within the refresh window must not re-run the collector.
zm.DatasetUsage()
assert.Equal(t, 1, calls)
}
func TestDatasetUsageRefreshOnErrorKeepsPrevious(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank", Used: 1, Avail: 1, Mountpoint: "/tank"}}, nil
}
assert.Len(t, zm.DatasetUsage(), 1)
// Force refresh window expiry, then a failing collector.
zm.backends[0].lastUsageRefresh = time.Now().Add(-10 * time.Minute)
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return nil, zfs.ErrNoZfs
}
usage := zm.DatasetUsage()
assert.Len(t, usage, 1, "previous usage should be retained on error")
}
func TestGetDetailForceRefresh(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
poolCalls := 0
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
poolCalls++
return []zfs.PoolStat{{Name: "tank", Alloc: uint64(poolCalls)}}, nil
}
zm.backends[0].poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
first := zm.GetDetail(false)
assert.True(t, first.Complete)
require.Len(t, first.Pools, 1)
assert.Equal(t, uint64(1), first.Pools[0].Alloc)
cached := zm.GetDetail(false)
require.Len(t, cached.Pools, 1)
assert.Equal(t, uint64(1), cached.Pools[0].Alloc)
assert.Equal(t, 1, poolCalls)
refreshed := zm.GetDetail(true)
assert.True(t, refreshed.Complete)
require.Len(t, refreshed.Pools, 1)
assert.Equal(t, uint64(2), refreshed.Pools[0].Alloc)
assert.Equal(t, 2, poolCalls)
}
func TestGetDetailSuccessfulEmptyInventoryClearsCache(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank"}}, nil
}
zm.backends[0].poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
require.Len(t, zm.GetDetail(false).Pools, 1)
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) { return nil, nil }
empty := zm.GetDetail(true)
assert.True(t, empty.Complete)
assert.Empty(t, empty.Pools)
}
func TestGetDetailFailureReturnsIncompleteCachedInventory(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank"}}, nil
}
zm.backends[0].poolStatusesFn = func() ([]zfs.PoolStatus, error) {
return []zfs.PoolStatus{{Name: "tank", Vdevs: []zfs.VdevStatus{{Name: "mirror-0"}}}}, nil
}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank/data"}}, nil
}
first := zm.GetDetail(false)
require.True(t, first.Complete)
require.Len(t, first.Pools[0].Vdevs, 1)
require.Len(t, first.Pools[0].Datasets, 1)
zm.backends[0].poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, zfs.ErrNoZfs }
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) { return nil, zfs.ErrNoZfs }
partial := zm.GetDetail(true)
require.True(t, partial.Complete)
require.Len(t, partial.Pools[0].Vdevs, 1)
require.Len(t, partial.Pools[0].Datasets, 1)
zm.backends[0].poolStatsFn = func() ([]zfs.PoolStat, error) { return nil, zfs.ErrNoZfs }
lastSuccessfulRefresh := zm.backends[0].lastDetailRefresh
failed := zm.GetDetail(true)
assert.False(t, failed.Complete)
require.Len(t, failed.Pools, 1)
assert.Equal(t, "tank", failed.Pools[0].Name)
assert.Equal(t, lastSuccessfulRefresh, zm.backends[0].lastDetailRefresh)
}
func TestZfsMountpoints(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs"}}}
zm.backends[0].datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "tank", Mountpoint: "/tank"},
{Name: "rpool/ROOT/pve-1", Mountpoint: "/"},
}, nil
}
mountpoints := zm.ZfsMountpoints()
assert.Len(t, mountpoints, 2)
assert.True(t, mountpoints["/tank"])
assert.True(t, mountpoints["/"])
}
func TestBtrfsRawCapacityPropagates(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs", poolStatsFn: func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{btrfsPoolStats(btrfs.Filesystem{UUID: "raw", Name: "raw", Size: 200, Alloc: 100, Raw: true})}, nil
},
poolStatusesFn: func() ([]zfs.PoolStatus, error) { return nil, nil },
datasetsFn: func() ([]zfs.Dataset, error) { return nil, nil }}}}
var stats system.Stats
zm.Update(&stats)
require.True(t, stats.ZfsPools["b:raw"].Raw)
detail := zm.GetDetail(true)
require.True(t, detail.Complete)
require.Len(t, detail.Pools, 1)
assert.True(t, detail.Pools[0].Raw)
}
func TestMarkDuplicatePoolCharts(t *testing.T) {
for _, tc := range []struct {
name, poolID, device string
raw bool
diskTotal float64
wantUsage, wantIO bool
}{
{"single device root", "fs1", "dm-0", false, 100, true, true},
{"multi device", "fs1", "", false, 100, true, false},
{"different IO device", "fs1", "nvme0n1", false, 100, true, false},
{"different filesystem", "fs2", "dm-0", false, 100, false, false},
{"unknown identity", "", "dm-0", false, 100, false, false},
{"raw usage", "fs1", "dm-0", true, 100, false, true},
{"failed disk collection", "fs1", "dm-0", false, 0, false, false},
} {
t.Run(tc.name, func(t *testing.T) {
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs", poolData: []zfs.PoolStat{{Name: "arbitrary label", MountID: tc.poolID, IODevice: tc.device, Raw: tc.raw}}}}}
stats := &system.Stats{ZfsPools: map[string]*system.ZfsPool{"arbitrary label": {}}}
fs := map[string]*system.FsStats{"dm-0": {Root: true, Mountpoint: "/", DiskTotal: tc.diskTotal}}
zm.markDuplicateCharts(stats, fs, func(string) string { return "fs1" })
assert.Equal(t, tc.wantUsage, stats.ZfsPools["arbitrary label"].HideUsage)
assert.Equal(t, tc.wantIO, stats.ZfsPools["arbitrary label"].HideIO)
// Bind mounts and custom extra-filesystem names have the same identity.
fs["dm-0"].Root = false
fs["dm-0"].Mountpoint = "/extra-filesystems/storage"
fs["dm-0"].Name = "custom name"
stats.ZfsPools["arbitrary label"] = &system.ZfsPool{}
zm.markDuplicateCharts(stats, fs, func(string) string { return "fs1" })
assert.Equal(t, tc.wantUsage, stats.ZfsPools["arbitrary label"].HideUsage)
assert.Equal(t, tc.wantIO, stats.ZfsPools["arbitrary label"].HideIO)
})
}
}
func TestBtrfsPoolIdentities(t *testing.T) {
old := btrfsFilesystems
t.Cleanup(func() { btrfsFilesystems = old })
label := "tank"
btrfsFilesystems = func() ([]btrfs.Filesystem, error) {
return []btrfs.Filesystem{
{UUID: "11111111-1111-4111-8111-111111111111", Name: label, Size: 100, Health: "ONLINE", NRead: 100, Devices: []btrfs.Device{{Name: "first"}}},
{UUID: "22222222-2222-4222-8222-222222222222", Name: "tank", Size: 200, Health: "DEGRADED", NRead: 200, Devices: []btrfs.Device{{Name: "second"}}},
}, nil
}
zm := &StoragePoolManager{detailInterval: time.Hour, backends: []*poolBackend{{name: "zfs", poolStatsFn: func() ([]zfs.PoolStat, error) { return []zfs.PoolStat{{Name: "tank", Size: 300}}, nil },
kernelStatsFn: func() ([]zfs.PoolKernelStat, error) { return []zfs.PoolKernelStat{{Name: "tank", NRead: 300}}, nil },
poolStatusesFn: func() ([]zfs.PoolStatus, error) {
return []zfs.PoolStatus{{Name: "tank", Vdevs: []zfs.VdevStatus{{Name: "zfs-device"}}}}, nil
},
datasetsFn: func() ([]zfs.Dataset, error) { return []zfs.Dataset{{Name: "tank/data"}}, nil }}, newBtrfsBackend()}}
first := "b:11111111-1111-4111-8111-111111111111"
second := "b:22222222-2222-4222-8222-222222222222"
var stats system.Stats
zm.Update(&stats)
require.Len(t, stats.ZfsPools, 3)
assert.Contains(t, stats.ZfsPools, "tank")
assert.Equal(t, "ONLINE", stats.ZfsPools[first].Health)
assert.Equal(t, "DEGRADED", stats.ZfsPools[second].Health)
assert.Equal(t, uint64(100), zm.backends[1].kernelSamples[first].nread)
assert.Equal(t, uint64(200), zm.backends[1].kernelSamples[second].nread)
detail := zm.GetDetail(true)
require.Len(t, detail.Pools, 3)
assert.Equal(t, "zfs-device", detail.Pools[0].Vdevs[0].Name)
assert.Len(t, detail.Pools[0].Datasets, 1)
assert.Equal(t, "first", detail.Pools[1].Vdevs[0].Name)
assert.Empty(t, detail.Pools[1].Datasets)
assert.Equal(t, "second", detail.Pools[2].Vdevs[0].Name)
label = "renamed"
zm.backends[0].lastPoolStats = time.Time{}
zm.backends[1].lastPoolStats = time.Time{}
zm.Update(&stats)
require.Len(t, stats.ZfsPools, 3)
assert.Equal(t, "renamed", stats.ZfsPools[first].DisplayName)
assert.Equal(t, first, zm.GetDetail(true).Pools[1].Name)
assert.Equal(t, "renamed", zm.GetDetail(true).Pools[1].DisplayName)
}
+4 -2
View File
@@ -12,6 +12,7 @@ import (
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/agent/battery"
"github.com/henrygd/beszel/agent/btrfs"
"github.com/henrygd/beszel/agent/utils"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/container"
@@ -219,8 +220,9 @@ func (a *Agent) getSystemStats(cacheTimeMs uint16) system.Stats {
// disk i/o (cache-aware per interval)
a.updateDiskIo(cacheTimeMs, &systemStats)
// zfs pool stats
a.zfsManager.Update(&systemStats)
// storage pool stats
a.storagePoolManager.Update(&systemStats)
a.storagePoolManager.markDuplicateCharts(&systemStats, a.fsStats, btrfs.MountID)
// network stats (per cache interval)
a.updateNetworkStats(cacheTimeMs, &systemStats)
+9 -5
View File
@@ -33,11 +33,15 @@ var ErrNoZfs = errors.New("zfs utilities unavailable")
// PoolStat is a snapshot of a ZFS pool's capacity and health.
type PoolStat struct {
Name string
Size uint64 // total capacity in bytes
Alloc uint64 // allocated bytes
Free uint64 // free bytes
Health string // ONLINE, DEGRADED, FAULTED, ...
DisplayName string // optional friendly name; Name remains the stable key
MountID string // Btrfs filesystem identity, empty for other backends
IODevice string // sole Btrfs member device, if known
Raw bool // physical accounting rather than usable filesystem space
Name string
Size uint64 // total capacity in bytes
Alloc uint64 // allocated bytes
Free uint64 // free bytes
Health string // ONLINE, DEGRADED, FAULTED, ...
}
// PoolKernelStat is the inexpensive pool telemetry exposed by the ZFS kernel.
-320
View File
@@ -1,320 +0,0 @@
package agent
import (
"log/slog"
"strings"
"sync"
"time"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/system"
zfsentity "github.com/henrygd/beszel/internal/entities/zfs"
)
// zfsDatasetUsage holds usage values for a ZFS dataset mountpoint.
type zfsDatasetUsage struct {
used uint64
avail uint64
}
// datasetUsageRefreshInterval controls how often `zfs list` is re-run for the
// mountpoint usage map. Dataset inventory changes rarely.
const datasetUsageRefreshInterval = 5 * time.Minute
// poolStatsRefreshInterval controls how often `zpool list` is re-run for pool
// capacity. Health and I/O are read from procfs on Linux, so the utility only
// needs to refresh slow-moving space accounting.
const poolStatsRefreshInterval = time.Minute
type poolKernelSample struct {
nread uint64
nwrite uint64
at time.Time
}
// ZfsManager collects ZFS pool and dataset statistics. Collection functions
// are fields so unit tests can substitute them (same pattern as
// diskDiscovery.usageFn). It is safe for concurrent use by a single goroutine
// only; callers must hold the agent lock like updateDiskUsage does.
type ZfsManager struct {
poolStatsFn func() ([]zfs.PoolStat, error) // capacity/health source
datasetsFn func() ([]zfs.Dataset, error) // dataset inventory source
kernelStatsFn func() ([]zfs.PoolKernelStat, error) // procfs pool state/I/O source
poolStatusesFn func() ([]zfs.PoolStatus, error) // scrub/vdev detail source
poolData []zfs.PoolStat // cached pool inventory (TTL below)
lastPoolStats time.Time
kernelSamples map[string]poolKernelSample
datasetUsage map[string]zfsDatasetUsage // mountpoint -> usage
lastUsageRefresh time.Time
// Detail data (pools, vdevs, scrub, datasets) is cached and refreshed on
// an interval. Accessed from handler goroutines, so it is mutex-protected.
detailMu sync.Mutex
detail *zfsentity.ZfsData
lastDetailRefresh time.Time
detailInterval time.Duration
}
// newZfsManager creates a ZfsManager wired to the system's ZFS utilities.
func newZfsManager() *ZfsManager {
return &ZfsManager{
poolStatsFn: zfs.PoolStats,
datasetsFn: zfs.Datasets,
kernelStatsFn: zfs.PoolKernelStats,
poolStatusesFn: zfs.PoolStatuses,
detailInterval: time.Hour,
}
}
// Update refreshes systemStats.ZfsPools with the latest pool data. I/O
// throughput and health come from inexpensive kernel kstats on Linux. Pool
// capacity and dataset usage come from separately cached utility calls. It is
// a no-op when ZFS is absent.
func (zm *ZfsManager) Update(systemStats *system.Stats) {
pools := zm.poolStats()
if len(pools) == 0 {
return
}
kernelStats, ioRates := zm.kernelStats()
if systemStats.ZfsPools == nil {
systemStats.ZfsPools = make(map[string]*system.ZfsPool, len(pools))
}
for i := range pools {
pool := &pools[i]
// Full precision, matching the dataset values below; the frontend
// formats any magnitude.
stats := &system.ZfsPool{
Total: float64(pool.Size) / (1024 * 1024 * 1024),
Used: float64(pool.Alloc) / (1024 * 1024 * 1024),
Health: pool.Health,
}
if kernel, exists := kernelStats[pool.Name]; exists && kernel.Health != "" {
stats.Health = kernel.Health
}
if io, exists := ioRates[pool.Name]; exists {
stats.ReadBytes = io.NRead
stats.WriteBytes = io.NWrite
}
slog.Debug("ZFS pool sample", "pool", pool.Name, "health", stats.Health, "used_gb", stats.Used, "read_bps", stats.ReadBytes, "write_bps", stats.WriteBytes)
systemStats.ZfsPools[pool.Name] = stats
}
}
// poolStats returns the cached pool inventory, re-running `zpool list` at most
// every poolStatsRefreshInterval. On failure the previous inventory is
// retained and the refresh is retried on the next cadence.
func (zm *ZfsManager) poolStats() []zfs.PoolStat {
if zm.lastPoolStats.IsZero() || time.Since(zm.lastPoolStats) >= poolStatsRefreshInterval {
pools, err := zm.poolStatsFn()
if err != nil {
slog.Debug("ZFS pool stats unavailable", "err", err)
} else {
zm.poolData = pools
}
zm.lastPoolStats = time.Now()
}
return zm.poolData
}
// kernelStats reads cumulative pool counters and converts them to per-second
// rates. Counter decreases indicate a pool export/import and reset the
// baseline instead of producing an underflow spike.
func (zm *ZfsManager) kernelStats() (map[string]zfs.PoolKernelStat, map[string]zfs.PoolIoStats) {
if zm.kernelStatsFn == nil {
return nil, nil
}
stats, err := zm.kernelStatsFn()
if err != nil {
slog.Debug("ZFS kernel stats unavailable", "err", err)
return nil, nil
}
now := time.Now()
byName := make(map[string]zfs.PoolKernelStat, len(stats))
rates := make(map[string]zfs.PoolIoStats, len(stats))
nextSamples := make(map[string]poolKernelSample, len(stats))
for _, stat := range stats {
byName[stat.Name] = stat
if previous, ok := zm.kernelSamples[stat.Name]; ok && now.After(previous.at) &&
stat.NRead >= previous.nread && stat.NWrite >= previous.nwrite {
seconds := now.Sub(previous.at).Seconds()
rates[stat.Name] = zfs.PoolIoStats{
NRead: uint64(float64(stat.NRead-previous.nread) / seconds),
NWrite: uint64(float64(stat.NWrite-previous.nwrite) / seconds),
}
}
nextSamples[stat.Name] = poolKernelSample{nread: stat.NRead, nwrite: stat.NWrite, at: now}
}
zm.kernelSamples = nextSamples
return byName, rates
}
// refreshDatasetUsage re-runs `zfs list` when the refresh window has elapsed
// and rebuilds the mountpoint-keyed usage map.
func (zm *ZfsManager) refreshDatasetUsage() {
if !zm.lastUsageRefresh.IsZero() && time.Since(zm.lastUsageRefresh) < datasetUsageRefreshInterval {
return
}
datasets, err := zm.datasetsFn()
if err != nil {
slog.Debug("ZFS dataset usage unavailable", "err", err)
} else {
usage := make(map[string]zfsDatasetUsage, len(datasets))
for _, ds := range datasets {
if ds.Mountpoint != "" && ds.Mountpoint != "-" {
usage[ds.Mountpoint] = zfsDatasetUsage{used: ds.Used, avail: ds.Avail}
}
}
zm.datasetUsage = usage
}
zm.lastUsageRefresh = time.Now()
}
// DatasetUsage returns ZFS dataset usage keyed by mountpoint, refreshed at
// most every datasetUsageRefreshInterval. On failure the previous map is
// retained and a debug log is emitted.
func (zm *ZfsManager) DatasetUsage() map[string]zfsDatasetUsage {
zm.refreshDatasetUsage()
return zm.datasetUsage
}
// GetDetail returns ZFS detail data (pool health, scrub, vdevs, datasets).
// Scheduled requests use the cached snapshot until stale; manual requests can
// force collection. On failure the previous snapshot is retained.
func (zm *ZfsManager) GetDetail(force bool) *zfsentity.ZfsData {
zm.detailMu.Lock()
defer zm.detailMu.Unlock()
if force || zm.detail == nil || time.Since(zm.lastDetailRefresh) >= zm.detailInterval {
if data, err := zm.collectDetail(zm.detail); err != nil {
slog.Debug("ZFS detail collection failed", "err", err)
if zm.detail == nil {
return &zfsentity.ZfsData{}
}
return &zfsentity.ZfsData{Pools: zm.detail.Pools}
} else {
zm.detail = data
zm.lastDetailRefresh = time.Now()
}
}
if zm.detail == nil {
return &zfsentity.ZfsData{}
}
return zm.detail
}
// collectDetail builds a ZfsData payload from the current system state.
func (zm *ZfsManager) collectDetail(previous *zfsentity.ZfsData) (*zfsentity.ZfsData, error) {
pools, err := zm.poolStatsFn()
if err != nil {
return nil, err
}
if len(pools) == 0 {
return &zfsentity.ZfsData{Pools: []*zfsentity.PoolDetail{}, Complete: true}, nil
}
statuses, statusErr := zm.poolStatusesFn()
if statusErr != nil {
slog.Debug("ZFS pool status unavailable", "err", statusErr)
}
datasets, datasetsErr := zm.datasetsFn()
if datasetsErr != nil {
slog.Debug("ZFS datasets unavailable", "err", datasetsErr)
}
statusByPool := make(map[string]zfs.PoolStatus, len(statuses))
for _, st := range statuses {
statusByPool[st.Name] = st
}
previousByPool := make(map[string]*zfsentity.PoolDetail)
if previous != nil {
for _, pool := range previous.Pools {
if pool != nil {
previousByPool[pool.Name] = pool
}
}
}
data := &zfsentity.ZfsData{Pools: make([]*zfsentity.PoolDetail, 0, len(pools)), Complete: true}
for i := range pools {
p := &pools[i]
detail := &zfsentity.PoolDetail{
Name: p.Name,
Health: p.Health,
Size: p.Size,
Alloc: p.Alloc,
Free: p.Free,
}
if st, ok := statusByPool[p.Name]; statusErr == nil && ok {
if st.Scrub.State != "" && st.Scrub.State != "NONE" {
detail.Scrub = &zfsentity.Scrub{
State: st.Scrub.State,
Progress: st.Scrub.Progress,
Errors: st.Scrub.Errors,
}
}
for _, v := range st.Vdevs {
detail.Vdevs = append(detail.Vdevs, &zfsentity.Vdev{
Name: v.Name,
State: v.State,
ReadErrs: v.ReadErrs,
WriteErrs: v.WriteErrs,
ChecksumErrs: v.ChecksumErrs,
})
}
} else {
if cached := previousByPool[p.Name]; cached != nil {
detail.Scrub = cached.Scrub
detail.Vdevs = cached.Vdevs
}
}
if datasetsErr == nil {
foundDataset := false
for _, ds := range datasets {
if poolOfDataset(ds.Name) == p.Name {
foundDataset = true
detail.Datasets = append(detail.Datasets, &zfsentity.Dataset{
Name: ds.Name,
Used: ds.Used,
Avail: ds.Avail,
Mountpoint: ds.Mountpoint,
})
}
}
if !foundDataset {
if cached := previousByPool[p.Name]; cached != nil {
detail.Datasets = cached.Datasets
}
}
} else if cached := previousByPool[p.Name]; cached != nil {
detail.Datasets = cached.Datasets
}
data.Pools = append(data.Pools, detail)
}
return data, nil
}
// poolOfDataset returns the pool name for a dataset name (everything before
// the first '/'). Datasets without a separator belong to a pool of the same
// name.
func poolOfDataset(name string) string {
if idx := strings.IndexByte(name, '/'); idx >= 0 {
return name[:idx]
}
return name
}
// ZfsMountpoints returns the set of mountpoints backed by ZFS datasets.
func (zm *ZfsManager) ZfsMountpoints() map[string]bool {
usage := zm.DatasetUsage()
mountpoints := make(map[string]bool, len(usage))
for mountpoint := range usage {
mountpoints[mountpoint] = true
}
return mountpoints
}
-245
View File
@@ -1,245 +0,0 @@
//go:build testing
package agent
import (
"testing"
"time"
"github.com/henrygd/beszel/agent/zfs"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUpdatePopulatesZfsPools(t *testing.T) {
zm := &ZfsManager{}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Size: 23999000000000, Alloc: 12000000000000, Free: 11999000000000, Health: "DEGRADED"}}, nil
}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "tank/apps", Used: 5000000000000, Avail: 11999000000000, Mountpoint: "/tank/apps"},
{Name: "tank/backup", Used: 6000000000000, Avail: 11999000000000, Mountpoint: "/tank/backup"},
// Small zvol (Proxmox VM EFI disk): must not round to zero.
{Name: "rpool/vm-100-disk-2", Used: 4194304, Avail: 0, Mountpoint: "-"},
}, nil
}
var kernelCalls int
zm.kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
kernelCalls++
return []zfs.PoolKernelStat{{
Name: "tank", Health: "ONLINE",
NRead: uint64(kernelCalls-1) * 1250, NWrite: uint64(kernelCalls-1) * 5120,
}}, nil
}
var stats system.Stats
// The first kernel sample establishes the cumulative-counter baseline.
zm.Update(&stats)
zm.kernelSamples["tank"] = poolKernelSample{at: time.Now().Add(-time.Second)}
zm.Update(&stats)
require.NotNil(t, stats.ZfsPools)
require.Contains(t, stats.ZfsPools, "tank")
assert.InDelta(t, 22350.8105, stats.ZfsPools["tank"].Total, 0.0001) // Size in GiB
assert.InDelta(t, 11175.8709, stats.ZfsPools["tank"].Used, 0.0001) // Alloc in GiB
assert.Equal(t, "ONLINE", stats.ZfsPools["tank"].Health)
assert.InDelta(t, 1250, stats.ZfsPools["tank"].ReadBytes, 5)
assert.InDelta(t, 5120, stats.ZfsPools["tank"].WriteBytes, 5)
}
// TestUpdateKernelStatsMissing verifies pools without a kernel sample report zero
// I/O instead of erroring.
func TestUpdateKernelStatsMissing(t *testing.T) {
zm := &ZfsManager{}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Size: 1, Alloc: 1, Health: "ONLINE"}}, nil
}
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
return nil, zfs.ErrNoZfs
}
var stats system.Stats
zm.Update(&stats)
require.NotNil(t, stats.ZfsPools)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].ReadBytes)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].WriteBytes)
}
func TestUpdateKernelCounterReset(t *testing.T) {
zm := &ZfsManager{}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank", Health: "ONLINE"}}, nil
}
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
zm.kernelSamples = map[string]poolKernelSample{
"tank": {nread: 100, nwrite: 200, at: time.Now().Add(-time.Second)},
}
zm.kernelStatsFn = func() ([]zfs.PoolKernelStat, error) {
return []zfs.PoolKernelStat{{Name: "tank", Health: "ONLINE", NRead: 10, NWrite: 20}}, nil
}
var stats system.Stats
zm.Update(&stats)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].ReadBytes)
assert.Equal(t, uint64(0), stats.ZfsPools["tank"].WriteBytes)
}
func TestUpdateNoZfs(t *testing.T) {
zm := &ZfsManager{}
calls := 0
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
calls++
return nil, zfs.ErrNoZfs
}
var stats system.Stats
zm.Update(&stats)
zm.Update(&stats)
assert.Nil(t, stats.ZfsPools)
assert.Equal(t, 1, calls, "failed pool discovery should be cached until the next refresh interval")
}
func TestUpdateEmptyPools(t *testing.T) {
zm := &ZfsManager{}
calls := 0
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
calls++
return nil, nil
}
var stats system.Stats
zm.Update(&stats)
zm.Update(&stats)
assert.Nil(t, stats.ZfsPools)
assert.Equal(t, 1, calls, "an empty pool inventory should be cached until the next refresh interval")
}
func TestDatasetUsage(t *testing.T) {
zm := &ZfsManager{}
calls := 0
zm.datasetsFn = func() ([]zfs.Dataset, error) {
calls++
return []zfs.Dataset{
{Name: "tank", Used: 12000000000000, Avail: 11999000000000, Mountpoint: "/tank"},
{Name: "tank/apps", Used: 1000000000000, Avail: 11999000000000, Mountpoint: "/tank/apps"},
{Name: "rpool", Used: 900000000000, Avail: 300000000000, Mountpoint: "-"}, // zvol/unmounted: excluded
}, nil
}
usage := zm.DatasetUsage()
require.Len(t, usage, 2)
assert.Equal(t, zfsDatasetUsage{used: 12000000000000, avail: 11999000000000}, usage["/tank"])
assert.Equal(t, zfsDatasetUsage{used: 1000000000000, avail: 11999000000000}, usage["/tank/apps"])
assert.Equal(t, 1, calls)
// Second call within the refresh window must not re-run the collector.
zm.DatasetUsage()
assert.Equal(t, 1, calls)
}
func TestDatasetUsageRefreshOnErrorKeepsPrevious(t *testing.T) {
zm := &ZfsManager{}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank", Used: 1, Avail: 1, Mountpoint: "/tank"}}, nil
}
assert.Len(t, zm.DatasetUsage(), 1)
// Force refresh window expiry, then a failing collector.
zm.lastUsageRefresh = time.Now().Add(-10 * time.Minute)
zm.datasetsFn = func() ([]zfs.Dataset, error) {
return nil, zfs.ErrNoZfs
}
usage := zm.DatasetUsage()
assert.Len(t, usage, 1, "previous usage should be retained on error")
}
func TestGetDetailForceRefresh(t *testing.T) {
zm := &ZfsManager{detailInterval: time.Hour}
poolCalls := 0
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
poolCalls++
return []zfs.PoolStat{{Name: "tank", Alloc: uint64(poolCalls)}}, nil
}
zm.poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
first := zm.GetDetail(false)
assert.True(t, first.Complete)
require.Len(t, first.Pools, 1)
assert.Equal(t, uint64(1), first.Pools[0].Alloc)
cached := zm.GetDetail(false)
require.Len(t, cached.Pools, 1)
assert.Equal(t, uint64(1), cached.Pools[0].Alloc)
assert.Equal(t, 1, poolCalls)
refreshed := zm.GetDetail(true)
assert.True(t, refreshed.Complete)
require.Len(t, refreshed.Pools, 1)
assert.Equal(t, uint64(2), refreshed.Pools[0].Alloc)
assert.Equal(t, 2, poolCalls)
}
func TestGetDetailSuccessfulEmptyInventoryClearsCache(t *testing.T) {
zm := &ZfsManager{detailInterval: time.Hour}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank"}}, nil
}
zm.poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, nil }
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, nil }
require.Len(t, zm.GetDetail(false).Pools, 1)
zm.poolStatsFn = func() ([]zfs.PoolStat, error) { return nil, nil }
empty := zm.GetDetail(true)
assert.True(t, empty.Complete)
assert.Empty(t, empty.Pools)
}
func TestGetDetailFailureReturnsIncompleteCachedInventory(t *testing.T) {
zm := &ZfsManager{detailInterval: time.Hour}
zm.poolStatsFn = func() ([]zfs.PoolStat, error) {
return []zfs.PoolStat{{Name: "tank"}}, nil
}
zm.poolStatusesFn = func() ([]zfs.PoolStatus, error) {
return []zfs.PoolStatus{{Name: "tank", Vdevs: []zfs.VdevStatus{{Name: "mirror-0"}}}}, nil
}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{{Name: "tank/data"}}, nil
}
first := zm.GetDetail(false)
require.True(t, first.Complete)
require.Len(t, first.Pools[0].Vdevs, 1)
require.Len(t, first.Pools[0].Datasets, 1)
zm.poolStatusesFn = func() ([]zfs.PoolStatus, error) { return nil, zfs.ErrNoZfs }
zm.datasetsFn = func() ([]zfs.Dataset, error) { return nil, zfs.ErrNoZfs }
partial := zm.GetDetail(true)
require.True(t, partial.Complete)
require.Len(t, partial.Pools[0].Vdevs, 1)
require.Len(t, partial.Pools[0].Datasets, 1)
zm.poolStatsFn = func() ([]zfs.PoolStat, error) { return nil, zfs.ErrNoZfs }
lastSuccessfulRefresh := zm.lastDetailRefresh
failed := zm.GetDetail(true)
assert.False(t, failed.Complete)
require.Len(t, failed.Pools, 1)
assert.Equal(t, "tank", failed.Pools[0].Name)
assert.Equal(t, lastSuccessfulRefresh, zm.lastDetailRefresh)
}
func TestZfsMountpoints(t *testing.T) {
zm := &ZfsManager{}
zm.datasetsFn = func() ([]zfs.Dataset, error) {
return []zfs.Dataset{
{Name: "tank", Mountpoint: "/tank"},
{Name: "rpool/ROOT/pve-1", Mountpoint: "/"},
}, nil
}
mountpoints := zm.ZfsMountpoints()
assert.Len(t, mountpoints, 2)
assert.True(t, mountpoints["/tank"])
assert.True(t, mountpoints["/"])
}
+1 -1
View File
@@ -10,7 +10,7 @@ require (
github.com/gliderlabs/ssh v0.3.8
github.com/google/uuid v1.6.0
github.com/lxzan/gws v1.10.1
github.com/nicholas-fedor/shoutrrr v0.19.0
github.com/nicholas-fedor/shoutrrr v0.20.0
github.com/pocketbase/dbx v1.12.0
github.com/pocketbase/pocketbase v0.40.2
github.com/shirou/gopsutil/v4 v4.26.8
+4 -4
View File
@@ -54,8 +54,8 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/pprof v0.0.0-20260902005441-ca85771921e4 h1:/6mPXfWmhv8eKck12I0YNIcIjwHtxP3YRIMKiEgTjWg=
github.com/google/pprof v0.0.0-20260902005441-ca85771921e4/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/pprof v0.0.0-20260906184651-6331bc6350fe h1:QAinXoAFJdGQYztXn3VpFey7KCwpedbZ/EkzbplQ0cY=
github.com/google/pprof v0.0.0-20260906184651-6331bc6350fe/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
@@ -83,8 +83,8 @@ github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsRe
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
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/nicholas-fedor/shoutrrr v0.19.0 h1:Rl6bpK3DXuR2Trtx2JV8t+wjUwkHdRHrc8nBKoEpHr0=
github.com/nicholas-fedor/shoutrrr v0.19.0/go.mod h1:Glfdi8AGTbnEn2k2+hW62n8oL0i9vqRVFtXaUIthNks=
github.com/nicholas-fedor/shoutrrr v0.20.0 h1:hMAxIYlfAeZ1FcTDgU0kUOvVXUsOirWo8IWlnzGLkac=
github.com/nicholas-fedor/shoutrrr v0.20.0/go.mod h1:hgde37yNWCXh8+N6WemyDRMNYLOFTf326GsBx8Z7CFA=
github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
github.com/onsi/gomega v1.43.0 h1:VlG/1FxqNxhSO+lq/OHBNaaqwiBK/mO8JbVkX9Y+FeU=
+23 -6
View File
@@ -20,10 +20,10 @@ type hubLike interface {
}
type AlertManager struct {
hub hubLike
stopOnce sync.Once
pendingAlerts sync.Map
alertsCache *AlertsCache
hub hubLike
stopOnce sync.Once
pendingAlerts sync.Map
alertsCache *AlertsCache
}
type AlertMessageData struct {
@@ -66,6 +66,7 @@ type SystemAlertGPUData struct {
}
type SystemAlertZfsPool struct {
Raw bool `json:"raw,omitempty"`
Total float64 `json:"d"`
Used float64 `json:"du"`
}
@@ -231,8 +232,20 @@ func (am *AlertManager) SendAlert(data AlertMessageData) error {
am.hub.Logger().Error("Failed to unmarshal user settings", "err", err)
}
// send alerts via webhooks
send := sendPublicNotification
if len(userAlertSettings.Webhooks) > 0 {
// Read the owner's current role at delivery time, including for URLs
// saved before an admin was demoted. Never fall back on lookup failure.
owner, err := am.hub.FindRecordById("users", data.UserID)
if err != nil {
return fmt.Errorf("load notification owner: %w", err)
}
if owner.GetString("role") == "admin" {
send = shoutrrr.Send
}
}
for _, webhook := range userAlertSettings.Webhooks {
if err := am.SendShoutrrrAlert(webhook, data.Title, data.Message, data.Link, data.LinkText); err != nil {
if err := am.sendShoutrrrAlert(webhook, data.Title, data.Message, data.Link, data.LinkText, send); err != nil {
am.hub.Logger().Error("Failed to send shoutrrr alert", "err", err)
}
}
@@ -263,6 +276,10 @@ func (am *AlertManager) SendAlert(data AlertMessageData) error {
// SendShoutrrrAlert sends an alert via a Shoutrrr URL
func (am *AlertManager) SendShoutrrrAlert(notificationUrl, title, message, link, linkText string) error {
return am.sendShoutrrrAlert(notificationUrl, title, message, link, linkText, shoutrrr.Send)
}
func (am *AlertManager) sendShoutrrrAlert(notificationUrl, title, message, link, linkText string, send func(string, string) error) error {
// Parse the URL
parsedURL, err := url.Parse(notificationUrl)
if err != nil {
@@ -305,7 +322,7 @@ func (am *AlertManager) SendShoutrrrAlert(notificationUrl, title, message, link,
parsedURL.RawQuery = queryParams.Encode()
// log.Println("URL after modification:", parsedURL.String())
err = shoutrrr.Send(parsedURL.String(), message)
err = send(parsedURL.String(), message)
if err == nil {
am.hub.Logger().Info("Sent shoutrrr alert", "title", title)
+7 -65
View File
@@ -3,13 +3,11 @@ package alerts
import (
"database/sql"
"errors"
"net"
"net/http"
"net/url"
"slices"
"strings"
"github.com/henrygd/beszel/internal/hub/utils"
"github.com/nicholas-fedor/shoutrrr"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
)
@@ -147,72 +145,16 @@ func (am *AlertManager) SendTestNotification(e *core.RequestEvent) error {
if err != nil || data.URL == "" {
return e.BadRequestError("URL is required", err)
}
// Only allow admins to send test notifications to internal URLs
send := shoutrrr.Send
if !e.Auth.IsSuperuser() && e.Auth.GetString("role") != "admin" {
internalURL, err := isInternalURL(data.URL)
if err != nil {
return e.BadRequestError(err.Error(), nil)
}
if internalURL {
return e.ForbiddenError("Only admins can send to internal destinations", nil)
}
send = sendPublicNotification
}
err = am.sendShoutrrrAlert(data.URL, "Test Alert", "This is a notification from Beszel.", am.hub.Settings().Meta.AppURL, "View Beszel", send)
if errors.Is(err, errInternalDestination) || errors.Is(err, errUnrestrictedService) {
return e.ForbiddenError(err.Error(), nil)
}
err = am.SendShoutrrrAlert(data.URL, "Test Alert", "This is a notification from Beszel.", am.hub.Settings().Meta.AppURL, "View Beszel")
if err != nil {
return e.JSON(200, map[string]string{"err": err.Error()})
}
return e.JSON(200, map[string]bool{"err": false})
}
// isInternalURL checks if the given shoutrrr URL points to an internal destination (localhost or private IP)
func isInternalURL(rawURL string) (bool, error) {
parsedURL, err := url.Parse(rawURL)
if err != nil {
return false, err
}
host := parsedURL.Hostname()
if host == "" {
return false, nil
}
if strings.EqualFold(host, "localhost") {
return true, nil
}
if ip := net.ParseIP(host); ip != nil {
return isInternalIP(ip), nil
}
// Some Shoutrrr URLs use the host position for service identifiers rather than a
// network hostname (for example, discord://token@webhookid). Restrict DNS lookups
// to names that look like actual hostnames so valid service URLs keep working.
if !strings.Contains(host, ".") {
return false, nil
}
ips, err := net.LookupIP(host)
if err != nil {
return false, nil
}
if slices.ContainsFunc(ips, isInternalIP) {
return true, nil
}
return false, nil
}
var cgnatNetwork = &net.IPNet{
IP: net.IPv4(100, 64, 0, 0),
Mask: net.CIDRMask(10, 32),
}
func isInternalIP(ip net.IP) bool {
return ip.IsPrivate() ||
ip.IsLoopback() ||
ip.IsUnspecified() ||
ip.IsLinkLocalUnicast() ||
ip.IsMulticast() ||
cgnatNetwork.Contains(ip)
}
+33 -44
View File
@@ -7,10 +7,11 @@ import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync/atomic"
"testing"
"github.com/henrygd/beszel/internal/alerts"
beszelTests "github.com/henrygd/beszel/internal/tests"
pbTests "github.com/pocketbase/pocketbase/tests"
@@ -29,43 +30,6 @@ func jsonReader(v any) io.Reader {
return bytes.NewReader(data)
}
func TestIsInternalURL(t *testing.T) {
testCases := []struct {
name string
url string
internal bool
}{
{name: "loopback ipv4", url: "generic://127.0.0.1", internal: true},
{name: "private ipv4", url: "generic://10.0.0.1", internal: true},
{name: "localhost hostname", url: "generic://localhost", internal: true},
{name: "localhost with path", url: "generic+http://localhost/api/v1/postStuff", internal: true},
{name: "loopback with port and path", url: "generic+http://127.0.0.1:8080/api/v1/postStuff", internal: true},
{name: "public hostname", url: "generic+https://beszel.dev/api/v1/postStuff", internal: false},
{name: "cloud metadata ipv4", url: "generic://169.254.169.254", internal: true},
{name: "link-local ipv4", url: "generic://169.254.1.1", internal: true},
{name: "link-local ipv6", url: "generic://[fe80::1]", internal: true},
{name: "mapped link-local ipv4", url: "generic://[::ffff:169.254.169.254]", internal: true},
{name: "cgnat lower boundary", url: "generic://100.64.0.0", internal: true},
{name: "cgnat upper boundary", url: "generic://100.127.255.255", internal: true},
{name: "below cgnat", url: "generic://100.63.255.255", internal: false},
{name: "above cgnat", url: "generic://100.128.0.0", internal: false},
{name: "multicast ipv4", url: "generic://224.0.0.1", internal: true},
{name: "multicast ipv6", url: "generic://[ff02::1]", internal: true},
{name: "public ipv4", url: "generic://8.8.8.8", internal: false},
{name: "public ipv6", url: "generic://[2001:4860:4860::8888]", internal: false},
{name: "token style service url", url: "discord://abc123@123456789", internal: false},
{name: "single label service url", url: "slack://token@team/channel", internal: false},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
internal, err := alerts.IsInternalURL(testCase.url)
assert.NoError(t, err)
assert.Equal(t, testCase.internal, internal)
})
}
}
func TestUserAlertsApi(t *testing.T) {
hub, _ := beszelTests.NewTestHub(t.TempDir())
defer hub.Cleanup()
@@ -457,6 +421,17 @@ func TestSendTestNotification(t *testing.T) {
hub, user := beszelTests.GetHubWithUser(t)
defer hub.Cleanup()
var delivered atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
delivered.Add(1)
}))
defer server.Close()
localURL := "generic+" + server.URL
readonlyUser, err := beszelTests.CreateUserWithRole(hub, "readonly@example.com", "password123", "readonly")
assert.NoError(t, err)
readonlyToken, err := readonlyUser.NewAuthToken()
assert.NoError(t, err)
userToken, err := user.NewAuthToken()
adminUser, err := beszelTests.CreateUserWithRole(hub, "admin@example.com", "password123", "admin")
@@ -481,11 +456,11 @@ func TestSendTestNotification(t *testing.T) {
ExpectedContent: []string{"requires valid"},
TestAppFactory: testAppFactory,
Body: jsonReader(map[string]any{
"url": "generic://127.0.0.1",
"url": localURL,
}),
},
{
Name: "POST /test-notification - with external auth should succeed",
Name: "POST /test-notification - invalid service reports error",
Method: http.MethodPost,
URL: "/api/beszel/test-notification",
TestAppFactory: testAppFactory,
@@ -493,7 +468,7 @@ func TestSendTestNotification(t *testing.T) {
"Authorization": userToken,
},
Body: jsonReader(map[string]any{
"url": "generic://8.8.8.8",
"url": "unknown://example.com",
}),
ExpectedStatus: 200,
ExpectedContent: []string{"\"err\":"},
@@ -535,10 +510,10 @@ func TestSendTestNotification(t *testing.T) {
"Authorization": adminUserToken,
},
Body: jsonReader(map[string]any{
"url": "generic://127.0.0.1",
"url": localURL,
}),
ExpectedStatus: 200,
ExpectedContent: []string{"\"err\":"},
ExpectedContent: []string{"\"err\":false"},
},
{
Name: "POST /test-notification - internal url with superuser auth should succeed",
@@ -549,14 +524,28 @@ func TestSendTestNotification(t *testing.T) {
"Authorization": superuserToken,
},
Body: jsonReader(map[string]any{
"url": "generic://127.0.0.1",
"url": localURL,
}),
ExpectedStatus: 200,
ExpectedContent: []string{"\"err\":"},
},
}
for _, url := range []string{localURL, "smtp://user:pass@127.0.0.1/?fromAddress=sender@example.com&toAddresses=recipient@example.com", "mqtt://127.0.0.1/topic"} {
scenarios = append(scenarios, beszelTests.ApiScenario{
Name: "readonly cannot send to " + url,
Method: http.MethodPost,
URL: "/api/beszel/test-notification",
TestAppFactory: testAppFactory,
Headers: map[string]string{"Authorization": readonlyToken},
Body: jsonReader(map[string]any{"url": url}),
ExpectedStatus: 403,
ExpectedContent: []string{"Only admins"},
})
}
for _, scenario := range scenarios {
scenario.Test(t)
}
assert.EqualValues(t, 2, delivered.Load(), "only admin and superuser requests should reach the server")
}
+8 -3
View File
@@ -78,7 +78,7 @@ func (am *AlertManager) HandleSystemAlerts(systemRecord *core.Record, data *syst
}
}
for _, pool := range data.Stats.ZfsPools {
if pool != nil && pool.Total > 0 {
if pool != nil && !pool.Raw && pool.Total > 0 {
usedPct := pool.Used / pool.Total * 100
if usedPct > maxUsedPct {
maxUsedPct = usedPct
@@ -256,7 +256,7 @@ func (am *AlertManager) HandleSystemAlerts(systemRecord *core.Record, data *syst
}
// add zfs pool usage from historical record
for key, pool := range stats.ZfsPools {
if pool.Total > 0 {
if !pool.Raw && pool.Total > 0 {
zfsKey := zfsDiskAlertKey(key)
if _, ok := alert.mapSums[zfsKey]; !ok {
alert.mapSums[zfsKey] = 0.0
@@ -319,6 +319,11 @@ func (am *AlertManager) HandleSystemAlerts(systemRecord *core.Record, data *syst
if sumPct > maxPct {
maxPct = sumPct
alert.descriptor = diskAlertDescriptor(key)
if poolKey, ok := strings.CutPrefix(key, "zfs:"); ok {
if pool := data.Stats.ZfsPools[poolKey]; pool != nil && pool.DisplayName != "" {
alert.descriptor = diskAlertDescriptor(zfsDiskAlertKey(pool.DisplayName))
}
}
}
}
alert.val = float64(maxPct / float32(alert.count))
@@ -370,7 +375,7 @@ func zfsDiskAlertKey(poolName string) string {
func diskAlertDescriptor(key string) string {
if poolName, ok := strings.CutPrefix(key, "zfs:"); ok {
return fmt.Sprintf("Usage of ZFS pool %s", poolName)
return fmt.Sprintf("Usage of storage pool %s", poolName)
}
return fmt.Sprintf("Usage of %s", key)
}
-4
View File
@@ -100,10 +100,6 @@ func (am *AlertManager) SetAlertTriggered(alert CachedAlertData, triggered bool)
return am.setAlertTriggered(alert, triggered)
}
func IsInternalURL(rawURL string) (bool, error) {
return isInternalURL(rawURL)
}
// BuildContainerLogExcerpt exposes buildContainerLogExcerpt for testing.
func BuildContainerLogExcerpt(raw string) string {
return buildContainerLogExcerpt(raw)
+66
View File
@@ -0,0 +1,66 @@
//go:build testing
package alerts_test
import (
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"github.com/henrygd/beszel/internal/alerts"
beszelTests "github.com/henrygd/beszel/internal/tests"
"github.com/pocketbase/dbx"
"github.com/stretchr/testify/require"
)
func TestPersistedWebhooksUseCurrentOwnerRole(t *testing.T) {
hub, user := beszelTests.GetHubWithUser(t)
defer hub.Cleanup()
am := alerts.NewTestAlertManagerWithoutWorker(hub)
var delivered atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
delivered.Add(1)
}))
defer server.Close()
settings, err := hub.FindFirstRecordByFilter("user_settings", "user={:user}", dbx.Params{"user": user.Id})
require.NoError(t, err)
settings.Set("settings", alerts.UserNotificationSettings{Webhooks: []string{"generic+" + server.URL}})
require.NoError(t, hub.Save(settings))
message := alerts.AlertMessageData{UserID: user.Id, Title: "Test", Message: "Persisted webhook"}
// Keep the same URL and manager while changing roles, so cached privileges
// or treating previously saved URLs as trusted would fail this test.
for _, tc := range []struct {
name string
role string
want int32
}{
{"regular user", "user", 0},
{"readonly user", "readonly", 0},
{"promoted admin", "admin", 1},
{"demoted admin", "user", 1},
} {
t.Run(tc.name, func(t *testing.T) {
user.Set("role", tc.role)
require.NoError(t, hub.Save(user))
// Webhook errors are logged; SendAlert continues to email delivery.
require.NoError(t, am.SendAlert(message))
require.Equal(t, tc.want, delivered.Load())
})
}
t.Run("missing owner fails closed", func(t *testing.T) {
// Model an orphaned settings record without deleting it through the
// normal user deletion cascade.
const missingOwner = "missingowner123"
settings.Set("user", missingOwner)
require.NoError(t, hub.SaveNoValidate(settings))
message.UserID = missingOwner
err := am.SendAlert(message)
require.ErrorContains(t, err, "load notification owner")
require.EqualValues(t, 1, delivered.Load())
})
}
+8 -5
View File
@@ -46,12 +46,15 @@ func (am *AlertManager) handleZfsPoolHealthAlert(e *core.RecordEvent, oldHealth
}
systemName := systemRecord.GetString("name")
poolName := e.Record.GetString("name")
poolName := e.Record.GetString("display_name")
if poolName == "" {
poolName = e.Record.GetString("name")
}
title := fmt.Sprintf("ZFS pool %s on %s: %s", newHealth, systemName, poolName)
message := fmt.Sprintf("ZFS pool %s (%s) was first observed as %s", poolName, systemName, newHealth)
title := fmt.Sprintf("Storage pool %s on %s: %s", newHealth, systemName, poolName)
message := fmt.Sprintf("Storage pool %s (%s) was first observed as %s", poolName, systemName, newHealth)
if oldSeverity > 0 {
message = fmt.Sprintf("ZFS pool %s (%s) health changed from %s to %s", poolName, systemName, oldHealth, newHealth)
message = fmt.Sprintf("Storage pool %s (%s) health changed from %s to %s", poolName, systemName, oldHealth, newHealth)
}
userIDs := systemRecord.GetStringSlice("users")
@@ -116,7 +119,7 @@ func createZfsPoolHistoryRecord(app core.App, userID, systemID, alertID, poolNam
record.Set("user", userID)
record.Set("system", systemID)
record.Set("alert_id", alertID)
record.Set("name", "ZFS Pool: "+poolName)
record.Set("name", "Storage Pool: "+poolName)
return app.Save(record)
}
+34
View File
@@ -143,3 +143,37 @@ func TestDiskAlertZfsPoolMultiMinute(t *testing.T) {
assert.False(t, diskAlert.GetBool("triggered"),
"Alert should be resolved when ZFS pool average (50%%) drops below threshold (80%%)")
}
func TestDiskAlertIgnoresRawPool(t *testing.T) {
for _, minutes := range []int{0, 2} {
hub, user := beszelTests.GetHubWithUser(t)
systems, err := beszelTests.CreateSystems(hub, 1, user.Id, "up")
require.NoError(t, err)
alert, err := beszelTests.CreateRecord(hub, "alerts", map[string]any{"name": "Disk", "system": systems[0].Id, "user": user.Id, "value": 80, "min": minutes})
require.NoError(t, err)
pools := map[string]*system.ZfsPool{"btrfs": {Total: 100, Used: 99, Raw: true}}
for _, offset := range []time.Duration{-180, -90, -60, -30} {
data, err := json.Marshal(system.Stats{ZfsPools: pools})
require.NoError(t, err)
record, err := beszelTests.CreateRecord(hub, "system_stats", map[string]any{"system": systems[0].Id, "type": "1m", "stats": string(data)})
require.NoError(t, err)
record.SetRaw("created", time.Now().UTC().Add(offset*time.Second).Format(types.DefaultDateLayout))
require.NoError(t, hub.SaveNoValidate(record))
}
require.NoError(t, hub.GetAlertManager().HandleSystemAlerts(systems[0], &system.CombinedData{Stats: system.Stats{ZfsPools: pools}}))
time.Sleep(20 * time.Millisecond)
record, err := hub.FindRecordById("alerts", alert.Id)
require.NoError(t, err)
assert.False(t, record.GetBool("triggered"))
if minutes > 0 {
// A current usable sample must not make raw historical values eligible.
pools["btrfs"].Raw = false
require.NoError(t, hub.GetAlertManager().HandleSystemAlerts(systems[0], &system.CombinedData{Stats: system.Stats{ZfsPools: pools}}))
time.Sleep(20 * time.Millisecond)
record, err = hub.FindRecordById("alerts", alert.Id)
require.NoError(t, err)
assert.False(t, record.GetBool("triggered"))
}
hub.Cleanup()
}
}
+1 -1
View File
@@ -10,6 +10,6 @@ import (
func TestZfsDiskAlertKeyIsNamespaced(t *testing.T) {
assert.Equal(t, "zfs:tank", zfsDiskAlertKey("tank"))
assert.Equal(t, "Usage of ZFS pool tank", diskAlertDescriptor(zfsDiskAlertKey("tank")))
assert.Equal(t, "Usage of storage pool tank", diskAlertDescriptor(zfsDiskAlertKey("tank")))
assert.Equal(t, "Usage of tank", diskAlertDescriptor("tank"))
}
+3 -3
View File
@@ -42,7 +42,7 @@ func TestZfsPoolAlertOnlineToDegraded(t *testing.T) {
assert.EqualValues(t, 1, hub.TestMailer.TotalSend(), "should have 1 email sent after pool became DEGRADED")
lastMessage := hub.TestMailer.LastMessage()
assert.Contains(t, lastMessage.Subject, "ZFS pool DEGRADED on test-system")
assert.Contains(t, lastMessage.Subject, "Storage pool DEGRADED on test-system")
assert.Contains(t, lastMessage.Subject, "tank")
assert.Contains(t, lastMessage.Text, "ONLINE to DEGRADED")
}
@@ -76,7 +76,7 @@ func TestZfsPoolAlertDegradedToFaulted(t *testing.T) {
assert.EqualValues(t, 2, hub.TestMailer.TotalSend(), "should alert on initial DEGRADED state and later FAULTED transition")
lastMessage := hub.TestMailer.LastMessage()
assert.Contains(t, lastMessage.Subject, "ZFS pool FAULTED on test-system")
assert.Contains(t, lastMessage.Subject, "Storage pool FAULTED on test-system")
}
func TestZfsPoolAlertNoAlertOnRecovery(t *testing.T) {
@@ -239,7 +239,7 @@ func TestZfsPoolAlertWritesHistory(t *testing.T) {
history, err := hub.FindRecordsByFilter("alerts_history", "alert_id={:alert_id}", "", 0, 0, map[string]any{"alert_id": pool.Id})
assert.NoError(t, err)
require.Len(t, history, 1, "expected one history entry per user")
assert.Equal(t, "ZFS Pool: tank", history[0].GetString("name"))
assert.Equal(t, "Storage Pool: tank", history[0].GetString("name"))
assert.Equal(t, system.Id, history[0].GetString("system"))
}
+150
View File
@@ -0,0 +1,150 @@
package alerts
import (
"context"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/netip"
"sync/atomic"
"syscall"
"time"
"github.com/nicholas-fedor/shoutrrr/pkg/router"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
)
var (
errInternalDestination = errors.New("Only admins can send to internal destinations")
errUnrestrictedService = errors.New("Only admins can use this notification service") // Restrict services w/o custom connection support
publicNotificationDialer = &net.Dialer{
Timeout: 10 * time.Second,
// Control checks each resolved address immediately before connecting.
Control: func(_, address string, _ syscall.RawConn) error { return checkNotificationAddress(address) },
}
publicNotificationClient = newPublicNotificationClient()
)
func newPublicNotificationClient() *http.Client {
return &http.Client{
Timeout: 15 * time.Second,
Transport: &http.Transport{
// Do not use proxies: they can resolve the target themselves and
// bypass the destination check on our socket.
DialContext: publicNotificationDialer.DialContext,
TLSHandshakeTimeout: 10 * time.Second,
IdleConnTimeout: 90 * time.Second,
},
}
}
func checkNotificationAddress(address string) error {
addr, err := netip.ParseAddrPort(address)
if err != nil || addr.Addr().Zone() != "" {
return errInternalDestination
}
ip := net.IP(addr.Addr().AsSlice())
if !ip.IsGlobalUnicast() || isInternalIP(ip) {
return errInternalDestination
}
return nil
}
func sendPublicNotification(rawURL, message string) error {
client := &notificationClient{Client: publicNotificationClient}
service, err := newPublicNotificationService(rawURL, types.SenderOptions{HTTPClient: client, DialContext: client.dialContext})
if err == nil {
if closer, ok := service.(io.Closer); ok {
defer closer.Close()
}
err = service.Send(message, &types.Params{})
}
// Some services format errors without preserving their error chain.
if client.blocked.Load() {
return errInternalDestination
}
return err
}
type notificationClient struct {
*http.Client
blocked atomic.Bool
}
func (c *notificationClient) Do(req *http.Request) (*http.Response, error) {
response, err := c.Client.Do(req)
if errors.Is(err, errInternalDestination) {
c.blocked.Store(true)
}
return response, err
}
func (c *notificationClient) dialContext(ctx context.Context, network, address string) (net.Conn, error) {
conn, err := publicNotificationDialer.DialContext(ctx, network, address)
if errors.Is(err, errInternalDestination) {
c.blocked.Store(true)
}
return conn, err
}
func newPublicNotificationService(rawURL string, opts types.SenderOptions) (types.Service, error) {
r := &router.ServiceRouter{}
scheme, serviceURL, err := r.ExtractServiceName(rawURL)
if err != nil {
return nil, err
}
service, err := r.NewService(scheme)
if err != nil {
return nil, err
}
httpSetter, httpOK := service.(types.HTTPClientSetter)
dialSetter, dialOK := service.(types.DialContextSetter)
if (!httpOK || opts.HTTPClient == nil) && (!dialOK || opts.DialContext == nil) {
return nil, errUnrestrictedService
}
if serviceURL.Scheme != scheme {
custom, ok := service.(types.CustomURLService)
if !ok {
return nil, fmt.Errorf("%w: %s", router.ErrCustomURLsNotSupported, scheme)
}
serviceURL, err = custom.GetServiceURLFromCustom(serviceURL)
if err != nil {
return nil, err
}
}
// Shoutrrr v0.20.0 CreateSenderWithOptions injects only AFTER Initialize.
// Matrix can log in during Initialize, so inject before it as well.
if httpOK {
httpSetter.SetHTTPClient(opts.HTTPClient)
}
if dialOK {
dialSetter.SetDialContext(opts.DialContext)
}
if err := service.Initialize(serviceURL, nil); err != nil {
return nil, err
}
// Some initializers replace their HTTP client with a default client.
if httpOK {
httpSetter.SetHTTPClient(opts.HTTPClient)
}
if dialOK {
dialSetter.SetDialContext(opts.DialContext)
}
return service, nil
}
var cgnatNetwork = &net.IPNet{
IP: net.IPv4(100, 64, 0, 0),
Mask: net.CIDRMask(10, 32),
}
func isInternalIP(ip net.IP) bool {
return ip.IsPrivate() ||
ip.IsLoopback() ||
ip.IsUnspecified() ||
ip.IsLinkLocalUnicast() ||
ip.IsMulticast() ||
cgnatNetwork.Contains(ip)
}
+217
View File
@@ -0,0 +1,217 @@
package alerts
import (
"context"
"encoding/binary"
"errors"
"io"
"net"
"net/http"
"net/http/httptest"
"strings"
"sync/atomic"
"testing"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
"golang.org/x/net/dns/dnsmessage"
)
func TestCheckNotificationAddress(t *testing.T) {
for _, host := range []string{"127.0.0.1", "10.0.0.1", "172.16.0.1", "192.168.0.1", "169.254.169.254", "100.64.0.0", "100.127.255.255", "0.0.0.0", "224.0.0.1", "255.255.255.255", "::1", "::", "fc00::1", "fe80::1", "ff02::1", "::ffff:127.0.0.1", "::ffff:169.254.169.254", "fe80::1%lo", "localhost", "consul"} {
t.Run(host, func(t *testing.T) {
if err := checkNotificationAddress(net.JoinHostPort(host, "80")); !errors.Is(err, errInternalDestination) {
t.Fatalf("expected blocked address, got %v", err)
}
})
}
for _, host := range []string{"8.8.8.8", "100.63.255.255", "100.128.0.0", "2001:4860:4860::8888"} {
if err := checkNotificationAddress(net.JoinHostPort(host, "443")); err != nil {
t.Errorf("public address %s: %v", host, err)
}
}
}
func TestPublicNotificationBlocksInternalRequests(t *testing.T) {
var hits atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hits.Add(1)
}))
defer server.Close()
host := strings.TrimPrefix(server.URL, "http://")
for _, rawURL := range []string{
"generic+http://" + host,
"generic+https://" + host,
"generic+http://localhost:" + strings.Split(host, ":")[1],
"matrix://user:password@" + host + "/room?disabletls=yes",
"mattermost://" + host + "/token?disabletls=yes",
} {
t.Run(rawURL, func(t *testing.T) {
if err := sendPublicNotification(rawURL, "test"); !errors.Is(err, errInternalDestination) {
t.Fatalf("expected internal destination error, got %v", err)
}
})
}
if hits.Load() != 0 {
t.Fatal("internal server received a request")
}
}
type notificationRoundTripper func(*http.Request) (*http.Response, error)
func (f notificationRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) }
func TestPublicNotificationRedirect(t *testing.T) {
client := newPublicNotificationClient()
defer client.CloseIdleConnections()
transport := client.Transport
client.Transport = notificationRoundTripper(func(r *http.Request) (*http.Response, error) {
if r.URL.Host == "public.example" {
return &http.Response{StatusCode: 307, Header: http.Header{"Location": {"http://127.0.0.1/"}}, Body: io.NopCloser(strings.NewReader("")), Request: r}, nil
}
return transport.RoundTrip(r)
})
_, err := client.Get("http://public.example/")
if !errors.Is(err, errInternalDestination) {
t.Fatalf("expected redirect to be blocked, got %v", err)
}
}
func TestPublicNotificationServiceClient(t *testing.T) {
for _, rawURL := range []string{"generic+http://public.example/path", "discord://token@123456789", "slack://hook:AAAAAAAAA-BBBBBBBBB-123456789123456789123456@webhook"} {
t.Run(rawURL, func(t *testing.T) {
var hits int
client := &http.Client{Transport: notificationRoundTripper(func(r *http.Request) (*http.Response, error) {
hits++
body := `{"ok":true}`
if strings.HasPrefix(rawURL, "slack:") {
body = "ok"
}
return &http.Response{StatusCode: 200, Header: make(http.Header), Body: io.NopCloser(strings.NewReader(body)), Request: r}, nil
})}
service, err := newPublicNotificationService(rawURL, types.SenderOptions{HTTPClient: client})
if err != nil {
t.Fatal(err)
}
if err := service.Send("test", &types.Params{}); err != nil {
t.Fatal(err)
}
if hits == 0 {
t.Fatal("injected client was not used")
}
})
}
}
func TestPublicNotificationDNS(t *testing.T) {
// Supply deterministic DNS responses over an in-memory TCP connection.
// The first lookup sees a public IP; subsequent lookups see loopback.
var rebound atomic.Bool
resolver := &net.Resolver{PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
client, server := net.Pipe()
go func() {
defer server.Close()
var size [2]byte
if _, err := io.ReadFull(server, size[:]); err != nil {
return
}
buf := make([]byte, binary.BigEndian.Uint16(size[:]))
if _, err := io.ReadFull(server, buf); err != nil {
return
}
var msg dnsmessage.Message
if err := msg.Unpack(buf); err != nil {
return
}
msg.Header.Response = true
msg.Header.RecursionAvailable = true
q := msg.Questions[0]
if q.Type == dnsmessage.TypeA {
ip := [4]byte{8, 8, 8, 8}
if rebound.Load() {
ip = [4]byte{127, 0, 0, 1}
}
msg.Answers = []dnsmessage.Resource{{Header: dnsmessage.ResourceHeader{Name: q.Name, Type: q.Type, Class: dnsmessage.ClassINET}, Body: &dnsmessage.AResource{A: ip}}}
}
buf, err := msg.Pack()
if err != nil {
return
}
binary.BigEndian.PutUint16(size[:], uint16(len(buf)))
server.Write(append(size[:], buf...))
}()
return client, nil
}}
// These tests do not run in parallel; restore the process resolver afterward.
previous := net.DefaultResolver
net.DefaultResolver = resolver
t.Cleanup(func() { net.DefaultResolver = previous })
ips, err := resolver.LookupIP(context.Background(), "ip4", "rebind.example")
if err != nil || len(ips) != 1 || !ips[0].Equal(net.IPv4(8, 8, 8, 8)) {
t.Fatalf("initial DNS lookup: %v, %v", ips, err)
}
rebound.Store(true)
client := newPublicNotificationClient()
defer client.CloseIdleConnections()
for _, host := range []string{"rebind.example", "consul"} {
guarded := &notificationClient{Client: client}
conn, dialErr := guarded.dialContext(context.Background(), "tcp", net.JoinHostPort(host, "25"))
if conn != nil {
conn.Close()
}
if !errors.Is(dialErr, errInternalDestination) || !guarded.blocked.Load() {
t.Errorf("expected TCP dial-time rejection for %s, got %v", host, dialErr)
}
_, err := client.Get("http://" + host + "/")
if !errors.Is(err, errInternalDestination) {
t.Errorf("expected dial-time rejection for %s, got %v", host, err)
}
}
}
func TestPublicNotificationTCP(t *testing.T) {
for _, rawURL := range []string{
"smtp://user:pass@HOST:25/?fromAddress=sender@example.com&toAddresses=recipient@example.com",
"smtp://user:pass@HOST:465/?fromAddress=sender@example.com&toAddresses=recipient@example.com",
"mqtt://HOST:1883/topic",
"mqtts://HOST:8883/topic",
} {
t.Run(rawURL, func(t *testing.T) {
t.Parallel()
t.Run("internal destination", func(t *testing.T) {
err := sendPublicNotification(strings.ReplaceAll(rawURL, "HOST", "127.0.0.1"), "test")
if !errors.Is(err, errInternalDestination) {
t.Fatalf("expected blocked destination, got %v", err)
}
})
t.Run("public destination uses injected dialer", func(t *testing.T) {
var calls atomic.Int32
stopped := errors.New("test dial stopped")
service, err := newPublicNotificationService(strings.ReplaceAll(rawURL, "HOST", "8.8.8.8"), types.SenderOptions{
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
calls.Add(1)
if network != "tcp" || !strings.HasPrefix(address, "8.8.8.8:") {
t.Errorf("unexpected dial: %s %s", network, address)
}
if err := checkNotificationAddress(address); err != nil {
t.Error(err)
}
return nil, stopped
},
})
if err != nil {
t.Fatal(err)
}
if closer, ok := service.(io.Closer); ok {
defer closer.Close()
}
if err := service.Send("test", &types.Params{}); err == nil {
t.Fatal("expected dial failure")
}
if calls.Load() == 0 {
t.Fatal("custom dialer was not used")
}
})
})
}
}
+4 -1
View File
@@ -8,6 +8,8 @@ RUN go mod download
# Copy source files
COPY . ./
RUN apk add --no-cache ca-certificates && update-ca-certificates
# Build
ARG TARGETOS TARGETARCH
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-w -s" -o /agent ./internal/cmd/agent
@@ -19,6 +21,7 @@ RUN rm -rf /tmp/*
# --------------------------
FROM scratch
COPY --from=builder /agent /agent
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# this is so we don't need to create the /tmp directory in the scratch container
COPY --from=builder /tmp /tmp
@@ -29,4 +32,4 @@ COPY --from=builder /app/agent/test-data/amdgpu.ids /usr/share/libdrm/amdgpu.ids
# Ensure data persistence across container recreations
VOLUME ["/var/lib/beszel-agent"]
ENTRYPOINT ["/agent"]
ENTRYPOINT ["/agent"]
+2 -2
View File
@@ -20,9 +20,9 @@ FROM alpine:3.23
COPY --from=builder /agent /agent
RUN apk add --no-cache -X https://dl-cdn.alpinelinux.org/alpine/edge/testing igt-gpu-tools nvtop smartmontools
RUN apk add --no-cache -X https://dl-cdn.alpinelinux.org/alpine/edge/testing igt-gpu-tools nvtop smartmontools zfs
# Ensure data persistence across container recreations
VOLUME ["/var/lib/beszel-agent"]
ENTRYPOINT ["/agent"]
ENTRYPOINT ["/agent"]
+5
View File
@@ -43,6 +43,11 @@ COPY --from=builder /app/agent/test-data/amdgpu.ids /usr/share/libdrm/amdgpu.ids
# Copy smartmontools binaries and config files
COPY --from=smartmontools-builder /usr/sbin/smartctl /usr/sbin/smartctl
# Install ZFS userspace utilities (zpool, zfs) for pool/dataset monitoring
RUN apt-get update && apt-get install -y --no-install-recommends \
zfsutils-linux \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Ensure data persistence across container recreations
VOLUME ["/var/lib/beszel-agent"]
+29
View File
@@ -65,6 +65,32 @@ RUN set -eux; \
cp -v "$interp" "/out/rootfs$interp"; \
fi
# --------------------------
# ZFS utilities builder stage
# --------------------------
FROM --platform=$TARGETPLATFORM debian:bookworm-slim AS zfsutils-builder
RUN apt-get update && apt-get install -y --no-install-recommends \
zfsutils-linux \
&& rm -rf /var/lib/apt/lists/*
# Copy the zpool/zfs binaries and their required runtime libraries
RUN set -eux; \
mkdir -p /out/rootfs/lib /out/rootfs/lib64 /out/rootfs/usr/lib; \
for bin in /usr/sbin/zpool /usr/sbin/zfs; do \
mkdir -p "/out/rootfs$(dirname "$bin")"; \
cp -v "$bin" "/out/rootfs$bin"; \
ldd "$bin" \
| awk '{print $3}' \
| grep '^/' \
| xargs -r -I '{}' sh -c 'mkdir -p "/out/rootfs$(dirname "{}")"; cp -v "{}" "/out/rootfs{}"'; \
interp="$(ldd "$bin" | awk "/ld-linux/ {print \$1}")"; \
if [ -n "$interp" ] && [ -e "$interp" ]; then \
mkdir -p "/out/rootfs$(dirname "$interp")"; \
cp -v "$interp" "/out/rootfs$interp"; \
fi; \
done
# --------------------------
# Final image: lightweight multi-arch NVIDIA agent (slim)
# --------------------------
@@ -78,6 +104,9 @@ COPY --from=builder /app/agent/test-data/amdgpu.ids /usr/share/libdrm/amdgpu.ids
COPY --from=smartmontools-builder /usr/sbin/smartctl /usr/sbin/smartctl
COPY --from=smartmontools-builder /out/rootfs/ /
# Copy ZFS utilities (zpool, zfs) binaries and required runtime libraries
COPY --from=zfsutils-builder /out/rootfs/ /
# nvidia-smi is intentionally not bundled.
# Mount the host binary instead, for example:
# - /usr/bin/nvidia-smi:/usr/bin/nvidia-smi:ro
+9 -5
View File
@@ -59,11 +59,15 @@ type Stats struct {
// ZfsPool holds per-pool ZFS metrics for a single collection interval.
type ZfsPool struct {
Total float64 `json:"d" cbor:"0,keyasint"` // total capacity in GiB
Used float64 `json:"du" cbor:"1,keyasint"` // allocated in GiB
ReadBytes uint64 `json:"rb,omitzero" cbor:"2,keyasint,omitzero"` // read throughput in bytes/s
WriteBytes uint64 `json:"wb,omitzero" cbor:"3,keyasint,omitzero"` // write throughput in bytes/s
Health string `json:"h,omitempty" cbor:"4,keyasint,omitempty"` // ONLINE, DEGRADED, FAULTED, ...
DisplayName string `json:"n,omitempty" cbor:"8,keyasint,omitempty"`
HideUsage bool `json:"hu,omitempty" cbor:"6,keyasint,omitempty"` // equivalent filesystem usage chart exists
HideIO bool `json:"hi,omitempty" cbor:"7,keyasint,omitempty"` // equivalent filesystem I/O chart exists
Raw bool `json:"raw,omitempty" cbor:"5,keyasint,omitempty"`
Total float64 `json:"d" cbor:"0,keyasint"` // total capacity in GiB
Used float64 `json:"du" cbor:"1,keyasint"` // allocated in GiB
ReadBytes uint64 `json:"rb,omitzero" cbor:"2,keyasint,omitzero"` // read throughput in bytes/s
WriteBytes uint64 `json:"wb,omitzero" cbor:"3,keyasint,omitzero"` // write throughput in bytes/s
Health string `json:"h,omitempty" cbor:"4,keyasint,omitempty"` // ONLINE, DEGRADED, FAULTED, ...
}
// Uint8Slice wraps []uint8 to customize JSON encoding while keeping CBOR efficient.
+32 -8
View File
@@ -1,23 +1,47 @@
// Package zfs defines the ZFS detail data exchanged between agent and hub.
package zfs
import "strings"
// ZfsData is the detail payload returned by the agent for the GetZfsData action.
type ZfsData struct {
Pools []*PoolDetail `json:"pools,omitempty"`
Complete bool `json:"complete,omitempty"`
// Backends whose inventories are complete, even when another backend failed.
CompleteBackends []string `json:"completeBackends,omitempty"`
}
// CanRefreshPool also governs deletion: missing pools may only be removed
// after a successful inventory of their backend. Complete supports old agents.
func (data *ZfsData) CanRefreshPool(name string) bool {
if data.Complete {
return true
}
backend := "zfs"
if strings.HasPrefix(name, "b:") {
backend = "btrfs"
}
for _, complete := range data.CompleteBackends {
if complete == backend {
return true
}
}
return false
}
// PoolDetail holds the verbose state of a single pool: capacity, health,
// scrub, vdev, and dataset information.
type PoolDetail struct {
Name string `json:"name"`
Health string `json:"health,omitempty"`
Size uint64 `json:"size,omitempty"` // bytes
Alloc uint64 `json:"alloc,omitempty"` // bytes
Free uint64 `json:"free,omitempty"` // bytes
Scrub *Scrub `json:"scrub,omitempty"`
Vdevs []*Vdev `json:"vdevs,omitempty"`
Datasets []*Dataset `json:"datasets,omitempty"`
DisplayName string `json:"displayName,omitempty"`
Raw bool `json:"raw,omitempty"`
Name string `json:"name"`
Health string `json:"health,omitempty"`
Size uint64 `json:"size,omitempty"` // bytes
Alloc uint64 `json:"alloc,omitempty"` // bytes
Free uint64 `json:"free,omitempty"` // bytes
Scrub *Scrub `json:"scrub,omitempty"`
Vdevs []*Vdev `json:"vdevs,omitempty"`
Datasets []*Dataset `json:"datasets,omitempty"`
}
// Scrub holds the scrub (or resilver) status of a pool.
+2 -2
View File
@@ -99,8 +99,8 @@ func setCollectionAuthSettings(app core.App) error {
}
if err := applyCollectionRules(app, []string{"fingerprints"}, collectionRules{
list: &systemScopedReadRule,
view: &systemScopedReadRule,
list: &systemScopedWriteRule,
view: &systemScopedWriteRule,
create: &systemScopedWriteRule,
update: &systemScopedWriteRule,
delete: &systemScopedWriteRule,
+4 -4
View File
@@ -88,8 +88,8 @@ func TestCollectionRulesDefault(t *testing.T) {
// fingerprints collection
fingerprintsCollection, err := hub.FindCollectionByNameOrId("fingerprints")
require.NoError(t, err, "Failed to find fingerprints collection")
assert.Equal(t, isUserInSystemUsers, *fingerprintsCollection.ListRule)
assert.Equal(t, isUserInSystemUsers, *fingerprintsCollection.ViewRule)
assert.Equal(t, isUserInSystemUsersNotReadonly, *fingerprintsCollection.ListRule)
assert.Equal(t, isUserInSystemUsersNotReadonly, *fingerprintsCollection.ViewRule)
assert.Equal(t, isUserInSystemUsersNotReadonly, *fingerprintsCollection.CreateRule)
assert.Equal(t, isUserInSystemUsersNotReadonly, *fingerprintsCollection.UpdateRule)
assert.Equal(t, isUserInSystemUsersNotReadonly, *fingerprintsCollection.DeleteRule)
@@ -216,8 +216,8 @@ func TestCollectionRulesShareAllSystems(t *testing.T) {
// fingerprints collection
fingerprintsCollection, err := hub.FindCollectionByNameOrId("fingerprints")
require.NoError(t, err, "Failed to find fingerprints collection")
assert.Equal(t, isUser, *fingerprintsCollection.ListRule)
assert.Equal(t, isUser, *fingerprintsCollection.ViewRule)
assert.Equal(t, isUserNotReadonly, *fingerprintsCollection.ListRule)
assert.Equal(t, isUserNotReadonly, *fingerprintsCollection.ViewRule)
assert.Equal(t, isUserNotReadonly, *fingerprintsCollection.CreateRule)
assert.Equal(t, isUserNotReadonly, *fingerprintsCollection.UpdateRule)
assert.Equal(t, isUserNotReadonly, *fingerprintsCollection.DeleteRule)
+14 -1
View File
@@ -272,7 +272,15 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
systemRecord.Set("status", up)
systemRecord.Set("info", data.Info)
// Distinguish an idle GPU from a system without GPU data (#2312)
info := struct {
system.Info
GpuPct *float64 `json:"g,omitempty"`
}{Info: data.Info}
if len(data.Stats.GPUData) > 0 {
info.GpuPct = &data.Info.GpuPct
}
systemRecord.Set("info", info)
if err := txApp.SaveNoValidate(systemRecord); err != nil {
return err
}
@@ -322,6 +330,11 @@ func createSystemdStatsRecords(app core.App, data []*systemd.Service, systemId s
valueStrings := make([]string, 0, len(data))
for i, service := range data {
// Agent payloads can contain null entries. Reject the snapshot before
// executing any queries so existing service records remain intact.
if service == nil {
return fmt.Errorf("null systemd service at index %d", i)
}
suffix := fmt.Sprintf("%d", i)
valueStrings = append(valueStrings, fmt.Sprintf("({:id%[1]s}, {:system}, {:name%[1]s}, {:state%[1]s}, {:sub%[1]s}, {:cpu%[1]s}, {:cpuPeak%[1]s}, {:memory%[1]s}, {:memPeak%[1]s}, {:updated})", suffix))
params["id"+suffix] = makeStableHashId(systemId, service.Name)
+44
View File
@@ -0,0 +1,44 @@
//go:build testing
package systems
import (
"testing"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCreateRecordsGPUUtilization(t *testing.T) {
sys, app := newTestSystemWithHub(t)
for _, tc := range []struct {
name string
gpu bool
usage float64
}{
{"no GPU", false, 0},
{"active GPU", true, 42.5},
{"idle GPU", true, 0},
{"GPU removed", false, 0},
} {
t.Run(tc.name, func(t *testing.T) {
data := &system.CombinedData{Info: system.Info{GpuPct: tc.usage, Cpu: 12.5}}
if tc.gpu {
data.Stats.GPUData = map[string]system.GPUData{"0": {Name: "GPU", Usage: tc.usage}}
}
_, err := sys.createRecords(data)
require.NoError(t, err)
record, err := app.FindRecordById("systems", sys.Id)
require.NoError(t, err)
var info map[string]any
require.NoError(t, record.UnmarshalJSONField("info", &info))
assert.Equal(t, 12.5, info["cpu"])
if tc.gpu {
assert.Equal(t, tc.usage, info["g"])
} else {
assert.NotContains(t, info, "g")
}
})
}
}
+18 -11
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"sync"
"time"
"github.com/henrygd/beszel/internal/hub/ws"
@@ -42,13 +43,17 @@ var errSystemExists = errors.New("system exists")
// SystemManager manages a collection of monitored systems and their connections.
// It handles system lifecycle, status updates, and maintains both SSH and WebSocket connections.
type SystemManager struct {
hub hubLike // Hub interface for database and alert operations
systems *store.Store[string, *System] // Thread-safe store of active systems
sshConfig *ssh.ClientConfig // SSH client configuration for system connections
smartFetchMap *expirymap.ExpiryMap[smartFetchState] // Stores last SMART fetch time/result; TTL is only for cleanup
zfsFetchMap *expirymap.ExpiryMap[zfsFetchState] // Stores last ZFS fetch time/result; TTL is only for cleanup
ctx context.Context // Cancelled when the app terminates
cancel context.CancelFunc // Cancels ctx and all child system contexts
hub hubLike // Hub interface for database and alert operations
systems *store.Store[string, *System] // Thread-safe store of active systems
sshConfig *ssh.ClientConfig // SSH client configuration for system connections
smartFetchMap *expirymap.ExpiryMap[smartFetchState] // Stores last SMART fetch time/result; TTL is only for cleanup
zfsFetchMap *expirymap.ExpiryMap[zfsFetchState] // Stores last ZFS fetch time/result; TTL is only for cleanup
realtimeMutex sync.Mutex // Protects all realtime worker and subscription state
activeSubscriptions map[string]*subscriptionInfo // Realtime subscriptions keyed by system ID
realtimeWorkerStop chan struct{} // Stops the current realtime worker generation
realtimeWorkerRun bool // Whether a realtime worker has been started
ctx context.Context // Cancelled when the app terminates
cancel context.CancelFunc // Cancels ctx and all child system contexts
}
// hubLike defines the interface requirements for the hub dependency.
@@ -67,10 +72,11 @@ type hubLike interface {
// The hub must implement the hubLike interface to provide database and alert functionality.
func NewSystemManager(hub hubLike) *SystemManager {
sm := &SystemManager{
systems: store.New(map[string]*System{}),
hub: hub,
smartFetchMap: expirymap.New[smartFetchState](time.Hour),
zfsFetchMap: expirymap.New[zfsFetchState](time.Hour),
systems: store.New(map[string]*System{}),
hub: hub,
smartFetchMap: expirymap.New[smartFetchState](time.Hour),
zfsFetchMap: expirymap.New[zfsFetchState](time.Hour),
activeSubscriptions: make(map[string]*subscriptionInfo),
}
sm.ctx, sm.cancel = context.WithCancel(context.Background())
return sm
@@ -138,6 +144,7 @@ func (sm *SystemManager) bindEventHooks() {
// onTerminate cancels SystemManager context on app shutdown
func (sm *SystemManager) onTerminate(e *core.TerminateEvent) error {
sm.cancel()
sm.stopRealtimeWorker()
return e.Next()
}
+135 -64
View File
@@ -3,25 +3,27 @@ package systems
import (
"encoding/json"
"strings"
"sync"
"time"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/hub/utils"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/subscriptions"
)
type subscriptionInfo struct {
subscription string
connectedClients uint8
connectedClients int
fetching bool
}
var (
activeSubscriptions = make(map[string]*subscriptionInfo)
workerRunning bool
tickerStopChan chan struct{}
realtimeMutex sync.Mutex
)
type realtimeFetch struct {
systemID string
subscription string
info *subscriptionInfo
}
// onRealtimeConnectRequest handles client connection events for realtime subscriptions.
// It cleans up existing subscriptions when a client connects.
@@ -38,6 +40,19 @@ func (sm *SystemManager) onRealtimeConnectRequest(e *core.RealtimeConnectRequest
// onRealtimeSubscribeRequest handles client subscription events for realtime metrics.
// It tracks new subscriptions and unsubscriptions to manage the realtime worker lifecycle.
func (sm *SystemManager) onRealtimeSubscribeRequest(e *core.RealtimeSubscribeRequestEvent) error {
// Parse with PocketBase's own subscription parser before changing the real
// client. Reject the entire request if any metrics target is inaccessible.
requested := subscriptions.NewDefaultClient()
requested.Subscribe(e.Subscriptions...)
for topic, options := range requested.Subscriptions() {
if !strings.HasPrefix(topic, "rt_metrics") {
continue
}
system, err := sm.GetSystem(options.Query["system"])
if err != nil || !system.HasUser(e.App, e.Auth) {
return e.NotFoundError("", nil)
}
}
oldSubs := e.Client.Subscriptions()
// after e.Next() is the result of the subscribe request
err := e.Next()
@@ -47,14 +62,7 @@ func (sm *SystemManager) onRealtimeSubscribeRequest(e *core.RealtimeSubscribeReq
for k, options := range newSubs {
if _, ok := oldSubs[k]; !ok {
if strings.HasPrefix(k, "rt_metrics") {
systemId := options.Query["system"]
if _, ok := activeSubscriptions[systemId]; !ok {
activeSubscriptions[systemId] = &subscriptionInfo{
subscription: k,
}
}
activeSubscriptions[systemId].connectedClients += 1
sm.onRealtimeSubscriptionAdded()
sm.addRealtimeSubscription(options.Query["system"], k)
}
}
}
@@ -68,72 +76,76 @@ func (sm *SystemManager) onRealtimeSubscribeRequest(e *core.RealtimeSubscribeReq
return err
}
// onRealtimeSubscriptionAdded initializes or starts the realtime worker when the first subscription is added.
// It ensures only one worker runs at a time.
func (sm *SystemManager) onRealtimeSubscriptionAdded() {
realtimeMutex.Lock()
defer realtimeMutex.Unlock()
// addRealtimeSubscription tracks a subscriber and starts a worker if necessary.
func (sm *SystemManager) addRealtimeSubscription(systemID, subscription string) {
sm.realtimeMutex.Lock()
defer sm.realtimeMutex.Unlock()
// Start the worker if it's not already running
if !workerRunning {
workerRunning = true
// Create a new stop channel for this worker instance
tickerStopChan = make(chan struct{})
go sm.startRealtimeWorker()
if sm.activeSubscriptions == nil {
sm.activeSubscriptions = make(map[string]*subscriptionInfo)
}
info, ok := sm.activeSubscriptions[systemID]
if !ok {
info = &subscriptionInfo{subscription: subscription}
sm.activeSubscriptions[systemID] = info
}
info.connectedClients++
if !sm.realtimeWorkerRun {
sm.realtimeWorkerRun = true
stop := make(chan struct{})
sm.realtimeWorkerStop = stop
go sm.startRealtimeWorker(stop)
}
}
// checkSubscriptions stops the realtime worker when there are no active subscriptions.
// This prevents unnecessary resource usage when no clients are listening for realtime data.
func (sm *SystemManager) checkSubscriptions() {
if !workerRunning || len(activeSubscriptions) > 0 {
// stopRealtimeWorker stops the current worker generation, if any.
func (sm *SystemManager) stopRealtimeWorker() {
sm.realtimeMutex.Lock()
defer sm.realtimeMutex.Unlock()
sm.stopRealtimeWorkerLocked()
}
func (sm *SystemManager) stopRealtimeWorkerLocked() {
if !sm.realtimeWorkerRun {
return
}
realtimeMutex.Lock()
defer realtimeMutex.Unlock()
// Signal the worker to stop
if tickerStopChan != nil {
select {
case tickerStopChan <- struct{}{}:
default:
}
}
// Mark worker as stopped (will be reset when next subscription comes in)
workerRunning = false
close(sm.realtimeWorkerStop)
sm.realtimeWorkerStop = nil
sm.realtimeWorkerRun = false
}
// removeRealtimeSubscription removes a realtime subscription and checks if the worker should be stopped.
// It only processes subscriptions with the "rt_metrics" prefix and triggers cleanup when subscriptions are removed.
func (sm *SystemManager) removeRealtimeSubscription(subscription string, options subscriptions.SubscriptionOptions) {
if strings.HasPrefix(subscription, "rt_metrics") {
systemId := options.Query["system"]
if info, ok := activeSubscriptions[systemId]; ok {
info.connectedClients -= 1
systemID := options.Query["system"]
sm.realtimeMutex.Lock()
if info, ok := sm.activeSubscriptions[systemID]; ok {
info.connectedClients--
if info.connectedClients <= 0 {
delete(activeSubscriptions, systemId)
delete(sm.activeSubscriptions, systemID)
}
}
sm.checkSubscriptions()
if len(sm.activeSubscriptions) == 0 {
sm.stopRealtimeWorkerLocked()
}
sm.realtimeMutex.Unlock()
}
}
// startRealtimeWorker runs the main loop for fetching realtime data from agents.
// It continuously fetches system data and broadcasts it to subscribed clients via WebSocket.
func (sm *SystemManager) startRealtimeWorker() {
func (sm *SystemManager) startRealtimeWorker(stop <-chan struct{}) {
sm.fetchRealtimeDataAndNotify()
tick := time.Tick(1 * time.Second)
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-tickerStopChan:
case <-stop:
return
case <-tick:
if len(activeSubscriptions) == 0 {
return
}
case <-ticker.C:
sm.fetchRealtimeDataAndNotify()
}
}
@@ -141,27 +153,79 @@ func (sm *SystemManager) startRealtimeWorker() {
// fetchRealtimeDataAndNotify fetches realtime data for all active subscriptions and notifies the clients.
func (sm *SystemManager) fetchRealtimeDataAndNotify() {
for systemId, info := range activeSubscriptions {
system, err := sm.GetSystem(systemId)
for _, fetch := range sm.claimRealtimeFetches() {
system, err := sm.GetSystem(fetch.systemID)
if err != nil {
sm.finishRealtimeFetch(fetch)
continue
}
go func() {
go func(fetch realtimeFetch) {
defer sm.finishRealtimeFetch(fetch)
data, err := system.fetchDataFromAgent(common.DataRequestOptions{CacheTimeMs: 1000})
if err != nil {
return
}
bytes, err := json.Marshal(data)
if err == nil {
notify(sm.hub, info.subscription, bytes)
notify(sm.hub, system, fetch.subscription, bytes)
}
}()
}(fetch)
}
}
// claimRealtimeFetches takes a stable snapshot and marks each selected system as
// in flight. Slow agents are skipped on later ticks until their fetch completes.
func (sm *SystemManager) claimRealtimeFetches() []realtimeFetch {
sm.realtimeMutex.Lock()
defer sm.realtimeMutex.Unlock()
fetches := make([]realtimeFetch, 0, len(sm.activeSubscriptions))
for systemID, info := range sm.activeSubscriptions {
if info.fetching {
continue
}
info.fetching = true
fetches = append(fetches, realtimeFetch{
systemID: systemID,
subscription: info.subscription,
info: info,
})
}
return fetches
}
func (sm *SystemManager) finishRealtimeFetch(fetch realtimeFetch) {
sm.realtimeMutex.Lock()
defer sm.realtimeMutex.Unlock()
// A subscription may have been removed and recreated while the old request
// was running. Only release the exact entry claimed by this request.
if info := sm.activeSubscriptions[fetch.systemID]; info == fetch.info {
info.fetching = false
}
}
// notify broadcasts realtime data to all clients subscribed to a specific subscription.
// It iterates through all connected clients and sends the data only to those with matching subscriptions.
func notify(app core.App, subscription string, data []byte) error {
// Custom topics bypass collection rules, so check current access for every
// recipient, including clients whose authentication or membership was revoked.
func notify(app core.App, system *System, subscription string, data []byte) error {
shareAll, _ := utils.GetEnv("SHARE_ALL_SYSTEMS")
members := make(map[string]struct{})
if shareAll != "true" {
// Refresh once per broadcast so membership changes take effect on the
// next update without querying the database for every recipient.
var recordData struct{ Users string }
if err := app.DB().NewQuery("SELECT users FROM systems WHERE id={:id}").
Bind(dbx.Params{"id": system.Id}).One(&recordData); err != nil {
return err
}
var userIDs []string
if err := json.Unmarshal([]byte(recordData.Users), &userIDs); err != nil {
return err
}
for _, id := range userIDs {
members[id] = struct{}{}
}
}
message := subscriptions.Message{
Name: subscription,
Data: data,
@@ -170,6 +234,13 @@ func notify(app core.App, subscription string, data []byte) error {
if !client.HasSubscription(subscription) {
continue
}
auth, _ := client.Get(apis.RealtimeClientAuthKey).(*core.Record)
if auth == nil {
continue
}
if _, member := members[auth.Id]; shareAll != "true" && !member {
continue
}
client.Send(message)
}
return nil
@@ -0,0 +1,229 @@
package systems
import (
"testing"
"time"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
pbtests "github.com/pocketbase/pocketbase/tests"
"github.com/pocketbase/pocketbase/tools/hook"
"github.com/pocketbase/pocketbase/tools/store"
"github.com/pocketbase/pocketbase/tools/subscriptions"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRealtimeAuthorization(t *testing.T) {
t.Setenv("SHARE_ALL_SYSTEMS", "false")
t.Setenv("BESZEL_HUB_SHARE_ALL_SYSTEMS", "")
app, err := pbtests.NewTestApp(t.TempDir())
require.NoError(t, err)
t.Cleanup(app.Cleanup)
_, err = app.DB().NewQuery(`CREATE TABLE IF NOT EXISTS systems (id TEXT PRIMARY KEY, users TEXT)`).Execute()
require.NoError(t, err)
_, err = app.DB().NewQuery(`INSERT INTO systems (id, users) VALUES ('target', '["member"]')`).Execute()
require.NoError(t, err)
member := core.NewRecord(core.NewAuthCollection("users"))
member.Id = "member"
outsider := core.NewRecord(member.Collection())
outsider.Id = "outsider"
system := &System{Id: "target"}
sm := newRealtimeTestManager()
sm.systems.Set(system.Id, system)
// Keep the lifecycle bookkeeping active without starting an agent worker.
sm.realtimeWorkerRun = true
sm.realtimeWorkerStop = make(chan struct{})
t.Cleanup(sm.stopRealtimeWorker)
topic := `rt_metrics?options={"query":{"system":"target"}}`
for _, tc := range []struct {
name string
auth *core.Record
topic string
share bool
allowed bool
}{
{"guest", nil, topic, false, false},
{"outsider", outsider, topic, false, false},
{"member", member, topic, false, true},
{"missing system", member, `rt_metrics`, false, false},
{"unknown system", member, `rt_metrics?options={"query":{"system":"missing"}}`, false, false},
{"malformed options", member, `rt_metrics?options=invalid`, false, false},
{"prefix variant", outsider, `rt_metrics_extra?options={"query":{"system":"target"}}`, false, false},
{"shared outsider", outsider, topic, true, true},
{"shared guest", nil, topic, true, false},
{"other topic", nil, "systems/*", false, true},
} {
t.Run(tc.name, func(t *testing.T) {
if tc.share {
t.Setenv("BESZEL_HUB_SHARE_ALL_SYSTEMS", "true")
}
client := subscriptions.NewDefaultClient()
client.Subscribe("existing")
e := &core.RealtimeSubscribeRequestEvent{
RequestEvent: &core.RequestEvent{App: app, Auth: tc.auth},
Client: client, Subscriptions: []string{tc.topic},
}
called := false
h := &hook.Hook[*core.RealtimeSubscribeRequestEvent]{}
h.BindFunc(sm.onRealtimeSubscribeRequest)
err := h.Trigger(e, func(e *core.RealtimeSubscribeRequestEvent) error {
called = true
client.Unsubscribe()
client.Subscribe(e.Subscriptions...)
return nil
})
if tc.allowed {
require.NoError(t, err)
assert.True(t, called)
} else {
require.Error(t, err)
assert.False(t, called)
assert.True(t, client.HasSubscription("existing"))
assert.False(t, client.HasSubscription(tc.topic))
}
})
}
t.Run("broadcast checks current access", func(t *testing.T) {
client := subscriptions.NewDefaultClient()
client.Subscribe(topic)
app.SubscriptionsBroker().Register(client)
defer app.SubscriptionsBroker().Unregister(client.Id())
secondClient := subscriptions.NewDefaultClient()
secondClient.Subscribe(topic)
app.SubscriptionsBroker().Register(secondClient)
defer app.SubscriptionsBroker().Unregister(secondClient.Id())
check := func(auth *core.Record, allowed bool) {
t.Helper()
client.Set(apis.RealtimeClientAuthKey, auth)
secondClient.Set(apis.RealtimeClientAuthKey, auth)
done := make(chan struct{})
go func() {
notify(app, system, topic, []byte(`{"cpu":42}`))
close(done)
}()
// Even on failure, drain pending sends and join the broadcaster before
// unregistering clients, which closes their channels.
defer func() {
for {
select {
case <-client.Channel():
case <-secondClient.Channel():
case <-done:
return
}
}
}()
var received [2]int
timer := time.NewTimer(time.Second)
defer timer.Stop()
for {
select {
case msg := <-client.Channel():
received[0]++
assert.Equal(t, topic, msg.Name)
case msg := <-secondClient.Channel():
received[1]++
assert.Equal(t, topic, msg.Name)
case <-done:
want := [2]int{}
if allowed {
want = [2]int{1, 1}
}
assert.Equal(t, want, received)
return
case <-timer.C:
t.Fatal("broadcast did not finish")
}
}
}
check(nil, false)
check(outsider, false)
check(member, true)
_, err := app.DB().NewQuery(`UPDATE systems SET users = '[]'`).Execute()
require.NoError(t, err)
check(member, false)
t.Setenv("BESZEL_HUB_SHARE_ALL_SYSTEMS", "true")
check(outsider, true)
check(nil, false)
})
}
func newRealtimeTestManager() *SystemManager {
return &SystemManager{
systems: store.New(map[string]*System{}),
activeSubscriptions: make(map[string]*subscriptionInfo),
}
}
func TestRealtimeFetchesDoNotOverlapPerSystem(t *testing.T) {
sm := newRealtimeTestManager()
sm.activeSubscriptions["one"] = &subscriptionInfo{subscription: "rt_metrics_one"}
sm.activeSubscriptions["two"] = &subscriptionInfo{subscription: "rt_metrics_two"}
first := sm.claimRealtimeFetches()
require.Len(t, first, 2)
assert.Empty(t, sm.claimRealtimeFetches())
sm.finishRealtimeFetch(first[0])
next := sm.claimRealtimeFetches()
require.Len(t, next, 1)
assert.Equal(t, first[0].systemID, next[0].systemID)
sm.finishRealtimeFetch(first[1])
sm.finishRealtimeFetch(next[0])
}
func TestFinishingOldRealtimeFetchDoesNotReleaseReplacement(t *testing.T) {
sm := newRealtimeTestManager()
oldInfo := &subscriptionInfo{subscription: "old"}
sm.activeSubscriptions["system"] = oldInfo
fetch := sm.claimRealtimeFetches()[0]
newInfo := &subscriptionInfo{subscription: "new", fetching: true}
sm.activeSubscriptions["system"] = newInfo
sm.finishRealtimeFetch(fetch)
assert.True(t, newInfo.fetching)
}
func TestRealtimeSubscriptionLifecycle(t *testing.T) {
sm := newRealtimeTestManager()
options := subscriptions.SubscriptionOptions{Query: map[string]string{"system": "system"}}
sm.addRealtimeSubscription("system", "rt_metrics")
sm.addRealtimeSubscription("system", "rt_metrics")
sm.realtimeMutex.Lock()
firstStop := sm.realtimeWorkerStop
assert.True(t, sm.realtimeWorkerRun)
assert.Equal(t, 2, sm.activeSubscriptions["system"].connectedClients)
sm.realtimeMutex.Unlock()
sm.removeRealtimeSubscription("rt_metrics", options)
sm.realtimeMutex.Lock()
assert.True(t, sm.realtimeWorkerRun)
assert.Equal(t, 1, sm.activeSubscriptions["system"].connectedClients)
sm.realtimeMutex.Unlock()
sm.removeRealtimeSubscription("rt_metrics", options)
sm.realtimeMutex.Lock()
assert.False(t, sm.realtimeWorkerRun)
assert.Empty(t, sm.activeSubscriptions)
sm.realtimeMutex.Unlock()
select {
case <-firstStop:
default:
t.Fatal("worker stop channel was not closed")
}
// A later subscription must get a new stop channel owned by its worker.
sm.addRealtimeSubscription("system", "rt_metrics")
sm.realtimeMutex.Lock()
secondStop := sm.realtimeWorkerStop
assert.NotEqual(t, firstStop, secondStop)
sm.realtimeMutex.Unlock()
sm.stopRealtimeWorker()
}
+27 -11
View File
@@ -32,13 +32,12 @@ func (sys *System) FetchAndSaveZfsPools(force bool) error {
sys.recordZfsFetchResult(err, 0)
return err
}
if zfsData == nil || !zfsData.Complete {
err = errIncompleteZfsData
sys.recordZfsFetchResult(err, 0)
return err
}
err = sys.saveZfsPools(zfsData)
sys.recordZfsFetchResult(err, len(zfsData.Pools))
poolCount := 0
if zfsData != nil {
poolCount = len(zfsData.Pools)
}
sys.recordZfsFetchResult(err, poolCount)
return err
}
@@ -79,7 +78,7 @@ func (sys *System) zfsFetchInterval() time.Duration {
// saveZfsPools saves ZFS pool detail data to the zfs_pools collection and
// removes records for pools no longer reported by a complete agent inventory.
func (sys *System) saveZfsPools(zfsData *zfs.ZfsData) error {
if zfsData == nil || !zfsData.Complete {
if zfsData == nil || (!zfsData.CanRefreshPool("zfs") && !zfsData.CanRefreshPool("b:")) {
return errIncompleteZfsData
}
@@ -89,10 +88,10 @@ func (sys *System) saveZfsPools(zfsData *zfs.ZfsData) error {
return err
}
return hub.RunInTransaction(func(txApp core.App) error {
err = hub.RunInTransaction(func(txApp core.App) error {
alive := make(map[string]bool, len(zfsData.Pools))
for _, pool := range zfsData.Pools {
if pool == nil {
if pool == nil || !zfsData.CanRefreshPool(pool.Name) {
continue
}
alive[pool.Name] = true
@@ -111,7 +110,7 @@ func (sys *System) saveZfsPools(zfsData *zfs.ZfsData) error {
return err
}
for _, record := range existing {
if !alive[record.GetString("name")] {
if name := record.GetString("name"); zfsData.CanRefreshPool(name) && !alive[name] {
if err := txApp.Delete(record); err != nil {
return err
}
@@ -119,6 +118,14 @@ func (sys *System) saveZfsPools(zfsData *zfs.ZfsData) error {
}
return nil
})
if err != nil {
return err
}
// Report partial failure only after committing healthy backend updates.
if !zfsData.Complete {
return errIncompleteZfsData
}
return nil
}
func (sys *System) upsertZfsPoolRecord(app core.App, collection *core.Collection, pool *zfs.PoolDetail) error {
@@ -135,10 +142,12 @@ func (sys *System) upsertZfsPoolRecord(app core.App, collection *core.Collection
record.Set("system", sys.Id)
record.Set("name", pool.Name)
record.Set("display_name", pool.DisplayName)
record.Set("health", pool.Health)
record.Set("size", pool.Size)
record.Set("alloc", pool.Alloc)
record.Set("free", pool.Free)
record.Set("raw", pool.Raw)
record.Set("scrub", pool.Scrub)
record.Set("vdevs", pool.Vdevs)
record.Set("datasets", pool.Datasets)
@@ -172,7 +181,9 @@ func (sys *System) syncZfsPoolHealth(app core.App, pools map[string]*system.ZfsP
record.Set("id", recordID)
record.Set("system", sys.Id)
record.Set("name", name)
record.Set("display_name", pool.DisplayName)
record.Set("health", pool.Health)
record.Set("raw", pool.Raw)
record.Set("size", uint64(pool.Total*gib))
record.Set("alloc", uint64(pool.Used*gib))
record.Set("free", uint64(max(pool.Total-pool.Used, 0)*gib))
@@ -181,10 +192,15 @@ func (sys *System) syncZfsPoolHealth(app core.App, pools map[string]*system.ZfsP
}
continue
}
if record.GetString("health") == pool.Health {
if record.GetString("health") == pool.Health && record.GetBool("raw") == pool.Raw && record.GetString("display_name") == pool.DisplayName {
continue
}
record.Set("display_name", pool.DisplayName)
record.Set("health", pool.Health)
record.Set("raw", pool.Raw)
record.Set("size", uint64(pool.Total*gib))
record.Set("alloc", uint64(pool.Used*gib))
record.Set("free", uint64(max(pool.Total-pool.Used, 0)*gib))
if err := app.SaveNoValidate(record); err != nil {
return fmt.Errorf("updating ZFS pool health %q: %w", name, err)
}
+77
View File
@@ -123,6 +123,44 @@ func TestSaveZfsPoolsIncompletePreservesRecords(t *testing.T) {
assert.Len(t, records, 1)
}
func TestSavePartialBackendInventory(t *testing.T) {
for _, healthy := range []string{"zfs", "btrfs"} {
t.Run(healthy, func(t *testing.T) {
sys, app := newTestSystemWithHub(t)
healthyKey, failedKey := "tank", "b:uuid"
if healthy == "btrfs" {
healthyKey, failedKey = failedKey, healthyKey
}
initial := &zfs.ZfsData{Complete: true, Pools: []*zfs.PoolDetail{
{Name: healthyKey, Alloc: 10}, {Name: failedKey, Alloc: 10},
}}
require.NoError(t, sys.saveZfsPools(initial))
failedID := makeStableHashId(sys.Id, failedKey)
before, err := app.FindRecordById("zfs_pools", failedID)
require.NoError(t, err)
partial := &zfs.ZfsData{CompleteBackends: []string{healthy}, Pools: []*zfs.PoolDetail{
{Name: healthyKey, Alloc: 20}, {Name: failedKey, Alloc: 99},
}}
assert.ErrorIs(t, sys.saveZfsPools(partial), errIncompleteZfsData)
fresh, err := app.FindRecordById("zfs_pools", makeStableHashId(sys.Id, healthyKey))
require.NoError(t, err)
assert.EqualValues(t, 20, fresh.GetInt("alloc"))
cached, err := app.FindRecordById("zfs_pools", failedID)
require.NoError(t, err)
assert.EqualValues(t, 10, cached.GetInt("alloc"))
assert.Equal(t, before.GetDateTime("details_updated"), cached.GetDateTime("details_updated"))
// An empty successful backend can prune, even while the other fails.
partial.Pools = nil
assert.ErrorIs(t, sys.saveZfsPools(partial), errIncompleteZfsData)
records, err := app.FindRecordsByFilter("zfs_pools", "system={:system}", "", 0, 0, map[string]any{"system": sys.Id})
require.NoError(t, err)
require.Len(t, records, 1)
assert.Equal(t, failedKey, records[0].GetString("name"))
require.NoError(t, sys.saveZfsPools(&zfs.ZfsData{Complete: true}))
})
}
}
func TestSyncZfsPoolHealthWritesOnlyTransitions(t *testing.T) {
sys, app := newTestSystemWithHub(t)
collection, err := app.FindCachedCollectionByNameOrId("zfs_pools")
@@ -151,3 +189,42 @@ func TestSyncZfsPoolHealthWritesOnlyTransitions(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "DEGRADED", record.GetString("health"))
}
func TestZfsRawCapacityPersistence(t *testing.T) {
sys, app := newTestSystemWithHub(t)
require.NoError(t, sys.saveZfsPools(&zfs.ZfsData{Complete: true, Pools: []*zfs.PoolDetail{{Name: "btrfs", Size: 200, Alloc: 10, Raw: true}}}))
record, err := app.FindRecordById("zfs_pools", makeStableHashId(sys.Id, "btrfs"))
require.NoError(t, err)
require.True(t, record.GetBool("raw"))
require.NoError(t, sys.syncZfsPoolHealth(app, map[string]*system.ZfsPool{"btrfs": {Total: 1, Used: 0.25}}))
record, err = app.FindRecordById("zfs_pools", record.Id)
require.NoError(t, err)
assert.False(t, record.GetBool("raw"))
assert.EqualValues(t, 1024*1024*1024, record.GetInt("size"))
}
func TestBtrfsDisplayNameKeepsRecordIdentity(t *testing.T) {
sys, app := newTestSystemWithHub(t)
key := "b:11111111-1111-4111-8111-111111111111"
require.NoError(t, sys.syncZfsPoolHealth(app, map[string]*system.ZfsPool{
key: {DisplayName: "tank", Health: "ONLINE"},
"tank": {Health: "ONLINE"},
}))
id := makeStableHashId(sys.Id, key)
record, err := app.FindRecordById("zfs_pools", id)
require.NoError(t, err)
assert.Equal(t, "tank", record.GetString("display_name"))
require.NoError(t, sys.syncZfsPoolHealth(app, map[string]*system.ZfsPool{key: {DisplayName: "renamed", Health: "ONLINE"}}))
record, err = app.FindRecordById("zfs_pools", id)
require.NoError(t, err)
assert.Equal(t, key, record.GetString("name"))
assert.Equal(t, "renamed", record.GetString("display_name"))
require.NoError(t, sys.saveZfsPools(&zfs.ZfsData{Complete: true, Pools: []*zfs.PoolDetail{
{Name: key, DisplayName: "detail name", Health: "ONLINE"}, {Name: "tank", Health: "ONLINE"},
}}))
record, err = app.FindRecordById("zfs_pools", id)
require.NoError(t, err)
assert.Equal(t, "detail name", record.GetString("display_name"))
_, err = app.FindRecordById("zfs_pools", makeStableHashId(sys.Id, "tank"))
require.NoError(t, err)
}
@@ -3,9 +3,11 @@
package systems_test
import (
"encoding/json"
"testing"
"time"
"github.com/fxamacker/cbor/v2"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/henrygd/beszel/internal/entities/systemd"
"github.com/henrygd/beszel/internal/hub/systems"
@@ -15,6 +17,42 @@ import (
"github.com/stretchr/testify/require"
)
func TestCreateRecordsRejectsNullSystemdService(t *testing.T) {
hub, user := tests.GetHubWithUser(t)
defer hub.Cleanup()
records, err := tests.CreateSystems(hub, 1, user.Id, "paused")
require.NoError(t, err)
sys, err := hub.GetSystemManager().GetSystem(records[0].Id)
require.NoError(t, err)
require.NoError(t, systems.CreateSystemdStatsRecords(hub, []*systemd.Service{
{Name: "existing.service", State: systemd.StatusFailed},
}, records[0].Id))
for _, services := range []string{`[null]`, `[{"name":"new.service"},null]`, `[null,{"name":"new.service"}]`} {
for _, encoding := range []string{"json", "cbor"} {
t.Run(encoding+"/"+services, func(t *testing.T) {
var data system.CombinedData
require.NoError(t, json.Unmarshal([]byte(`{"systemd":`+services+`}`), &data))
if encoding == "cbor" {
encoded, err := cbor.Marshal(data)
require.NoError(t, err)
data = system.CombinedData{}
require.NoError(t, cbor.Unmarshal(encoded, &data))
}
_, err := sys.CreateRecords(&data)
require.ErrorContains(t, err, "null systemd service")
var names []string
require.NoError(t, hub.DB().Select("name").From("systemd_services").
Where(dbx.HashExp{"system": records[0].Id}).Column(&names))
assert.Equal(t, []string{"existing.service"}, names)
count, err := hub.CountRecords("system_stats", dbx.HashExp{"system": records[0].Id})
require.NoError(t, err)
assert.Zero(t, count, "invalid snapshot must roll back system stats")
})
}
}
}
func TestCreateRecordsHandlesSystemdAlertLifecycle(t *testing.T) {
hub, user := tests.GetHubWithUser(t)
defer hub.Cleanup()
@@ -0,0 +1,27 @@
package migrations
import (
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(app core.App) error {
c, err := app.FindCollectionByNameOrId("zfs_pools")
if err != nil {
return err
}
c.Fields.Add(&core.TextField{Name: "display_name"})
c.Fields.Add(&core.BoolField{Name: "raw"})
return app.Save(c)
}, func(app core.App) error {
c, err := app.FindCollectionByNameOrId("zfs_pools")
if err != nil {
return err
}
c.Fields.RemoveByName("display_name")
c.Fields.RemoveByName("raw")
return app.Save(c)
})
}
+14 -3
View File
@@ -198,6 +198,7 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
var fanSums map[string]uint64
fanCount := uint64(0)
zfsPoolCounts := make(map[string]uint64)
zfsCapacityCounts := make(map[string]uint64)
// Accumulate totals
for i := range records {
@@ -350,9 +351,19 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
}
pool := sum.ZfsPools[name]
if pool == nil {
pool = &system.ZfsPool{}
pool = &system.ZfsPool{HideUsage: value.HideUsage, HideIO: value.HideIO}
sum.ZfsPools[name] = pool
}
// Never average physical and usable capacity into the same value.
if pool.Raw != value.Raw {
pool.Total, pool.Used = 0, 0
zfsCapacityCounts[name] = 0
}
pool.HideUsage = pool.HideUsage && value.HideUsage
pool.HideIO = pool.HideIO && value.HideIO
pool.DisplayName = value.DisplayName
pool.Raw = value.Raw
zfsCapacityCounts[name]++
pool.Total += value.Total
pool.Used += value.Used
pool.ReadBytes += value.ReadBytes
@@ -476,8 +487,8 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
// Average ZFS pool stats.
for name, pool := range sum.ZfsPools {
entryCount := zfsPoolCounts[name]
pool.Total = twoDecimals(pool.Total / float64(entryCount))
pool.Used = twoDecimals(pool.Used / float64(entryCount))
pool.Total = twoDecimals(pool.Total / float64(zfsCapacityCounts[name]))
pool.Used = twoDecimals(pool.Used / float64(zfsCapacityCounts[name]))
pool.ReadBytes /= entryCount
pool.WriteBytes /= entryCount
}
@@ -889,3 +889,34 @@ func TestAverageContainerStatsSlice_ManyContainers(t *testing.T) {
assert.Equal(t, 35.0, result[2].Cpu)
assert.Equal(t, 45.0, result[3].Cpu)
}
func TestAverageSystemStatsSlice_ZfsCapacityModes(t *testing.T) {
for _, raw := range []bool{false, true} {
result := records.AverageSystemStatsSlice([]system.Stats{
{ZfsPools: map[string]*system.ZfsPool{"pool": {Total: 200, Used: 40, Raw: !raw, ReadBytes: 100}}},
{ZfsPools: map[string]*system.ZfsPool{"pool": {Total: 100, Used: 10, Raw: raw, ReadBytes: 300}}},
})
assert.Equal(t, &system.ZfsPool{Total: 100, Used: 10, Raw: raw, ReadBytes: 200}, result.ZfsPools["pool"])
}
}
func TestAverageSystemStatsSlice_ZfsDuplicateCharts(t *testing.T) {
for _, hide := range []bool{false, true} {
result := records.AverageSystemStatsSlice([]system.Stats{
{ZfsPools: map[string]*system.ZfsPool{"pool": {HideUsage: true, HideIO: true}}},
{ZfsPools: map[string]*system.ZfsPool{"pool": {HideUsage: hide, HideIO: hide}}},
})
assert.Equal(t, hide, result.ZfsPools["pool"].HideUsage)
assert.Equal(t, hide, result.ZfsPools["pool"].HideIO)
}
}
func TestAverageSystemStatsSlice_BtrfsDisplayName(t *testing.T) {
result := records.AverageSystemStatsSlice([]system.Stats{
{ZfsPools: map[string]*system.ZfsPool{"b:uuid": {DisplayName: "before", Used: 10}}},
{ZfsPools: map[string]*system.ZfsPool{"b:uuid": {DisplayName: "after", Used: 20}}},
})
require.Len(t, result.ZfsPools, 1)
assert.Equal(t, "after", result.ZfsPools["b:uuid"].DisplayName)
assert.Equal(t, float64(15), result.ZfsPools["b:uuid"].Used)
}
@@ -8,7 +8,7 @@ import { useSystemData } from "./system/use-system-data"
import { CpuChart, ContainerCpuChart } from "./system/charts/cpu-charts"
import { MemoryChart, ContainerMemoryChart, SwapChart } from "./system/charts/memory-charts"
import { RootDiskCharts, ExtraFsCharts } from "./system/charts/disk-charts"
import { ZfsCharts } from "./system/charts/zfs-charts"
import { ZfsCharts } from "./system/charts/storage-pool-charts"
import { BandwidthChart, ContainerNetworkChart } from "./system/charts/network-charts"
import { TemperatureChart, FanChart, BatteryChart } from "./system/charts/sensor-charts"
import { GpuPowerChart, GpuCharts } from "./system/charts/gpu-charts"
@@ -95,7 +95,7 @@ export function ChartCard({
className,
}: {
title: string
description: string
description: React.ReactNode
children: React.ReactNode
grid?: boolean
empty?: boolean
@@ -3,6 +3,7 @@ import AreaChartDefault from "@/components/charts/area-chart"
import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import type { SystemStatsRecord } from "@/types"
import { ChartCard } from "../chart-card"
import { RawCapacityLabel } from "../raw-capacity-label"
import { Unit } from "@/lib/enums"
import { useStore } from "@nanostores/react"
import { $userSettings } from "@/lib/stores"
@@ -10,9 +11,11 @@ import type { SystemData } from "../use-system-data"
// Accessors for ZFS metrics
const poolUsage =
(name: string) =>
({ stats }: SystemStatsRecord) =>
stats?.z?.[name]?.du ?? 0
(name: string, raw: boolean) =>
({ stats }: SystemStatsRecord) => {
const pool = stats?.z?.[name]
return pool && !!pool.raw === raw ? pool.du : null
}
const poolRead =
(name: string) =>
({ stats }: SystemStatsRecord) =>
@@ -26,9 +29,10 @@ export function ZfsPoolUsageChart({ systemData, poolName }: { systemData: System
const { chartData, grid, dataEmpty } = systemData
const latest = chartData.systemStats.at(-1)?.stats
const pool = latest?.z?.[poolName]
if (!pool) {
if (!pool || pool.hu) {
return null
}
const displayName = pool.n || poolName
let poolTotal = pool.d
// round to nearest GB
if (poolTotal >= 100) {
@@ -39,8 +43,8 @@ export function ZfsPoolUsageChart({ systemData, poolName }: { systemData: System
<ChartCard
empty={dataEmpty}
grid={grid}
title={`${poolName} ${t`Usage`}`}
description={t`Usage of ZFS pool ${poolName}`}
title={`${displayName} ${t`Usage`}`}
description={pool.raw ? <RawCapacityLabel label={t`Raw usage of storage pool ${displayName}`} /> : t`Usage of storage pool ${displayName}`}
>
<AreaChartDefault
chartData={chartData}
@@ -57,7 +61,7 @@ export function ZfsPoolUsageChart({ systemData, poolName }: { systemData: System
dataPoints={[
{
label: t`Pool Usage`,
dataKey: poolUsage(poolName),
dataKey: poolUsage(poolName, !!pool.raw),
color: 4,
opacity: 0.4,
},
@@ -70,15 +74,16 @@ export function ZfsPoolUsageChart({ systemData, poolName }: { systemData: System
export function ZfsPoolIOChart({ systemData, poolName }: { systemData: SystemData; poolName: string }) {
const { chartData, grid, dataEmpty } = systemData
const userSettings = useStore($userSettings)
if (!chartData.systemStats?.length) {
if (!chartData.systemStats?.length || chartData.systemStats.at(-1)?.stats.z?.[poolName]?.hi) {
return null
}
const displayName = chartData.systemStats.at(-1)?.stats.z?.[poolName]?.n || poolName
return (
<ChartCard
empty={dataEmpty}
grid={grid}
title={`${poolName} I/O`}
description={t`Throughput of ZFS pool ${poolName}`}
title={`${displayName} I/O`}
description={t`Throughput of storage pool ${displayName}`}
>
<AreaChartDefault
chartData={chartData}
@@ -114,12 +119,15 @@ export function ZfsPoolIOChart({ systemData, poolName }: { systemData: SystemDat
export function ZfsCharts({ systemData }: { systemData: SystemData }) {
const latest = systemData.chartData.systemStats?.at(-1)?.stats
const pools = latest?.z ?? {}
if (Object.keys(pools).length === 0) {
const visiblePools = Object.keys(pools)
.filter((name) => !pools[name].hu || !pools[name].hi)
.sort((a, b) => (pools[a].n || a).localeCompare(pools[b].n || b, undefined, { numeric: true }) || a.localeCompare(b))
if (visiblePools.length === 0) {
return null
}
return (
<div className="grid xl:grid-cols-2 gap-4">
{Object.keys(pools).map((poolName) => (
{visiblePools.map((poolName) => (
<div key={poolName} className="contents">
<ZfsPoolUsageChart systemData={systemData} poolName={poolName} />
<ZfsPoolIOChart systemData={systemData} poolName={poolName} />
@@ -24,7 +24,7 @@ export function LazySmartTable({ systemId }: { systemId: string }) {
)
}
const ZfsTable = lazy(() => import("./zfs-table"))
const ZfsTable = lazy(() => import("./storage-pools-table"))
export function LazyZfsTable({ systemId }: { systemId: string }) {
const { isIntersecting, ref } = useIntersectionObserver({ rootMargin: "90px" })
@@ -0,0 +1,25 @@
import { t } from "@lingui/core/macro"
import { InfoIcon } from "lucide-react"
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
export function RawCapacityLabel({ label = t`Raw` }: { label?: string }) {
return (
<span className="inline-flex items-center gap-1">
{label}
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
aria-label="About raw capacity"
className="inline-flex rounded-sm text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<InfoIcon className="size-3.5" aria-hidden="true" />
</button>
</TooltipTrigger>
<TooltipContent className="max-w-64">
{t`Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled.`}
</TooltipContent>
</Tooltip>
</span>
)
}
@@ -75,7 +75,12 @@ export const smartColumns: ColumnDef<SmartAttribute>[] = [
header: "Name",
},
{
accessorFn: (row) => row.rs || row.rv?.toString(),
accessorFn: (row) => {
if (row.n === "DataUnitsWritten" || row.n === "DataUnitsRead") {
return formatDataUnits(Number(row.rv ?? 0))
}
return row.rs || row.rv?.toString()
},
header: "Value",
},
{
@@ -103,6 +108,12 @@ function formatCapacity(bytes: number): string {
return `${toFixedFloat(value, value >= 10 ? 1 : 2)} ${unit}`
}
// Function to format NVMe data units
// (1 unit = 1000 * 512 bytes) as a human-readable size
function formatDataUnits(units: number): string {
return formatCapacity(units * 1000 * 512)
}
const SMART_DEVICE_FIELDS = "id,system,name,model,state,capacity,temp,type,hours,cycles,updated"
export const createColumns = (
@@ -26,6 +26,7 @@ import {
CheckCircleIcon,
CircleAlertIcon,
ClockIcon,
DatabaseIcon,
HardDriveDownloadIcon,
HardDriveIcon,
HardDriveUploadIcon,
@@ -35,10 +36,13 @@ import {
RotateCwIcon,
XCircleIcon,
XIcon,
FolderTreeIcon,
} from "lucide-react"
import { useCallback, useEffect, useMemo, useState } from "react"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
const ZFS_POOL_FIELDS = "id,system,name,health,size,alloc,free,scrub,details_updated,updated"
import { RawCapacityLabel } from "./raw-capacity-label"
const ZFS_POOL_FIELDS = "id,system,name,display_name,health,size,alloc,free,raw,scrub,details_updated,updated"
/** Maps a zpool health string to a Badge variant. */
function healthVariant(health: string): "success" | "warning" | "danger" | "outline" {
@@ -81,13 +85,30 @@ function HeaderButton<T>({ column, name, Icon }: { column: Column<T>; name: stri
)
}
function poolType(pool: ZfsPoolRecord): string {
return pool.name.startsWith("b:") ? "Btrfs" : "ZFS"
}
const columns: ColumnDef<ZfsPoolRecord>[] = [
{
accessorKey: "name",
sortingFn: (a, b) => a.original.name.localeCompare(b.original.name),
header: ({ column }) => <HeaderButton column={column} name={`Pool`} Icon={HardDriveIcon} />,
id: "name",
accessorFn: (pool) => pool.display_name || pool.name,
header: ({ column }) => <HeaderButton column={column} name={`Pool`} Icon={DatabaseIcon} />,
cell: ({ getValue }) => <span className="font-medium ms-1.5">{getValue() as string}</span>,
},
{
id: "type",
accessorFn: poolType,
header: ({ column }) => <HeaderButton column={column} name={t`Type`} Icon={FolderTreeIcon} />,
cell: ({ getValue }) => {
const type = getValue() as string
return (
<Badge variant="outline" className={cn("border-transparent", type === "ZFS" ? "bg-blue-200 text-blue-800" : "bg-yellow-200 text-yellow-800")}>
{type}
</Badge>
)
},
},
{
accessorKey: "health",
sortingFn: (a, b) => a.original.health.localeCompare(b.original.health),
@@ -102,21 +123,21 @@ const columns: ColumnDef<ZfsPoolRecord>[] = [
accessorFn: (record) => record.size,
invertSorting: true,
header: ({ column }) => <HeaderButton column={column} name={t`Capacity`} Icon={BinaryIcon} />,
cell: ({ getValue }) => <span className="ms-1.5 tabular-nums">{formatCapacity(getValue() as number)}</span>,
cell: ({ getValue, row }) => <span className="ms-1.5 tabular-nums">{formatCapacity(getValue() as number)}{row.original.raw ? ` (${t`Raw`})` : ""}</span>,
},
{
id: "used",
accessorFn: (record) => record.alloc,
invertSorting: true,
header: ({ column }) => <HeaderButton column={column} name={t`Used`} Icon={HardDriveDownloadIcon} />,
cell: ({ getValue }) => <span className="ms-1.5 tabular-nums">{formatCapacity(getValue() as number)}</span>,
cell: ({ getValue, row }) => <span className="ms-1.5 tabular-nums">{formatCapacity(getValue() as number)}{row.original.raw ? ` (${t`Raw`})` : ""}</span>,
},
{
id: "free",
accessorFn: (record) => record.free,
invertSorting: true,
header: ({ column }) => <HeaderButton column={column} name={t({ message: `Free`, context: "Free space" })} Icon={HardDriveUploadIcon} />,
cell: ({ getValue }) => <span className="ms-1.5 tabular-nums">{formatCapacity(getValue() as number)}</span>,
cell: ({ getValue, row }) => <span className="ms-1.5 tabular-nums">{row.original.raw ? "-" : formatCapacity(getValue() as number)}</span>,
},
{
id: "scrub",
@@ -201,7 +222,7 @@ const datasetColumns: ColumnDef<ZfsDataset>[] = [
{
accessorKey: "name",
sortingFn: (a, b) => a.original.name.localeCompare(b.original.name),
header: ({ column }) => <HeaderButton column={column} name={`Dataset`} Icon={HardDriveIcon} />,
header: ({ column }) => <HeaderButton column={column} name={`Dataset`} Icon={DatabaseIcon} />,
cell: ({ getValue }) => <span className="font-mono text-xs">{getValue() as string}</span>,
},
{
@@ -310,6 +331,7 @@ function PoolSheet({
onOpenChange: (open: boolean) => void
}) {
const [pool, setPool] = useState<ZfsPoolRecord | null>(null)
const titleRef = useRef<HTMLHeadingElement>(null)
const [isLoading, setIsLoading] = useState(false)
useEffect(() => {
@@ -342,23 +364,30 @@ function PoolSheet({
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent className="w-full sm:max-w-220 gap-0 overflow-y-auto">
<SheetContent
className="w-full sm:max-w-220 gap-0 overflow-y-auto"
onOpenAutoFocus={(event) => {
event.preventDefault()
titleRef.current?.focus()
}}
>
<SheetHeader className="mb-0 border-b">
<SheetTitle className="flex items-center gap-2">
{pool ? pool.name : `ZFS Pool`}
<SheetTitle ref={titleRef} tabIndex={-1} className="flex items-center gap-2 outline-none">
{pool ? (pool.display_name || pool.name) : `Storage Pool`}
{pool && <Badge variant={healthVariantValue}>{health}</Badge>}
</SheetTitle>
<SheetDescription className="flex flex-wrap items-center gap-x-2 gap-y-1">
{pool?.size ? formatCapacity(pool.size) : null}
{pool?.raw && <RawCapacityLabel />}
{pool?.alloc ? (
<>
<Separator orientation="vertical" className="h-2.5 bg-muted-foreground opacity-70" />
<span>
<Trans>Used</Trans>: {formatCapacity(pool.alloc)}
<Trans>Used</Trans>: {formatCapacity(pool.alloc)}{pool.raw ? ` (${t`Raw`})` : ""}
</span>
</>
) : null}
{pool?.free ? (
{pool?.free && !pool.raw ? (
<>
<Separator orientation="vertical" className="h-2.5 bg-muted-foreground opacity-70" />
<span>
@@ -555,6 +584,7 @@ export default function ZfsTable({ systemId }: { systemId?: string }) {
const table = useReactTable({
data: zfsPools || ([] as ZfsPoolRecord[]),
columns: tableColumns,
initialState: { sorting: [{ id: "name", desc: false }] },
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
@@ -562,7 +592,7 @@ export default function ZfsTable({ systemId }: { systemId?: string }) {
onGlobalFilterChange: setGlobalFilter,
globalFilterFn: (row, _columnId, filterValue) => {
const pool = row.original
const searchString = `${pool.name} ${pool.health ?? ""}`.toLowerCase()
const searchString = `${pool.display_name ?? ""} ${pool.name} ${poolType(pool)} ${pool.health ?? ""}`.toLowerCase()
return (filterValue as string)
.toLowerCase()
.split(" ")
@@ -587,7 +617,7 @@ export default function ZfsTable({ systemId }: { systemId?: string }) {
<CardHeader className="p-0 mb-3 sm:mb-4">
<div className="grid md:flex gap-x-5 gap-y-3 w-full items-end">
<div className="px-2 sm:px-1">
<CardTitle className="mb-2">ZFS</CardTitle>
<CardTitle className="mb-2">Storage Pools</CardTitle>
<CardDescription className="flex">
<Trans>Click on a pool to view vdev and dataset details.</Trans>
</CardDescription>
@@ -193,7 +193,7 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef<Syste
header: sortableHeader,
},
{
accessorFn: ({ info }) => info.g || undefined,
accessorFn: ({ info }) => info.g,
id: "gpu",
name: () => "GPU",
cell: (info) => {
+18 -2
View File
@@ -4,7 +4,7 @@ import { basePath } from "@/components/router"
import { toast } from "@/components/ui/use-toast"
import type { ChartTimes, UserSettings } from "@/types"
import { $alerts, $allSystemsById, $allSystemsByName, $userSettings } from "./stores"
import { chartTimeData } from "./utils"
import { chartTimeData, debounce } from "./utils"
/** PocketBase JS Client */
export const pb = new PocketBase(basePath)
@@ -12,7 +12,7 @@ export const pb = new PocketBase(basePath)
export const isAdmin = () => pb.authStore.record?.role === "admin"
export const isReadOnlyUser = () => pb.authStore.record?.role === "readonly"
export const verifyAuth = () => {
const verifyAuth = () => {
pb.collection("users")
.authRefresh()
.catch(() => {
@@ -25,6 +25,22 @@ export const verifyAuth = () => {
})
}
const verifyAuthDebounced = debounce(verifyAuth, 100)
// verify the session whenever any API request returns a 4xx response (e.g. an
// expired JWT). The auth-refresh endpoint is excluded to avoid a loop, since
// it returns 401 itself when the token is no longer valid.
pb.afterSend = (response, data) => {
if (
(response.status === 401 || response.status === 403) &&
pb.authStore.token &&
!response.url.includes("auth-refresh")
) {
verifyAuthDebounced()
}
return data
}
/** Logs the user out by clearing the auth store and unsubscribing from realtime updates. */
export function logOut() {
$allSystemsByName.set({})
+1 -6
View File
@@ -1,6 +1,6 @@
/** biome-ignore-all lint/suspicious/noAssignInExpressions: it's fine :) */
import type { PreinitializedMapStore } from "nanostores"
import { pb, verifyAuth } from "@/lib/api"
import { pb } from "@/lib/api"
import {
$allSystemsById,
$allSystemsByName,
@@ -167,11 +167,6 @@ export async function subscribe() {
export async function refresh() {
try {
const records = await fetchSystems()
if (!records.length) {
// No systems found, verify authentication
verifyAuth()
return
}
for (const record of records) {
add(record)
}
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ar\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 19:32\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 دقائق"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "إجراءات"
@@ -196,7 +196,7 @@ msgstr "هل أنت متأكد؟"
msgid "Automatic copy requires a secure context."
msgstr "النسخ التلقائي يتطلب سياقًا آمنًا."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "المتاح"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "القدرات"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "السعة"
@@ -391,14 +391,14 @@ msgstr "تحقق من خدمة المراقبة الخاصة بك"
msgid "Check your notification service"
msgstr "تحقق من خدمة الإشعارات الخاصة بك"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "أخطاء المجموع الاختباري"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "مسح"
@@ -411,7 +411,7 @@ msgstr "انقر على حاوية لعرض مزيد من المعلومات."
msgid "Click on a device to view more information."
msgstr "انقر على جهاز لعرض مزيد من المعلومات."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "انقر على مجموعة تخزين لعرض تفاصيل vdev ومجموعة البيانات."
@@ -503,7 +503,7 @@ msgstr "نسخ الاسم"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "نسخ المفتاح العام"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "فشل: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "المراوح"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "لمدة <0>{min}</0> {min, plural, one {دقيقة} other {دقائق}}
msgid "Forgot password?"
msgstr "هل نسيت كلمة المرور؟"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "المساحة الحرة"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "شبكة"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "الصحة"
@@ -1146,7 +1146,7 @@ msgstr "استخدام الذاكرة للحاويات"
msgid "Model"
msgstr "الموديل"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "نقطة الربط"
@@ -1185,7 +1185,7 @@ msgstr "وحدة الشبكة"
msgid "No"
msgstr "لا"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "لا تتوفر بيانات تفصيلية لمجموعة التخزين هذه."
@@ -1212,7 +1212,7 @@ msgstr "لا توجد سمات S.M.A.R.T. متاحة لهذا الجهاز."
msgid "No systems found."
msgstr "لم يتم العثور على أنظمة."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "لا شيء"
@@ -1255,7 +1255,7 @@ msgstr "كلمة مرور لمرة واحدة"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "فتح القائمة"
@@ -1346,6 +1346,10 @@ msgstr "دائم"
msgid "Persistence"
msgstr "الاستمرارية"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "مساحة الجهاز الفعلية. السعة الفعلية القابلة للاستخدام غير معروفة. تم تعطيل تنبيهات استخدام أقراص المجموعة."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "يرجى <0>تكوين خادم SMTP</0> لضمان تسليم التنبيهات."
@@ -1379,11 +1383,11 @@ msgstr "يرجى الاطلاع على <0>التوثيق</0> للحصول على
msgid "Please sign in to your account"
msgstr "يرجى تسجيل الدخول إلى حسابك"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "صحة مجموعة التخزين"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "استخدام مجموعة التخزين"
@@ -1416,7 +1420,7 @@ msgstr "تم بدء العملية"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "المفتاح العام"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "عمق الدور"
msgid "Quiet Hours"
msgstr "ساعات الهدوء"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "الخام"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "الاستخدام الخام لمجموعة التخزين {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "ساعات الهدوء"
msgid "Read"
msgstr "قراءة"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "أخطاء القراءة"
@@ -1454,7 +1469,7 @@ msgstr "تم الاستلام"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "تحديث"
@@ -1643,7 +1658,7 @@ msgstr "وقت البدء"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "الحالة"
@@ -1671,7 +1686,7 @@ msgstr "استخدام التبديل"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "تبديل السمة"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "النظام"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "سرعات مراوح النظام (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "سيؤدي هذا إلى حذف جميع السجلات المحددة
msgid "Throughput of {extraFsName}"
msgstr "معدل نقل {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "معدل نقل البيانات لمجموعة ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "معدل نقل مجموعة التخزين {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "يتم التفعيل عندما يتجاوز استخدام أي قرص
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "النوع"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "رمز مميز عالمي"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "غير معروفة"
@@ -1945,7 +1961,7 @@ msgstr "تحديث"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "تم التحديث"
@@ -1968,20 +1984,20 @@ msgstr "مدة التشغيل"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "الاستخدام"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "استخدام مجموعة ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "استخدام مجموعة التخزين {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "مستخدم"
@@ -2058,7 +2074,7 @@ msgstr "أمر ويندوز"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "أمر ويندوز"
msgid "Write"
msgstr "كتابة"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "أخطاء الكتابة"
@@ -2087,3 +2103,4 @@ msgstr "نعم"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تم تحديث إعدادات المستخدم الخاصة بك."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: bg\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Bulgarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 минути"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Действия"
@@ -196,7 +196,7 @@ msgstr "Сигурни ли сте?"
msgid "Automatic copy requires a secure context."
msgstr "Автоматичното копиране изисква защитен контескт."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Налично"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Възможности"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Капацитет"
@@ -391,14 +391,14 @@ msgstr "Проверете мониторинг услугата си"
msgid "Check your notification service"
msgstr "Провери услугата си за удостоверяване"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Грешки в контролната сума"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Изчисти"
@@ -411,7 +411,7 @@ msgstr "Кликнете върху контейнер, за да видите
msgid "Click on a device to view more information."
msgstr "Кликнете върху устройство, за да видите повече информация."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Щракнете върху пул, за да видите подробности за vdev и наборите от данни."
@@ -503,7 +503,7 @@ msgstr "Копирай име"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Копирай публичния ключ"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Неуспешни: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Вентилатори"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "За <0>{min}</0> {min, plural, one {минута} other {минути}}
msgid "Forgot password?"
msgstr "Забравена парола?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Свободно"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Мрежово"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Здраве"
@@ -1146,7 +1146,7 @@ msgstr "Използване на паметта от контейнерите"
msgid "Model"
msgstr "Модел"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Точка на монтиране"
@@ -1185,7 +1185,7 @@ msgstr "Единица за измерване на скорост"
msgid "No"
msgstr "Не"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Няма подробни данни за този пул."
@@ -1212,7 +1212,7 @@ msgstr "Няма налични S.M.A.R.T. атрибути за това уст
msgid "No systems found."
msgstr "Няма намерени системи."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Няма"
@@ -1255,7 +1255,7 @@ msgstr "Еднократна парола"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Отвори менюто"
@@ -1346,6 +1346,10 @@ msgstr "Постоянен"
msgid "Persistence"
msgstr "Устойчивост"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Физическо пространство на устройството. Действителният използваем капацитет е неизвестен. Сигналите за използване на диска на пула са изключени."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Моля <0>конфигурурай SMTP сървър</0> за да се подсигуриш, че тревогите са доставени."
@@ -1379,11 +1383,11 @@ msgstr "Моля виж <0>документацията</0> за инструк
msgid "Please sign in to your account"
msgstr "Моля влез в акаунта ти"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Състояние на пула"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Използване на пула"
@@ -1416,7 +1420,7 @@ msgstr "Процесът стартира"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Публичен ключ"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Дълбочина на опашката"
msgid "Quiet Hours"
msgstr "Тихи часове"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Сурово"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Сурово използване на пула {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Тихи часове"
msgid "Read"
msgstr "Прочети"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Грешки при четене"
@@ -1454,7 +1469,7 @@ msgstr "Получени"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Опресни"
@@ -1643,7 +1658,7 @@ msgstr "Начален час"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Състояние"
@@ -1671,7 +1686,7 @@ msgstr "Използване на swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Смени темата"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Система"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Скорости на вентилаторите на системата (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Това ще доведе до трайно изтриване на в
msgid "Throughput of {extraFsName}"
msgstr "Пропускателна способност на {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Пропускателна способност на ZFS пул {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Пропускателна способност на пула {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Общо изпратени данни за всеки интерфей
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Общо време, прекарано в четене/запис (може да надвиши 100%)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Задейства се, когато употребата на няко
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Тип"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Универсален тоукън"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Неизвестна"
@@ -1945,7 +1961,7 @@ msgstr "Актуализирай"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Актуализирано"
@@ -1968,20 +1984,20 @@ msgstr "Време на работа"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Употреба"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Използване на ZFS пул {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Използване на пула {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Използвани"
@@ -2058,7 +2074,7 @@ msgstr "Команда Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Команда Windows"
msgid "Write"
msgstr "Запиши"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Грешки при запис"
@@ -2087,3 +2103,4 @@ msgstr "Да"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Настройките за потребителя ти са обновени."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: cs\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Akce"
@@ -196,7 +196,7 @@ msgstr "Jste si jistý?"
msgid "Automatic copy requires a secure context."
msgstr "Automatická kopie vyžaduje zabezpečený kontext."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Dostupné"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Schopnosti"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapacita"
@@ -391,14 +391,14 @@ msgstr "Zkontrolujte svou monitorovací službu"
msgid "Check your notification service"
msgstr "Zkontrolujte službu upozornění"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Chyby kontrolního součtu"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Vymazat"
@@ -411,7 +411,7 @@ msgstr "Klikněte na kontejner pro zobrazení dalších informací."
msgid "Click on a device to view more information."
msgstr "Klikněte na zařízení pro zobrazení dalších informací."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Kliknutím na fond zobrazíte podrobnosti o vdev a datových sadách."
@@ -503,7 +503,7 @@ msgstr "Kopírovat název"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Zkopírovat veřejný klíč"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Neúspěšné: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilátory"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Za <0>{min}</0> {min, plural, one {minutu} few {minuty} other {minut}}"
msgid "Forgot password?"
msgstr "Zapomněli jste heslo?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Volné"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Mřížka"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Zdraví"
@@ -1146,7 +1146,7 @@ msgstr "Využití paměti kontejnery"
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Bod připojení"
@@ -1185,7 +1185,7 @@ msgstr "Síťová jednotka"
msgid "No"
msgstr "Ne"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Pro tento fond nejsou k dispozici podrobné údaje."
@@ -1212,7 +1212,7 @@ msgstr "Pro toto zařízení nejsou k dispozici žádné atributy S.M.A.R.T."
msgid "No systems found."
msgstr "Nenalezeny žádné systémy."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Žádné"
@@ -1255,7 +1255,7 @@ msgstr "Jednorázové heslo"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Otevřít menu"
@@ -1346,6 +1346,10 @@ msgstr "Trvalý"
msgid "Persistence"
msgstr "Trvalost"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fyzické místo na zařízení. Skutečná využitelná kapacita není známa. Upozornění na využití disků fondu jsou vypnutá."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Instrukce naleznete v <0>dokumentaci</0>."
msgid "Please sign in to your account"
msgstr "Přihlaste se prosím k vašemu účtu"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Stav fondu"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Využití fondu"
@@ -1416,7 +1420,7 @@ msgstr "Proces spuštěn"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Veřejný klíč"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Hloubka fronty"
msgid "Quiet Hours"
msgstr "Tiché hodiny"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Hrubé"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Hrubé využití fondu {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Tiché hodiny"
msgid "Read"
msgstr "Číst"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Chyby čtení"
@@ -1454,7 +1469,7 @@ msgstr "Přijato"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Aktualizovat"
@@ -1643,7 +1658,7 @@ msgstr "Čas začátku"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stav"
@@ -1671,7 +1686,7 @@ msgstr "Swap využití"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Přepnout motiv"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Systém"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Rychlosti ventilátorů systému (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Tímto trvale odstraníte všechny vybrané záznamy z databáze."
msgid "Throughput of {extraFsName}"
msgstr "Propustnost {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Propustnost fondu ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Propustnost fondu {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Celkový odeslaný objem dat pro každé rozhraní"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Celkový čas strávený čtením/zápisem (může přesáhnout 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Spustí se, když využití disku překročí prahovou hodnotu"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Typ"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Univerzální token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Neznámá"
@@ -1945,7 +1961,7 @@ msgstr "Aktualizovat"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aktualizováno"
@@ -1968,20 +1984,20 @@ msgstr "Doba provozu"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Využití"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Využití fondu ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Využití fondu {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Využito"
@@ -2058,7 +2074,7 @@ msgstr "Windows příkaz"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows příkaz"
msgid "Write"
msgstr "Psát"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Chyby zápisu"
@@ -2087,3 +2103,4 @@ msgstr "Ano"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše uživatelská nastavení byla aktualizována."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: da\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Danish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 minutter"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Handlinger"
@@ -196,7 +196,7 @@ msgstr "Er du sikker?"
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering kræver en sikker kontekst."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Tilgængelig"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Funktioner"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapacitet"
@@ -391,14 +391,14 @@ msgstr "Tjek din overvågningstjeneste"
msgid "Check your notification service"
msgstr "Tjek din notifikationstjeneste"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Kontrolsumfejl"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Ryd"
@@ -411,7 +411,7 @@ msgstr "Klik på en container for at se mere information."
msgid "Click on a device to view more information."
msgstr "Klik på en enhed for at se flere oplysninger."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klik på en pool for at se detaljer om vdev og datasæt."
@@ -503,7 +503,7 @@ msgstr "Kopier navn"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopiér offentlig nøgle"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Mislykkedes: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Blæsere"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "For <0>{min}</0> {min, plural, one {minut} other {minutter}}"
msgid "Forgot password?"
msgstr "Glemt adgangskode?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Ledig"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Gitter"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Sundhed"
@@ -1146,7 +1146,7 @@ msgstr "Containeres hukommelsesforbrug"
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Monteringspunkt"
@@ -1185,7 +1185,7 @@ msgstr "Netværksenhed"
msgid "No"
msgstr "Nej"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Ingen detaljerede data for denne pool."
@@ -1212,7 +1212,7 @@ msgstr "Ingen S.M.A.R.T.-attributter tilgængelige for denne enhed."
msgid "No systems found."
msgstr "Ingen systemer fundet."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Ingen"
@@ -1255,7 +1255,7 @@ msgstr "Engangsadgangskode"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Åbn menu"
@@ -1346,6 +1346,10 @@ msgstr ""
msgid "Persistence"
msgstr "Vedholdenhed"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fysisk enhedsplads. Den reelle brugbare kapacitet er ukendt. Advarsler om diskforbrug for poolen er deaktiveret."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Se <0>dokumentationen</0> for instruktioner."
msgid "Please sign in to your account"
msgstr "Log venligst ind på din konto"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Poolstatus"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Poolforbrug"
@@ -1416,7 +1420,7 @@ msgstr "Proces startet"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Offentlig nøgle"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Kødybde"
msgid "Quiet Hours"
msgstr "Stille timer"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Rå"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Råt forbrug af lagerpool {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Stille timer"
msgid "Read"
msgstr "Læs"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Læsefejl"
@@ -1454,7 +1469,7 @@ msgstr "Modtaget"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Opdater"
@@ -1643,7 +1658,7 @@ msgstr "Starttid"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Tilstand"
@@ -1671,7 +1686,7 @@ msgstr "Swap forbrug"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Skift tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "System"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Systemblæserhastigheder (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Dette vil permanent slette alle poster fra databasen."
msgid "Throughput of {extraFsName}"
msgstr "Gennemløb af {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Gennemløb for ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Gennemløb af lagerpool {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Samlet sendt data for hver interface"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Samlet tid brugt på læsning/skrivning (kan overstige 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Udløser når brugen af en disk overstiger en tærskel"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Type"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universalnøgle"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Ukendt"
@@ -1945,7 +1961,7 @@ msgstr "Opdater"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Opdateret"
@@ -1968,20 +1984,20 @@ msgstr "Oppetid"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Forbrug"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Forbrug af ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Forbrug af lagerpool {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Brugt"
@@ -2058,7 +2074,7 @@ msgstr "Windows-kommando"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows-kommando"
msgid "Write"
msgstr "Skriv"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Skrivefejl"
@@ -2087,3 +2103,4 @@ msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dine brugerindstillinger er opdateret."
+55 -38
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 20:36\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 Min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Aktionen"
@@ -196,7 +196,7 @@ msgstr "Bist du sicher?"
msgid "Automatic copy requires a secure context."
msgstr "Automatisches Kopieren erfordert einen sicheren Kontext."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Verfügbar"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Fähigkeiten"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapazität"
@@ -391,14 +391,14 @@ msgstr "Überprüfen Sie Ihren Überwachungsdienst"
msgid "Check your notification service"
msgstr "Überprüfe deinen Benachrichtigungsdienst"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Prüfsummenfehler"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Löschen"
@@ -411,7 +411,7 @@ msgstr "Klicke auf einen Container, um weitere Informationen zu sehen."
msgid "Click on a device to view more information."
msgstr "Klicke auf ein Gerät, um weitere Informationen zu sehen."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klicke auf einen Pool, um Details zu vdevs und Datensätzen anzuzeigen."
@@ -875,8 +875,8 @@ msgstr "Lüfter"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Für <0>{min}</0> {min, plural, one {Minute} other {Minuten}}"
msgid "Forgot password?"
msgstr "Passwort vergessen?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Frei"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Raster"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Gesundheit"
@@ -1146,7 +1146,7 @@ msgstr "Speichernutzung der Container"
msgid "Model"
msgstr "Modell"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Einhängepunkt"
@@ -1185,7 +1185,7 @@ msgstr "Netzwerkeinheit"
msgid "No"
msgstr "Nein"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Für diesen Pool sind keine Detaildaten verfügbar."
@@ -1212,7 +1212,7 @@ msgstr "Für dieses Gerät sind keine S.M.A.R.T.-Attribute verfügbar."
msgid "No systems found."
msgstr "Keine Systeme gefunden."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Keine"
@@ -1255,7 +1255,7 @@ msgstr "Einmalpasswort"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Menü öffnen"
@@ -1346,6 +1346,10 @@ msgstr "Dauerhaft"
msgid "Persistence"
msgstr "Persistenz"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Physischer Gerätespeicherplatz. Die tatsächlich nutzbare Kapazität ist unbekannt. Warnungen zur Pool-Festplattennutzung sind deaktiviert."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "In der <0>Dokumentation</0> findest du weitere Anweisungen."
msgid "Please sign in to your account"
msgstr "Bitte melde dich bei deinem Konto an"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pool-Zustand"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Pool-Auslastung"
@@ -1432,10 +1436,21 @@ msgstr "Warteschlangentiefe"
msgid "Quiet Hours"
msgstr "Ruhezeiten"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Roh"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Rohauslastung des Pools {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Ruhezeiten"
msgid "Read"
msgstr "Lesen"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Lesefehler"
@@ -1454,7 +1469,7 @@ msgstr "Empfangen"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Aktualisieren"
@@ -1643,7 +1658,7 @@ msgstr "Startzeit"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Status"
@@ -1690,7 +1705,7 @@ msgstr "System"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Systemlüftergeschwindigkeiten (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Dadurch werden alle ausgewählten Datensätze dauerhaft aus der Datenban
msgid "Throughput of {extraFsName}"
msgstr "Durchsatz von {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Durchsatz des ZFS-Pools {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Durchsatz des Pools {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Löst aus, wenn die Nutzung einer Festplatte einen Schwellenwert übersc
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Typ"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universeller Token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Unbekannt"
@@ -1945,7 +1961,7 @@ msgstr "Aktualisieren"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aktualisiert"
@@ -1968,20 +1984,20 @@ msgstr "Betriebszeit"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Nutzung"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Auslastung des ZFS-Pools {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Auslastung des Pools {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Verwendet"
@@ -2058,7 +2074,7 @@ msgstr "Windows-Befehl"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows-Befehl"
msgid "Write"
msgstr "Schreiben"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Schreibfehler"
@@ -2087,3 +2103,4 @@ msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Deine Benutzereinstellungen wurden aktualisiert."
+57 -40
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: el\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Greek\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 λ"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Ενέργειες"
@@ -196,7 +196,7 @@ msgstr "Είστε βέβαιοι;"
msgid "Automatic copy requires a secure context."
msgstr "Η αυτόματη αντιγραφή απαιτεί ασφαλές περιβάλλον."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Διαθέσιμο"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Δυνατότητες"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Χωρητικότητα"
@@ -391,14 +391,14 @@ msgstr "Ελέγξτε την υπηρεσία παρακολούθησής σα
msgid "Check your notification service"
msgstr "Ελέγξτε την υπηρεσία ειδοποιήσεών σας"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Σφάλματα αθροίσματος ελέγχου"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Εκκαθάριση"
@@ -411,7 +411,7 @@ msgstr "Κάντε κλικ σε ένα κοντέινερ για να δείτ
msgid "Click on a device to view more information."
msgstr "Κάντε κλικ σε μια συσκευή για να δείτε περισσότερες πληροφορίες."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Κάντε κλικ σε ένα pool για να δείτε λεπτομέρειες για τα vdev και τα σύνολα δεδομένων."
@@ -447,11 +447,11 @@ msgstr "Η σύνδεση είναι εκτός λειτουργίας"
#: src/lib/alerts.ts
msgid "Container"
msgstr ""
msgstr "Κοντέινερ"
#: src/lib/alerts.ts
msgid "Container Health"
msgstr ""
msgstr "Υγεία κοντέινερ"
#: src/components/routes/system.tsx
msgid "Containers"
@@ -875,8 +875,8 @@ msgstr "Ανεμιστήρες"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Για <0>{min}</0> {min, plural, one {λεπτό} other {λεπτά}}"
msgid "Forgot password?"
msgstr "Ξεχάσατε τον κωδικό πρόσβασης;"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Ελεύθερο"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Πλέγμα"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Υγεία"
@@ -1146,7 +1146,7 @@ msgstr "Χρήση μνήμης των κοντέινερ"
msgid "Model"
msgstr "Μοντέλο"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Σημείο προσάρτησης"
@@ -1185,7 +1185,7 @@ msgstr "Μονάδα δικτύου"
msgid "No"
msgstr "Όχι"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Δεν υπάρχουν λεπτομερή δεδομένα για αυτό το pool."
@@ -1212,7 +1212,7 @@ msgstr "Δεν υπάρχουν διαθέσιμα χαρακτηριστικά
msgid "No systems found."
msgstr "Δεν βρέθηκαν συστήματα."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Κανένα"
@@ -1255,7 +1255,7 @@ msgstr "Κωδικός μίας χρήσης"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Άνοιγμα μενού"
@@ -1346,6 +1346,10 @@ msgstr "Μόνιμο"
msgid "Persistence"
msgstr "Διατήρηση"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Φυσικός χώρος συσκευής. Η πραγματική ωφέλιμη χωρητικότητα είναι άγνωστη. Οι ειδοποιήσεις χρήσης δίσκων του pool είναι απενεργοποιημένες."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Παρακαλώ <0>ρυθμίστε έναν διακομιστή SMTP</0> για να διασφαλίσετε την παράδοση των ειδοποιήσεων."
@@ -1379,11 +1383,11 @@ msgstr "Ανατρέξτε στην <0>τεκμηρίωση</0> για οδηγ
msgid "Please sign in to your account"
msgstr "Συνδεθείτε στον λογαριασμό σας"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Κατάσταση pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Χρήση pool"
@@ -1432,10 +1436,21 @@ msgstr "Βάθος ουράς"
msgid "Quiet Hours"
msgstr "Ώρες σίγασης"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Ακατέργαστο"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Ακατέργαστη χρήση του pool αποθήκευσης {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Ώρες σίγασης"
msgid "Read"
msgstr "Ανάγνωση"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Σφάλματα ανάγνωσης"
@@ -1454,7 +1469,7 @@ msgstr "Λήφθηκαν"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Ανανέωση"
@@ -1643,7 +1658,7 @@ msgstr "Ώρα έναρξης"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Κατάσταση"
@@ -1772,9 +1787,9 @@ msgstr "Αυτό θα διαγράψει οριστικά όλες τις επι
msgid "Throughput of {extraFsName}"
msgstr "Ρυθμός μεταφοράς του {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Ρυθμός διαμεταγωγής του ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Ρυθμός μεταφοράς του pool αποθήκευσης {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,12 +1912,13 @@ msgstr "Ενεργοποιείται όταν η χρήση οποιουδήπο
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Τύπος"
#: src/lib/alerts.ts
msgid "Unhealthy"
msgstr ""
msgstr "Μη υγιές"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Καθολικό διακριτικό"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Άγνωστο"
@@ -1945,7 +1961,7 @@ msgstr "Ενημέρωση"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Ενημερώθηκε"
@@ -1968,20 +1984,20 @@ msgstr "Χρόνος λειτουργίας"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Χρήση"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Χρήση του ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Χρήση του pool αποθήκευσης {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Χρησιμοποιείται"
@@ -2058,7 +2074,7 @@ msgstr "Εντολή Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Εντολή Windows"
msgid "Write"
msgstr "Εγγραφή"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Σφάλματα εγγραφής"
@@ -2087,3 +2103,4 @@ msgstr "Ναι"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Οι ρυθμίσεις χρήστη σας ενημερώθηκαν."
+52 -36
View File
@@ -92,7 +92,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Actions"
@@ -191,7 +191,7 @@ msgstr "Are you sure?"
msgid "Automatic copy requires a secure context."
msgstr "Automatic copy requires a secure context."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Available"
@@ -333,7 +333,7 @@ msgid "Capabilities"
msgstr "Capabilities"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacity"
@@ -386,14 +386,14 @@ msgstr "Check your monitoring service"
msgid "Check your notification service"
msgstr "Check your notification service"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Checksum errors"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Clear"
@@ -406,7 +406,7 @@ msgstr "Click on a container to view more information."
msgid "Click on a device to view more information."
msgstr "Click on a device to view more information."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Click on a pool to view vdev and dataset details."
@@ -870,8 +870,8 @@ msgstr "Fans"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -893,8 +893,8 @@ msgstr "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgid "Forgot password?"
msgstr "Forgot password?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Free"
@@ -943,7 +943,7 @@ msgid "Grid"
msgstr "Grid"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Health"
@@ -1141,7 +1141,7 @@ msgstr "Memory usage of containers"
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Mountpoint"
@@ -1180,7 +1180,7 @@ msgstr "Network unit"
msgid "No"
msgstr "No"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "No detail data for this pool."
@@ -1207,7 +1207,7 @@ msgstr "No S.M.A.R.T. attributes available for this device."
msgid "No systems found."
msgstr "No systems found."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "None"
@@ -1250,7 +1250,7 @@ msgstr "One-time password"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Open menu"
@@ -1341,6 +1341,10 @@ msgstr "Permanent"
msgid "Persistence"
msgstr "Persistence"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1374,11 +1378,11 @@ msgstr "Please see <0>the documentation</0> for instructions."
msgid "Please sign in to your account"
msgstr "Please sign in to your account"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pool Health"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Pool Usage"
@@ -1427,10 +1431,21 @@ msgstr "Queue Depth"
msgid "Quiet Hours"
msgstr "Quiet Hours"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Raw"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Raw usage of storage pool {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1438,7 +1453,7 @@ msgstr "Quiet Hours"
msgid "Read"
msgstr "Read"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Read errors"
@@ -1449,7 +1464,7 @@ msgstr "Received"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Refresh"
@@ -1638,7 +1653,7 @@ msgstr "Start Time"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "State"
@@ -1767,9 +1782,9 @@ msgstr "This will permanently delete all selected records from the database."
msgid "Throughput of {extraFsName}"
msgstr "Throughput of {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Throughput of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Throughput of storage pool {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1892,6 +1907,7 @@ msgstr "Triggers when usage of any disk exceeds a threshold"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Type"
@@ -1914,7 +1930,7 @@ msgid "Universal token"
msgstr "Universal token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Unknown"
@@ -1940,7 +1956,7 @@ msgstr "Update"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Updated"
@@ -1963,20 +1979,20 @@ msgstr "Uptime"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Usage"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Usage of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Usage of storage pool {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Used"
@@ -2053,7 +2069,7 @@ msgstr "Windows command"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2061,7 +2077,7 @@ msgstr "Windows command"
msgid "Write"
msgstr "Write"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Write errors"
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: es\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Acciones"
@@ -196,7 +196,7 @@ msgstr "¿Estás seguro?"
msgid "Automatic copy requires a secure context."
msgstr "La copia automática requiere un contexto seguro."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Disponible"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Capacidades"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacidad"
@@ -391,14 +391,14 @@ msgstr "Compruebe su servicio de monitorización"
msgid "Check your notification service"
msgstr "Verifica tu servicio de notificaciones"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Errores de suma de comprobación"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Limpiar"
@@ -411,7 +411,7 @@ msgstr "Haz clic en un contenedor para ver más información."
msgid "Click on a device to view more information."
msgstr "Haz clic en un dispositivo para ver más información."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Haz clic en un pool para ver los detalles de los vdev y los conjuntos de datos."
@@ -503,7 +503,7 @@ msgstr "Copiar nombre"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Copiar clave pública"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Fallidos: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventiladores"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Por <0>{min}</0> {min, plural, one {minuto} other {minutos}}"
msgid "Forgot password?"
msgstr "¿Olvidaste tu contraseña?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Libre"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Cuadrícula"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Estado"
@@ -1146,7 +1146,7 @@ msgstr "Uso de memoria de los contenedores"
msgid "Model"
msgstr "Modelo"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Punto de montaje"
@@ -1185,7 +1185,7 @@ msgstr "Unidad de red"
msgid "No"
msgstr "No"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "No hay datos detallados para este pool."
@@ -1212,7 +1212,7 @@ msgstr "No hay atributos S.M.A.R.T. disponibles para este dispositivo."
msgid "No systems found."
msgstr "No se encontraron sistemas."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Ninguno"
@@ -1255,7 +1255,7 @@ msgstr "Contraseña de un solo uso"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Abrir menú"
@@ -1346,6 +1346,10 @@ msgstr "Permanente"
msgid "Persistence"
msgstr "Persistencia"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Espacio físico del dispositivo. La capacidad útil real se desconoce. Las alertas de uso de disco del pool están desactivadas."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Por favor, consulta <0>la documentación</0> para obtener instrucciones.
msgid "Please sign in to your account"
msgstr "Por favor, inicia sesión en tu cuenta"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Estado del pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Uso del pool"
@@ -1416,7 +1420,7 @@ msgstr "Proceso iniciado"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Clave pública"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Profundidad de cola"
msgid "Quiet Hours"
msgstr "Horas de silencio"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Bruto"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Uso bruto del pool de almacenamiento {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Horas de silencio"
msgid "Read"
msgstr "Lectura"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Errores de lectura"
@@ -1454,7 +1469,7 @@ msgstr "Recibido"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Actualizar"
@@ -1643,7 +1658,7 @@ msgstr "Hora de inicio"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Estado"
@@ -1671,7 +1686,7 @@ msgstr "Uso de swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Cambiar tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistema"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Velocidades de los ventiladores del sistema (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Esto eliminará permanentemente todos los registros seleccionados de la
msgid "Throughput of {extraFsName}"
msgstr "Rendimiento de {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Rendimiento del pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Rendimiento del pool de almacenamiento {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Datos totales enviados por cada interfaz"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Tiempo total dedicado a lectura/escritura (puede superar el 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Se activa cuando el uso de cualquier disco supera un umbral"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tipo"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token universal"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Desconocida"
@@ -1945,7 +1961,7 @@ msgstr "Actualizar"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Actualizado"
@@ -1968,20 +1984,20 @@ msgstr "Tiempo de actividad"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Uso"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Uso del pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Uso del pool de almacenamiento {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Usado"
@@ -2058,7 +2074,7 @@ msgstr "Comando Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Comando Windows"
msgid "Write"
msgstr "Escritura"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Errores de escritura"
@@ -2087,3 +2103,4 @@ msgstr "Sí"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Tu configuración de usuario ha sido actualizada."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fa\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: Persian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "۵ دقیقه"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "عملیات"
@@ -196,7 +196,7 @@ msgstr "آیا مطمئن هستید؟"
msgid "Automatic copy requires a secure context."
msgstr "کپی خودکار نیاز به یک زمینه امن دارد."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "در دسترس"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "قابلیت‌ها"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "ظرفیت"
@@ -391,14 +391,14 @@ msgstr "سرویس نظارتی خود را بررسی کنید"
msgid "Check your notification service"
msgstr "سرویس اطلاع‌رسانی خود را بررسی کنید"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "خطاهای مجموع بررسی"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "پاک کردن"
@@ -411,7 +411,7 @@ msgstr "برای مشاهده اطلاعات بیشتر روی کانتینر ک
msgid "Click on a device to view more information."
msgstr "برای مشاهده اطلاعات بیشتر روی دستگاه کلیک کنید."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "برای مشاهده جزئیات vdev و مجموعه‌داده‌ها روی یک استخر کلیک کنید."
@@ -503,7 +503,7 @@ msgstr "کپی نام"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "کپی کردن کلید عمومی"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "ناموفق: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "فن‌ها"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "برای <0>{min}</0> {min, plural, one {دقیقه} other {دقیقه}}
msgid "Forgot password?"
msgstr "رمز عبور را فراموش کرده‌اید؟"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "آزاد"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "جدول"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "سلامتی"
@@ -1146,7 +1146,7 @@ msgstr "میزان استفاده حافظه کانتینرها"
msgid "Model"
msgstr "مدل"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "نقطه اتصال"
@@ -1185,7 +1185,7 @@ msgstr "واحد شبکه"
msgid "No"
msgstr "خیر"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "دادهٔ جزئی برای این استخر موجود نیست."
@@ -1212,7 +1212,7 @@ msgstr "هیچ ویژگی S.M.A.R.T برای این دستگاه موجود نی
msgid "No systems found."
msgstr "هیچ سیستمی یافت نشد."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "هیچ‌کدام"
@@ -1255,7 +1255,7 @@ msgstr "رمز عبور یک‌بار مصرف"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "باز کردن منو"
@@ -1346,6 +1346,10 @@ msgstr "دائمی"
msgid "Persistence"
msgstr "ماندگاری"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "فضای فیزیکی دستگاه. ظرفیت واقعی قابل استفاده نامشخص است. هشدارهای استفاده از دیسک استخر غیرفعال هستند."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "لطفاً برای اطمینان از تحویل هشدارها، یک <0>سرور SMTP پیکربندی کنید</0>."
@@ -1379,11 +1383,11 @@ msgstr "لطفاً برای دستورالعمل‌ها به <0>مستندات</
msgid "Please sign in to your account"
msgstr "لطفاً به حساب کاربری خود وارد شوید"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "سلامت استخر"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "استفاده از استخر"
@@ -1416,7 +1420,7 @@ msgstr "فرآیند شروع شد"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "کلید عمومی"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "عمق صف"
msgid "Quiet Hours"
msgstr "ساعات آرام"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "خام"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "استفاده خام از استخر ذخیره‌سازی {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "ساعات آرام"
msgid "Read"
msgstr "خواندن"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "خطاهای خواندن"
@@ -1454,7 +1469,7 @@ msgstr "دریافت شد"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "تازه‌سازی"
@@ -1643,7 +1658,7 @@ msgstr "زمان شروع"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "وضعیت"
@@ -1671,7 +1686,7 @@ msgstr "میزان استفاده از Swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "تغییر تم"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "سیستم"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "سرعت فن‌های سیستم (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "این کار تمام رکوردهای انتخاب شده را برا
msgid "Throughput of {extraFsName}"
msgstr "توان عملیاتی {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "توان عملیاتی استخر ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "توان عملیاتی استخر ذخیره‌سازی {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "داده‌های کل ارسال شده برای هر رابط"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "کل زمان صرف‌شده برای خواندن/نوشتن (ممکن است از ۱۰۰٪ بیشتر شود)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "هنگامی که استفاده از هر دیسکی از یک آستا
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "نوع"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "توکن جهانی"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "ناشناخته"
@@ -1945,7 +1961,7 @@ msgstr "به‌روزرسانی"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "به‌روزرسانی شد"
@@ -1968,20 +1984,20 @@ msgstr "آپتایم"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "میزان استفاده"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "استفاده از استخر ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "استفاده از استخر ذخیره‌سازی {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "استفاده شده"
@@ -2058,7 +2074,7 @@ msgstr "دستور Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "دستور Windows"
msgid "Write"
msgstr "نوشتن"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "خطاهای نوشتن"
@@ -2087,3 +2103,4 @@ msgstr "بله"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تنظیمات کاربری شما به‌روزرسانی شد."
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:42\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Actions"
@@ -196,7 +196,7 @@ msgstr "Êtes-vous sûr ?"
msgid "Automatic copy requires a secure context."
msgstr "La copie automatique nécessite un contexte sécurisé."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Disponible"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Capacités"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacité"
@@ -391,14 +391,14 @@ msgstr "Vérifiez votre service de surveillance"
msgid "Check your notification service"
msgstr "Vérifiez votre service de notification"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Erreurs de somme de contrôle"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Effacer"
@@ -411,7 +411,7 @@ msgstr "Cliquez sur un conteneur pour voir plus d'informations."
msgid "Click on a device to view more information."
msgstr "Cliquez sur un appareil pour voir plus d'informations."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Cliquez sur un pool pour afficher les détails des vdev et des jeux de données."
@@ -503,7 +503,7 @@ msgstr "Copier le nom"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Copier la clé publique"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Échec : {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilateurs"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Pendant <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgid "Forgot password?"
msgstr "Mot de passe oublié ?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Espace libre"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Grille"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Santé"
@@ -1146,7 +1146,7 @@ msgstr "Utilisation de la mémoire des conteneurs"
msgid "Model"
msgstr "Modèle"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Point de montage"
@@ -1185,7 +1185,7 @@ msgstr "Unité réseau"
msgid "No"
msgstr "Non"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Aucune donnée détaillée disponible pour ce pool."
@@ -1212,7 +1212,7 @@ msgstr "Aucun attribut S.M.A.R.T. disponible pour cet appareil."
msgid "No systems found."
msgstr "Aucun système trouvé."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Aucun"
@@ -1255,7 +1255,7 @@ msgstr "Mot de passe à usage unique"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Ouvrir le menu"
@@ -1346,6 +1346,10 @@ msgstr "Permanent"
msgid "Persistence"
msgstr "Persistance"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Espace physique de l'appareil. La capacité réellement utilisable est inconnue. Les alertes d'utilisation des disques du pool sont désactivées."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Veuillez consulter <0>la documentation</0> pour les instructions."
msgid "Please sign in to your account"
msgstr "Veuillez vous connecter à votre compte"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "État du pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Utilisation du pool"
@@ -1416,7 +1420,7 @@ msgstr "Processus démarré"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Clé publique"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Profondeur de file d'attente"
msgid "Quiet Hours"
msgstr "Heures calmes"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Brut"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Utilisation brute du pool de stockage {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Heures calmes"
msgid "Read"
msgstr "Lecture"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Erreurs de lecture"
@@ -1454,7 +1469,7 @@ msgstr "Reçu"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Actualiser"
@@ -1643,7 +1658,7 @@ msgstr "Heure de début"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "État"
@@ -1671,7 +1686,7 @@ msgstr "Utilisation du swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Changer de thème"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Système"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Vitesses des ventilateurs du système (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Ceci supprimera définitivement tous les enregistrements sélectionnés
msgid "Throughput of {extraFsName}"
msgstr "Débit de {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Débit du pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Débit du pool de stockage {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Déclenchement lorsque l'utilisation de tout disque dépasse un seuil"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Type"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token universel"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Inconnue"
@@ -1945,7 +1961,7 @@ msgstr "Mettre à jour"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Mis à jour"
@@ -1968,20 +1984,20 @@ msgstr "Temps de fonctionnement"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Utilisation"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Utilisation du pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Utilisation du pool de stockage {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Utilisé"
@@ -2058,7 +2074,7 @@ msgstr "Commande Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Commande Windows"
msgid "Write"
msgstr "Écriture"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Erreurs d’écriture"
@@ -2087,3 +2103,4 @@ msgstr "Oui"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vos paramètres utilisateur ont été mis à jour."
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: he\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Hebrew\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);\n"
@@ -97,7 +97,7 @@ msgstr "5 דק'"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "פעולות"
@@ -196,7 +196,7 @@ msgstr "האם אתה בטוח?"
msgid "Automatic copy requires a secure context."
msgstr "העתקה אוטומטית דורשת הקשר מאובטח."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "זמין"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "יכולות"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "קיבולת"
@@ -391,14 +391,14 @@ msgstr "בדוק את שירות הניטור שלך"
msgid "Check your notification service"
msgstr "בדוק את שירות ההתראות שלך"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "שגיאות סכום ביקורת"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "נקה"
@@ -411,7 +411,7 @@ msgstr "לחץ על קונטיינר כדי לצפות במידע נוסף."
msgid "Click on a device to view more information."
msgstr "לחץ על התקן כדי לצפות במידע נוסף."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "לחצו על מאגר כדי להציג פרטי vdev ומערכי נתונים."
@@ -503,7 +503,7 @@ msgstr "העתק שם"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "העתק מפתח ציבורי"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "נכשל: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "מאווררים"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "למשך <0>{min}</0> {min, plural, one {דקה} other {דקות}}"
msgid "Forgot password?"
msgstr "שכחת סיסמה?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "פנוי"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "רשת"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "בריאות"
@@ -1146,7 +1146,7 @@ msgstr "שימוש בזיכרון של קונטיינרים"
msgid "Model"
msgstr "דגם"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "נקודת עגינה"
@@ -1185,7 +1185,7 @@ msgstr "יחידת רשת"
msgid "No"
msgstr "לא"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "אין נתונים מפורטים עבור מאגר זה."
@@ -1212,7 +1212,7 @@ msgstr "אין מאפייני S.M.A.R.T. זמינים עבור התקן זה."
msgid "No systems found."
msgstr "לא נמצאו מערכות."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "ללא"
@@ -1255,7 +1255,7 @@ msgstr "סיסמה חד-פעמית"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "פתח תפריט"
@@ -1346,6 +1346,10 @@ msgstr "קבוע"
msgid "Persistence"
msgstr "עקביות"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "שטח פיזי של ההתקן. הקיבולת האמיתית הניתנת לשימוש אינה ידועה. התראות השימוש בדיסקים של המאגר מושבתות."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "אנא <0>הגדר שרת SMTP</0> כדי להבטיח שהתראות יישלחו."
@@ -1379,11 +1383,11 @@ msgstr "אנא ראה <0>את התיעוד</0> להוראות."
msgid "Please sign in to your account"
msgstr "אנא התחבר לחשבון שלך"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "מצב המאגר"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "שימוש במאגר"
@@ -1416,7 +1420,7 @@ msgstr "תהליך התחיל"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "מפתח ציבורי"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "עומק תור"
msgid "Quiet Hours"
msgstr "שעות שקט"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "גולמי"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "שימוש גולמי במאגר האחסון {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "שעות שקט"
msgid "Read"
msgstr "קריאה"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "שגיאות קריאה"
@@ -1454,7 +1469,7 @@ msgstr "התקבל"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "רענן"
@@ -1643,7 +1658,7 @@ msgstr "זמן התחלה"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "מצב"
@@ -1671,7 +1686,7 @@ msgstr "שימוש ב-Swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "החלף ערכת נושא"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "מערכת"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "מהירויות מאווררי המערכת (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "פעולה זו תמחק לצמיתות את כל הרשומות שנב
msgid "Throughput of {extraFsName}"
msgstr "תפוקה של {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "תפוקת מאגר ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "תפוקה של מאגר האחסון {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "מופעל כאשר שימוש בכל דיסק עולה על סף"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "סוג"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "token אוניברסלי"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "לא ידוע"
@@ -1945,7 +1961,7 @@ msgstr "עדכן"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "עודכן"
@@ -1968,20 +1984,20 @@ msgstr "זמן פעילות"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "שימוש"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "שימוש במאגר ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "שימוש במאגר האחסון {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "בשימוש"
@@ -2058,7 +2074,7 @@ msgstr "פקודת Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "פקודת Windows"
msgid "Write"
msgstr "כתיבה"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "שגיאות כתיבה"
@@ -2087,3 +2103,4 @@ msgstr "כן"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "הגדרות המשתמש שלך עודכנו."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: hr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 minuta"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Akcije"
@@ -196,7 +196,7 @@ msgstr "Jeste li sigurni?"
msgid "Automatic copy requires a secure context."
msgstr "Automatsko kopiranje zahtijeva siguran kontekst."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Dostupno"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Mogućnosti"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapacitet"
@@ -391,14 +391,14 @@ msgstr "Provjerite svoju uslugu nadzora"
msgid "Check your notification service"
msgstr "Provjerite svoju obavještajnu uslugu"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Pogreške kontrolnog zbroja"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Očisti"
@@ -411,7 +411,7 @@ msgstr "Kliknite na spremnik za prikaz više informacija."
msgid "Click on a device to view more information."
msgstr "Kliknite na uređaj da biste vidjeli više informacija."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Kliknite na spremište za prikaz pojedinosti o vdevovima i skupovima podataka."
@@ -503,7 +503,7 @@ msgstr "Kopiraj naziv"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopiraj javni ključ"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Neuspjelo: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilatori"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Za <0>{min}</0> {min, plural, one {minutu} other {minute}}"
msgid "Forgot password?"
msgstr "Zaboravljena lozinka?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Slobodno"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Rešetka"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Zdravlje"
@@ -1146,7 +1146,7 @@ msgstr "Upotreba memorije spremnika"
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Točka montiranja"
@@ -1185,7 +1185,7 @@ msgstr "Mjerna jedinica za mrežu"
msgid "No"
msgstr "Ne"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Nema detaljnih podataka za ovo spremište."
@@ -1212,7 +1212,7 @@ msgstr "Nema dostupnih S.M.A.R.T. atributa za ovaj uređaj."
msgid "No systems found."
msgstr "Nije pronađen nijedan sustav."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Nema"
@@ -1255,7 +1255,7 @@ msgstr "Jednokratna lozinka"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Otvori meni"
@@ -1346,6 +1346,10 @@ msgstr "Trajan"
msgid "Persistence"
msgstr "Postojanost"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fizički prostor uređaja. Stvarni iskoristivi kapacitet nije poznat. Upozorenja o iskorištenosti diskova spremišta su onemogućena."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Molimo provjerite <0>dokumentaciju</0> za upute."
msgid "Please sign in to your account"
msgstr "Molimo prijavite se u svoj račun"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Stanje spremišta"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Iskorištenost spremišta"
@@ -1416,7 +1420,7 @@ msgstr "Proces pokrenut"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Javni ključ"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Dubina reda"
msgid "Quiet Hours"
msgstr "Tihi sati"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Sirovo"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Sirova iskorištenost spremišta {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Tihi sati"
msgid "Read"
msgstr "Pročitaj"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Pogreške čitanja"
@@ -1454,7 +1469,7 @@ msgstr "Primljeno"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Osvježi"
@@ -1643,7 +1658,7 @@ msgstr "Vrijeme početka"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stanje"
@@ -1671,7 +1686,7 @@ msgstr "Swap Iskorištenost"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Promijeni temu"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sustav"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Brzine ventilatora sustava (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Ovom radnjom će se trajno izbrisati svi odabrani zapisi iz baze podatak
msgid "Throughput of {extraFsName}"
msgstr "Protok {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Propusnost ZFS spremišta {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Protok spremišta {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Ukupni podaci poslani za svako sučelje"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Ukupno vrijeme utrošeno na čitanje/pisanje (može prelaziti 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Pokreće se kada iskorištenost bilo kojeg diska premaši prag"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Vrsta"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Sveopći token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Nepoznato"
@@ -1945,7 +1961,7 @@ msgstr "Ažuriraj"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Ažurirano"
@@ -1968,20 +1984,20 @@ msgstr "Vrijeme rada"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Iskorištenost"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Iskorištenost ZFS spremišta {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Iskorištenost spremišta {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Iskorišteno"
@@ -2058,7 +2074,7 @@ msgstr "Windows naredba"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows naredba"
msgid "Write"
msgstr "Piši"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Pogreške zapisivanja"
@@ -2087,3 +2103,4 @@ msgstr "Da"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše korisničke postavke su ažurirane."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: hu\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 perc"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Műveletek"
@@ -196,7 +196,7 @@ msgstr "Biztos vagy benne?"
msgid "Automatic copy requires a secure context."
msgstr "Az automatikus másolás biztonságos környezetet igényel."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Elérhető"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Képességek"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapacitás"
@@ -391,14 +391,14 @@ msgstr "Ellenőrizze a megfigyelő szolgáltatást"
msgid "Check your notification service"
msgstr "Ellenőrizd az értesítési szolgáltatásodat"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Ellenőrzőösszeg-hibák"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Törlés"
@@ -411,7 +411,7 @@ msgstr "Kattintson egy konténerre a további információk megtekintéséhez."
msgid "Click on a device to view more information."
msgstr "Kattintson egy eszközre további információk megtekintéséhez."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Kattintson egy tárkészletre a vdev- és adatkészlet-részletek megtekintéséhez."
@@ -503,7 +503,7 @@ msgstr "Név másolása"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Nyilvános kulcs másolása"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Sikertelen: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilátorok"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "<0>{min}</0> {min, plural, one {percig} other {percig}}"
msgid "Forgot password?"
msgstr "Elfelejtette a jelszavát?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Szabad"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Rács"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Egészség"
@@ -1146,7 +1146,7 @@ msgstr "Konténerek memóriahasználata"
msgid "Model"
msgstr "Modell"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Csatolási pont"
@@ -1185,7 +1185,7 @@ msgstr "Sávszélesség mértékegysége"
msgid "No"
msgstr "Nem"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Ehhez a tárkészlethez nem érhetők el részletes adatok."
@@ -1212,7 +1212,7 @@ msgstr "Ehhez az eszközhöz nem állnak rendelkezésre S.M.A.R.T. attribútumok
msgid "No systems found."
msgstr "Nem található rendszer."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Nincs"
@@ -1255,7 +1255,7 @@ msgstr "Egyszeri jelszó"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Menü megnyitása"
@@ -1346,6 +1346,10 @@ msgstr "Állandó"
msgid "Persistence"
msgstr "Tartósság"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fizikai eszközterület. A valódi használható kapacitás ismeretlen. A készlet lemezhasználati riasztásai le vannak tiltva."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Kérjük, nézze meg <0>a dokumentációt</0> az utasításokért."
msgid "Please sign in to your account"
msgstr "Kérjük, jelentkezzen be a fiókjába"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Tárkészlet állapota"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Tárkészlet kihasználtsága"
@@ -1416,7 +1420,7 @@ msgstr "Folyamat elindítva"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Nyilvános kulcs"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Várakozási sor mélysége"
msgid "Quiet Hours"
msgstr "Csendes órák"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Nyers"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "A(z) {displayName} tárolókészlet nyers kihasználtsága"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Csendes órák"
msgid "Read"
msgstr "Olvasás"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Olvasási hibák"
@@ -1454,7 +1469,7 @@ msgstr "Fogadott"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Frissítés"
@@ -1643,7 +1658,7 @@ msgstr "Kezdési idő"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Állapot"
@@ -1671,7 +1686,7 @@ msgstr "Swap használat"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Téma váltása"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Rendszer"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Rendszerventilátorok sebessége (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Ez véglegesen törli az összes kijelölt bejegyzést az adatbázisból
msgid "Throughput of {extraFsName}"
msgstr "A {extraFsName} átviteli teljesítménye"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "{poolName} ZFS-tárkészlet átviteli sebessége"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "A(z) {displayName} tárolókészlet átviteli teljesítménye"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Összes elküldött adat minden interfészenként"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Olvasással/írással töltött teljes idő (meghaladhatja a 100%-ot)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Riaszt, ha a lemezhasználat túllép egy küszöbértéket"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Típus"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Univerzális token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Ismeretlen"
@@ -1945,7 +1961,7 @@ msgstr "Frissítés"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Frissítve"
@@ -1968,20 +1984,20 @@ msgstr "Üzemidő"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Használat"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "{poolName} ZFS-tárkészlet kihasználtsága"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "A(z) {displayName} tárolókészlet kihasználtsága"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Felhasznált"
@@ -2058,7 +2074,7 @@ msgstr "Windows parancs"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows parancs"
msgid "Write"
msgstr "Írás"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Írási hibák"
@@ -2087,3 +2103,4 @@ msgstr "Igen"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "A felhasználói beállítások frissítésre kerültek."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: id\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: Indonesian\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5 mnt"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Aksi"
@@ -196,7 +196,7 @@ msgstr "Apakah anda yakin?"
msgid "Automatic copy requires a secure context."
msgstr "Copy memerlukan https."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Tersedia"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Kapabilitas"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapasitas"
@@ -391,14 +391,14 @@ msgstr "Periksa layanan pemantauan Anda"
msgid "Check your notification service"
msgstr "Periksa jasa penyedia notifikasi anda"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Kesalahan checksum"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Bersihkan"
@@ -411,7 +411,7 @@ msgstr "Klik pada kontainer untuk melihat informasi lebih banyak."
msgid "Click on a device to view more information."
msgstr "Klik pada perangkat untuk melihat informasi lebih banyak."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klik pool untuk melihat detail vdev dan dataset."
@@ -503,7 +503,7 @@ msgstr "Salin nama"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Salin kunci publik"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Gagal: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Kipas"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Untuk <0>{min}</0> {min, plural, one {menit} other {menit}}"
msgid "Forgot password?"
msgstr "Lupa kata sandi?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Kosong"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Kartu"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Kesehatan"
@@ -1146,7 +1146,7 @@ msgstr "Penggunaan memori container"
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Titik kait"
@@ -1185,7 +1185,7 @@ msgstr "Unit jaringan"
msgid "No"
msgstr "Tidak"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Tidak ada data terperinci yang tersedia untuk pool ini."
@@ -1212,7 +1212,7 @@ msgstr "Tidak ada atribut S.M.A.R.T. yang tersedia untuk perangkat ini."
msgid "No systems found."
msgstr "Sistem tidak ditemukan."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Tidak ada"
@@ -1255,7 +1255,7 @@ msgstr "Kata sandi sekali pakai (OTP)"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Buka menu"
@@ -1346,6 +1346,10 @@ msgstr "Permanen"
msgid "Persistence"
msgstr "Tetap berlaku"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Ruang perangkat fisik. Kapasitas sebenarnya yang dapat digunakan tidak diketahui. Peringatan penggunaan disk pool dinonaktifkan."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Silakan <0>konfigurasi server SMTP</0> untuk memastikan peringatan dikirimkan."
@@ -1379,11 +1383,11 @@ msgstr "Silakan lihat <0>dokumentasi</0> untuk instruksi."
msgid "Please sign in to your account"
msgstr "Silakan masuk ke akun anda"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Kesehatan pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Penggunaan pool"
@@ -1416,7 +1420,7 @@ msgstr "Proses dimulai"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Kunci publik"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Kedalaman Antrian"
msgid "Quiet Hours"
msgstr "Jam Tenang"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Mentah"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Penggunaan mentah pool penyimpanan {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Jam Tenang"
msgid "Read"
msgstr "Baca"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Kesalahan baca"
@@ -1454,7 +1469,7 @@ msgstr "Diterima"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Muat ulang"
@@ -1643,7 +1658,7 @@ msgstr "Waktu Mulai"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Status"
@@ -1671,7 +1686,7 @@ msgstr "Penggunaan Swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Ganti tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistem"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Kecepatan kipas sistem (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Ini akan menghapus secara permanen semua record yang dipilih dari databa
msgid "Throughput of {extraFsName}"
msgstr "Throughput dari {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Throughput pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Laju transfer pool penyimpanan {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Total data yang dikirim untuk setiap antarmuka"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Total waktu yang dihabiskan untuk baca/tulis (dapat melebihi 100%)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Dipicu ketika penggunaan disk apa pun melebihi ambang batas"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tipe"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token universal"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Tidak diketahui"
@@ -1945,7 +1961,7 @@ msgstr "Perbarui"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Diperbarui"
@@ -1968,20 +1984,20 @@ msgstr "Waktu aktif"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Penggunaan"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Penggunaan pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Penggunaan pool penyimpanan {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Digunakan"
@@ -2058,7 +2074,7 @@ msgstr "Perintah Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Perintah Windows"
msgid "Write"
msgstr "Tulis"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Kesalahan tulis"
@@ -2087,3 +2103,4 @@ msgstr "Ya"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Pengaturan pengguna anda telah diperbarui."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: it\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Italian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Azioni"
@@ -196,7 +196,7 @@ msgstr "Sei sicuro?"
msgid "Automatic copy requires a secure context."
msgstr "La copia automatica richiede un contesto sicuro."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Disponibile"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Funzionalità"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacità"
@@ -391,14 +391,14 @@ msgstr "Controlla il tuo servizio di monitoraggio"
msgid "Check your notification service"
msgstr "Controlla il tuo servizio di notifica"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Errori di checksum"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Cancella"
@@ -411,7 +411,7 @@ msgstr "Fare clic su un contenitore per visualizzare ulteriori informazioni."
msgid "Click on a device to view more information."
msgstr "Fare clic su un dispositivo per visualizzare più informazioni."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Fai clic su un pool per visualizzare i dettagli di vdev e dataset."
@@ -503,7 +503,7 @@ msgstr "Copia nome"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Copia chiave pubblica"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Fallito: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventole"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Per <0>{min}</0> {min, plural, one {minuto} other {minuti}}"
msgid "Forgot password?"
msgstr "Password dimenticata?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Libero"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Griglia"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Stato"
@@ -1146,7 +1146,7 @@ msgstr "Utilizzo della memoria dei container"
msgid "Model"
msgstr "Modello"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Punto di montaggio"
@@ -1185,7 +1185,7 @@ msgstr "Unità rete"
msgid "No"
msgstr "No"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Nessun dato dettagliato disponibile per questo pool."
@@ -1212,7 +1212,7 @@ msgstr "Nessun attributo S.M.A.R.T. disponibile per questo dispositivo."
msgid "No systems found."
msgstr "Nessun sistema trovato."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Nessuno"
@@ -1255,7 +1255,7 @@ msgstr "Password monouso"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Apri menu"
@@ -1346,6 +1346,10 @@ msgstr "Permanente"
msgid "Persistence"
msgstr "Persistenza"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Spazio fisico del dispositivo. La capacità effettiva utilizzabile è sconosciuta. Gli avvisi di utilizzo del disco del pool sono disabilitati."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Si prega di consultare <0>la documentazione</0> per le istruzioni."
msgid "Please sign in to your account"
msgstr "Si prega di accedere al proprio account"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Stato del pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Utilizzo del pool"
@@ -1416,7 +1420,7 @@ msgstr "Processo avviato"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Chiave pubblica"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Profondità coda"
msgid "Quiet Hours"
msgstr "Ore silenziose"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Grezzo"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Utilizzo grezzo del pool di archiviazione {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Ore silenziose"
msgid "Read"
msgstr "Lettura"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Errori di lettura"
@@ -1454,7 +1469,7 @@ msgstr "Ricevuto"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Aggiorna"
@@ -1643,7 +1658,7 @@ msgstr "Ora di inizio"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stato"
@@ -1671,7 +1686,7 @@ msgstr "Utilizzo Swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Cambia tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistema"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Velocità delle ventole di sistema (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Questo eliminerà permanentemente tutti i record selezionati dal databas
msgid "Throughput of {extraFsName}"
msgstr "Throughput di {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Throughput del pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Throughput del pool di archiviazione {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Dati totali inviati per ogni interfaccia"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Tempo totale dedicato a lettura/scrittura (può superare il 100%)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Attiva quando l'utilizzo di un disco supera una soglia"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tipo"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token universale"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Sconosciuta"
@@ -1945,7 +1961,7 @@ msgstr "Aggiorna"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aggiornato"
@@ -1968,20 +1984,20 @@ msgstr "Tempo di attività"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Utilizzo"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Utilizzo del pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Utilizzo del pool di archiviazione {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Utilizzato"
@@ -2058,7 +2074,7 @@ msgstr "Comando Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Comando Windows"
msgid "Write"
msgstr "Scrittura"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Errori di scrittura"
@@ -2087,3 +2103,4 @@ msgstr "Sì"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Le impostazioni utente sono state aggiornate."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ja\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Japanese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5分"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "アクション"
@@ -196,7 +196,7 @@ msgstr "よろしいですか?"
msgid "Automatic copy requires a secure context."
msgstr "自動コピーには安全なコンテキストが必要です。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "利用可能"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "機能"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "容量"
@@ -391,14 +391,14 @@ msgstr "監視サービスを確認する"
msgid "Check your notification service"
msgstr "通知サービスを確認してください"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "チェックサムエラー"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "クリア"
@@ -411,7 +411,7 @@ msgstr "詳細情報を表示するにはコンテナをクリックしてくだ
msgid "Click on a device to view more information."
msgstr "詳細情報を表示するにはデバイスをクリックしてください。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "プールをクリックして、vdev とデータセットの詳細を表示します。"
@@ -503,7 +503,7 @@ msgstr "名前をコピーする"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "公開鍵をコピー"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "失敗: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "ファン"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "<0>{min}</0> {min, plural, one {分} other {分}}の間"
msgid "Forgot password?"
msgstr "パスワードをお忘れですか?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "空き"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "グリッド"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "ヘルス"
@@ -1146,7 +1146,7 @@ msgstr "コンテナのメモリ使用量"
msgid "Model"
msgstr "モデル"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "マウントポイント"
@@ -1185,7 +1185,7 @@ msgstr "ネットワーク単位"
msgid "No"
msgstr "いいえ"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "このプールの詳細データはありません。"
@@ -1212,7 +1212,7 @@ msgstr "このデバイスのS.M.A.R.T.属性は利用できません。"
msgid "No systems found."
msgstr "システムが見つかりませんでした。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "なし"
@@ -1255,7 +1255,7 @@ msgstr "ワンタイムパスワード"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "メニューを開く"
@@ -1346,6 +1346,10 @@ msgstr "永久"
msgid "Persistence"
msgstr "永続性"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "物理デバイス容量。実際に使用可能な容量は不明です。プールのディスク使用量アラートは無効になっています。"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "アラートが配信されるように<0>SMTPサーバーを設定</0>してください。"
@@ -1379,11 +1383,11 @@ msgstr "手順については<0>ドキュメント</0>を参照してくださ
msgid "Please sign in to your account"
msgstr "アカウントにサインインしてください"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "プールの健全性"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "プール使用量"
@@ -1416,7 +1420,7 @@ msgstr "プロセス開始"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "公開鍵"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "キューの深さ"
msgid "Quiet Hours"
msgstr "サイレント時間"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "生"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "ストレージプール {displayName} の生使用量"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "サイレント時間"
msgid "Read"
msgstr "読み取り"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "読み取りエラー"
@@ -1454,7 +1469,7 @@ msgstr "受信"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "更新"
@@ -1643,7 +1658,7 @@ msgstr "開始時間"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "状態"
@@ -1671,7 +1686,7 @@ msgstr "スワップ使用量"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "テーマを切り替え"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "システム"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "システムファン速度 (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "これにより、選択したすべてのレコードがデータベー
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}のスループット"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS プール {poolName} のスループット"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "ストレージプール {displayName} のスループット"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "各インターフェースの総送信データ量"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "読み取り/書き込みに費やした合計時間 (100% を超える場合があります)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "ディスクの使用量がしきい値を超えたときにトリガー
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "タイプ"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "ユニバーサルトークン"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "不明"
@@ -1945,7 +1961,7 @@ msgstr "更新"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "更新済み"
@@ -1968,20 +1984,20 @@ msgstr "稼働時間"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "使用量"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS プール {poolName} の使用量"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "ストレージプール {displayName} の使用量"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "使用中"
@@ -2058,7 +2074,7 @@ msgstr "Windows コマンド"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows コマンド"
msgid "Write"
msgstr "書き込み"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "書き込みエラー"
@@ -2087,3 +2103,4 @@ msgstr "はい"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "ユーザー設定が更新されました。"
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ko\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5분"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "작업"
@@ -196,7 +196,7 @@ msgstr "확실합니까?"
msgid "Automatic copy requires a secure context."
msgstr "자동 복사는 안전한 컨텍스트가 필요합니다."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "사용 가능"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "권한"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "용량"
@@ -391,14 +391,14 @@ msgstr "모니터링 서비스 확인"
msgid "Check your notification service"
msgstr "알림 서비스를 확인하세요."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "체크섬 오류"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "지우기"
@@ -411,7 +411,7 @@ msgstr "더 많은 정보를 보려면 컨테이너를 클릭하세요."
msgid "Click on a device to view more information."
msgstr "더 많은 정보를 보려면 장치를 클릭하세요."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "풀을 클릭하여 vdev 및 데이터 세트 세부 정보를 확인하세요."
@@ -503,7 +503,7 @@ msgstr "이름 복사"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "공개 키 복사"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "실패: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "<0>{min}</0> {min, plural, one {분} other {분}} 동안"
msgid "Forgot password?"
msgstr "비밀번호를 잊으셨나요?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "여유 공간"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "그리드"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "상태"
@@ -1146,7 +1146,7 @@ msgstr "컨테이너 메모리 사용량"
msgid "Model"
msgstr "모델"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "마운트 지점"
@@ -1185,7 +1185,7 @@ msgstr "네트워크 단위"
msgid "No"
msgstr "아니오"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "이 풀에 대한 상세 데이터가 없습니다."
@@ -1212,7 +1212,7 @@ msgstr "이 장치에 사용할 수 있는 S.M.A.R.T. 속성이 없습니다."
msgid "No systems found."
msgstr "시스템을 찾을 수 없습니다."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "없음"
@@ -1255,7 +1255,7 @@ msgstr "OTP"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "메뉴 열기"
@@ -1346,6 +1346,10 @@ msgstr "영구적"
msgid "Persistence"
msgstr "지속성"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "물리적 장치 공간. 실제 사용 가능한 용량을 알 수 없습니다. 풀 디스크 사용량 알림이 비활성화되어 있습니다."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "알림이 전달되도록 <0>SMTP 서버를 구성</0>하세요."
@@ -1379,11 +1383,11 @@ msgstr "사용법은 <0>문서</0>를 참조하세요."
msgid "Please sign in to your account"
msgstr "계정에 로그인하세요."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "풀 상태"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "풀 사용량"
@@ -1416,7 +1420,7 @@ msgstr "프로세스 시작됨"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "공개 키"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "대기열 깊이"
msgid "Quiet Hours"
msgstr "조용한 시간"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "원시"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "스토리지 풀 {displayName}의 원시 사용량"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "조용한 시간"
msgid "Read"
msgstr "읽기"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "읽기 오류"
@@ -1454,7 +1469,7 @@ msgstr "수신됨"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "새로고침"
@@ -1643,7 +1658,7 @@ msgstr "시작 시간"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "상태"
@@ -1671,7 +1686,7 @@ msgstr "스왑 사용량"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "테마 전환"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "시스템"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "시스템 팬 속도 (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "선택한 모든 레코드를 데이터베이스에서 영구적으로
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}의 처리량"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS 풀 {poolName} 처리량"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "스토리지 풀 {displayName} 처리량"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "각 인터페이스별 총합 업로드 데이터량"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "읽기/쓰기에 소요된 총 시간 (100%를 초과할 수 있음)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "디스크 사용량이 임계값을 초과할 때 트리거됩니다."
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "유형"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "범용 토큰"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "알 수 없음"
@@ -1945,7 +1961,7 @@ msgstr "업데이트"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "업데이트됨"
@@ -1968,20 +1984,20 @@ msgstr "가동시간"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "사용량"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS 풀 {poolName} 사용량"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "스토리지 풀 {displayName} 사용량"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "사용됨"
@@ -2058,7 +2074,7 @@ msgstr "Windows 명령어"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows 명령어"
msgid "Write"
msgstr "쓰기"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "쓰기 오류"
@@ -2087,3 +2103,4 @@ msgstr "예"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "사용자 설정이 업데이트되었습니다."
+54 -37
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: nl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 minuten"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Acties"
@@ -196,7 +196,7 @@ msgstr "Weet je het zeker?"
msgid "Automatic copy requires a secure context."
msgstr "Automatisch kopiëren vereist een veilige context."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Beschikbaar"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Mogelijkheden"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capaciteit"
@@ -391,14 +391,14 @@ msgstr "Controleer je monitoringservice"
msgid "Check your notification service"
msgstr "Controleer je meldingsservice"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Checksumfouten"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Wissen"
@@ -411,7 +411,7 @@ msgstr "Klik op een container om meer informatie te zien."
msgid "Click on a device to view more information."
msgstr "Klik op een apparaat om meer informatie te bekijken."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klik op een pool om details over vdevs en datasets te bekijken."
@@ -875,8 +875,8 @@ msgstr "Ventilatoren"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Voor <0>{min}</0> {min, plural, one {minuut} other {minuten}}"
msgid "Forgot password?"
msgstr "Wachtwoord vergeten?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Vrij"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Raster"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Gezondheid"
@@ -1146,7 +1146,7 @@ msgstr "Geheugengebruik van containers"
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Koppelpunt"
@@ -1185,7 +1185,7 @@ msgstr "Netwerk eenheid"
msgid "No"
msgstr "Nee"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Geen gedetailleerde gegevens beschikbaar voor deze pool."
@@ -1212,7 +1212,7 @@ msgstr "Geen S.M.A.R.T. kenmerken beschikbaar voor dit apparaat."
msgid "No systems found."
msgstr "Geen systemen gevonden."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Geen"
@@ -1255,7 +1255,7 @@ msgstr "Eenmalig wachtwoord"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Menu openen"
@@ -1346,6 +1346,10 @@ msgstr "Blijvend"
msgid "Persistence"
msgstr "Persistentie"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fysieke apparatuurruimte. De werkelijk bruikbare capaciteit is onbekend. Waarschuwingen voor pool-schijfgebruik zijn uitgeschakeld."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Bekijk <0>de documentatie</0> voor instructies."
msgid "Please sign in to your account"
msgstr "Meld je aan bij je account"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Poolstatus"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Poolgebruik"
@@ -1432,10 +1436,21 @@ msgstr "Wachtrijdiepte"
msgid "Quiet Hours"
msgstr "Stille uren"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Ruw"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Ruw gebruik van opslagpool {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Stille uren"
msgid "Read"
msgstr "Lezen"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Leesfouten"
@@ -1454,7 +1469,7 @@ msgstr "Ontvangen"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Vernieuwen"
@@ -1643,7 +1658,7 @@ msgstr "Starttijd"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Status"
@@ -1772,9 +1787,9 @@ msgstr "Dit zal alle geselecteerde records verwijderen uit de database."
msgid "Throughput of {extraFsName}"
msgstr "Doorvoer van {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Doorvoer van ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Doorvoer van opslagpool {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,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/storage-pools-table.tsx
msgid "Type"
msgstr "Type"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universele token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Onbekend"
@@ -1945,7 +1961,7 @@ msgstr "Bijwerken"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Bijgewerkt"
@@ -1968,20 +1984,20 @@ msgstr "Actief"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Gebruik"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Gebruik van ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Gebruik van opslagpool {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Gebruikt"
@@ -2058,7 +2074,7 @@ msgstr "Windows-commando"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows-commando"
msgid "Write"
msgstr "Schrijven"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Schrijffouten"
@@ -2087,3 +2103,4 @@ msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Je gebruikersinstellingen zijn bijgewerkt."
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: no\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Norwegian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Handlinger"
@@ -196,7 +196,7 @@ msgstr "Er du sikker?"
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering krever en sikker kontekst."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Tilgjengelig"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Kapabiliteter"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapasitet"
@@ -391,14 +391,14 @@ msgstr "Sjekk overvåkingstjenesten din"
msgid "Check your notification service"
msgstr "Sjekk din meldingstjeneste"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Kontrollsumfeil"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Tøm"
@@ -411,7 +411,7 @@ msgstr "Klikk på en container for å se mer informasjon."
msgid "Click on a device to view more information."
msgstr "Klikk på en enhet for å se mer informasjon."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klikk på en pool for å se detaljer om vdev-er og datasett."
@@ -503,7 +503,7 @@ msgstr "Kopier navn"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopier offentlig nøkkel"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Mislyktes: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Vifter"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "I <0>{min}</0> {min, plural, one {minutt} other {minutter}}"
msgid "Forgot password?"
msgstr "Glemt passord?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Ledig"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Rutenett"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Helse"
@@ -1146,7 +1146,7 @@ msgstr "Minnebruk for containere"
msgid "Model"
msgstr "Modell"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Monteringspunkt"
@@ -1185,7 +1185,7 @@ msgstr "Nettverksenhet"
msgid "No"
msgstr "Nei"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Ingen detaljerte data er tilgjengelige for denne poolen."
@@ -1212,7 +1212,7 @@ msgstr "Ingen S.M.A.R.T.-attributter tilgjengelig for denne enheten."
msgid "No systems found."
msgstr "Ingen systemer funnet."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Ingen"
@@ -1255,7 +1255,7 @@ msgstr "Engangspassord"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Åpne meny"
@@ -1346,6 +1346,10 @@ msgstr "Permanent"
msgid "Persistence"
msgstr "Vedvarenhet"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fysisk enhetsplass. Den faktiske brukbare kapasiteten er ukjent. Varsler om diskbruk for poolen er deaktivert."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Vennligst se <0>dokumentasjonen</0> for instrukser."
msgid "Please sign in to your account"
msgstr "Vennligst logg inn på kontoen din"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pooltilstand"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Poolbruk"
@@ -1416,7 +1420,7 @@ msgstr "Prosess startet"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Offentlig nøkkel"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Kødybde"
msgid "Quiet Hours"
msgstr "Stille timer"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Rå"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Rå bruk av lagringspool {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Stille timer"
msgid "Read"
msgstr "Lesing"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Lesefeil"
@@ -1454,7 +1469,7 @@ msgstr "Mottatt"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Oppdater"
@@ -1643,7 +1658,7 @@ msgstr "Starttid"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Tilstand"
@@ -1671,7 +1686,7 @@ msgstr "Swap-bruk"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Bytt tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "System"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Systemviftehastigheter (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Dette vil permanent slette alle valgte oppføringer fra databasen."
msgid "Throughput of {extraFsName}"
msgstr "Gjennomstrømning av {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Gjennomstrømning for ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Gjennomstrømning av lagringspool {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,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/storage-pools-table.tsx
msgid "Type"
msgstr "Type"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universal token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Ukjent"
@@ -1945,7 +1961,7 @@ msgstr "Oppdater"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Oppdatert"
@@ -1968,20 +1984,20 @@ msgstr "Oppetid"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Forbruk"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Bruk av ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Bruk av lagringspool {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Brukt"
@@ -2058,7 +2074,7 @@ msgstr "Windows-kommando"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows-kommando"
msgid "Write"
msgstr "Skriving"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Skrivefeil"
@@ -2087,3 +2103,4 @@ msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dine brukerinnstillinger har blitt oppdatert."
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Akcje"
@@ -196,7 +196,7 @@ msgstr "Czy jesteś pewien?"
msgid "Automatic copy requires a secure context."
msgstr "Automatyczne kopiowanie wymaga bezpiecznego kontekstu."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Dostępne"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Możliwości"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Pojemność"
@@ -391,14 +391,14 @@ msgstr "Sprawdź usługę monitorowania"
msgid "Check your notification service"
msgstr "Sprawdź swój serwis powiadomień"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Błędy sumy kontrolnej"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Wyczyść"
@@ -411,7 +411,7 @@ msgstr "Wybierz kontener, aby wyświetlić więcej informacji."
msgid "Click on a device to view more information."
msgstr "Wybierz urządzenie, aby wyświetlić więcej informacji."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Kliknij pulę, aby wyświetlić szczegóły vdevów i zestawów danych."
@@ -503,7 +503,7 @@ msgstr "Kopiuj nazwę"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopiuj klucz publiczny"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Nieudane: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Wentylatory"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Na <0>{min}</0> {min, plural, one {minutę} other {minut}}"
msgid "Forgot password?"
msgstr "Zapomniałeś hasła?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Wolne"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Siatka"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Kondycja"
@@ -1146,7 +1146,7 @@ msgstr "Zużycie pamięci przez kontenery"
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Punkt montowania"
@@ -1185,7 +1185,7 @@ msgstr "Jednostka sieciowa"
msgid "No"
msgstr "Nie"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Brak szczegółowych danych dla tej puli."
@@ -1212,7 +1212,7 @@ msgstr "Brak dostępnych atrybutów S.M.A.R.T. dla tego urządzenia."
msgid "No systems found."
msgstr "Nie znaleziono systemów."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Brak"
@@ -1255,7 +1255,7 @@ msgstr "Hasło jednorazowe"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Otwórz menu"
@@ -1346,6 +1346,10 @@ msgstr "Stały"
msgid "Persistence"
msgstr "Trwałość"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fizyczne miejsce na urządzeniu. Rzeczywista pojemność użytkowa jest nieznana. Alerty użycia dysków puli są wyłączone."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Proszę <0>skonfigurować serwer SMTP</0>, aby zapewnić dostarczanie powiadomień."
@@ -1379,11 +1383,11 @@ msgstr "Proszę zapoznać się z <0>dokumentacją</0>."
msgid "Please sign in to your account"
msgstr "Zaloguj się na swoje konto"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Stan puli"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Użycie puli"
@@ -1416,7 +1420,7 @@ msgstr "Proces uruchomiony"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Klucz publiczny"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Głębokość kolejki"
msgid "Quiet Hours"
msgstr "Godziny ciszy"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Surowe"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Surowe użycie puli magazynu {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Godziny ciszy"
msgid "Read"
msgstr "Odczyt"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Błędy odczytu"
@@ -1454,7 +1469,7 @@ msgstr "Otrzymane"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Odśwież"
@@ -1643,7 +1658,7 @@ msgstr "Czas rozpoczęcia"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stan"
@@ -1671,7 +1686,7 @@ msgstr "Użycie pamięci wymiany"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Zmień motyw"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "System"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Prędkości wentylatorów systemu (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Spowoduje to trwałe usunięcie wszystkich zaznaczonych rekordów z bazy
msgid "Throughput of {extraFsName}"
msgstr "Przepustowość {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Przepustowość puli ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Przepustowość puli magazynu {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Wyzwalane, gdy wykorzystanie któregokolwiek dysku przekroczy ustalony p
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Typ"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Uniwersalny token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Nieznana"
@@ -1945,7 +1961,7 @@ msgstr "Aktualizuj"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Zaktualizowano"
@@ -1968,20 +1984,20 @@ msgstr "Czas pracy"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Wykorzystanie"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Użycie puli ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Użycie puli magazynu {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Używane"
@@ -2058,7 +2074,7 @@ msgstr "Polecenie Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Polecenie Windows"
msgid "Write"
msgstr "Zapis"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Błędy zapisu"
@@ -2087,3 +2103,4 @@ msgstr "Tak"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Twoje ustawienia użytkownika zostały zaktualizowane."
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pt\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Portuguese\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Ações"
@@ -196,7 +196,7 @@ msgstr "Tem certeza?"
msgid "Automatic copy requires a secure context."
msgstr "A cópia automática requer um contexto seguro."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Disponível"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Capacidades"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacidade"
@@ -391,14 +391,14 @@ msgstr "Verifique o seu serviço de monitorização"
msgid "Check your notification service"
msgstr "Verifique seu serviço de notificação"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Erros de checksum"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Limpar"
@@ -411,7 +411,7 @@ msgstr "Clique num contentor para ver mais informações."
msgid "Click on a device to view more information."
msgstr "Clique em um dispositivo para ver mais informações."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Clique num pool para ver os detalhes de vdev e dataset."
@@ -503,7 +503,7 @@ msgstr "Copiar nome"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Copiar chave pública"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Falhou: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventoinhas"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Por <0>{min}</0> {min, plural, one {minuto} other {minutos}}"
msgid "Forgot password?"
msgstr "Esqueceu a senha?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Livre"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Grade"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Saúde"
@@ -1146,7 +1146,7 @@ msgstr "Utilização de memória dos contentores"
msgid "Model"
msgstr "Modelo"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Ponto de montagem"
@@ -1185,7 +1185,7 @@ msgstr "Unidade de rede"
msgid "No"
msgstr "Não"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Não existem dados detalhados para este pool."
@@ -1212,7 +1212,7 @@ msgstr "Nenhum atributo S.M.A.R.T. disponível para este dispositivo."
msgid "No systems found."
msgstr "Nenhum sistema encontrado."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Nenhum"
@@ -1255,7 +1255,7 @@ msgstr "Senha de uso único"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Abrir menu"
@@ -1346,6 +1346,10 @@ msgstr "Permanente"
msgid "Persistence"
msgstr "Persistência"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Espaço físico do dispositivo. A capacidade útil real é desconhecida. Os alertas de utilização do disco do pool estão desativados."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Por favor, veja <0>a documentação</0> para instruções."
msgid "Please sign in to your account"
msgstr "Por favor, entre na sua conta"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Estado do pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Utilização do pool"
@@ -1416,7 +1420,7 @@ msgstr "Processo iniciado"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Chave pública"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Profundidade da fila"
msgid "Quiet Hours"
msgstr "Horas Silenciosas"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Bruto"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Utilização bruta do pool de armazenamento {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Horas Silenciosas"
msgid "Read"
msgstr "Ler"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Erros de leitura"
@@ -1454,7 +1469,7 @@ msgstr "Recebido"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Atualizar"
@@ -1643,7 +1658,7 @@ msgstr "Hora de Início"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Estado"
@@ -1671,7 +1686,7 @@ msgstr "Uso de Swap"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Mudar tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistema"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Velocidades das ventoinhas do sistema (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Isso excluirá permanentemente todos os registros selecionados do banco
msgid "Throughput of {extraFsName}"
msgstr "Taxa de transferência de {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Débito do pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Taxa de transferência do pool de armazenamento {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Dispara quando o uso de qualquer disco excede um limite"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tipo"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token universal"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Desconhecida"
@@ -1945,7 +1961,7 @@ msgstr "Atualizar"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Atualizado"
@@ -1968,20 +1984,20 @@ msgstr "Tempo de Atividade"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Uso"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Utilização do pool ZFS {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Utilização do pool de armazenamento {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Usado"
@@ -2058,7 +2074,7 @@ msgstr "Comando Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Comando Windows"
msgid "Write"
msgstr "Escrever"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Erros de escrita"
@@ -2087,3 +2103,4 @@ msgstr "Sim"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "As configurações do seu usuário foram atualizadas."
+64 -48
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ro\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 19:06\n"
"PO-Revision-Date: 2026-09-10 00:33\n"
"Last-Translator: \n"
"Language-Team: Romanian\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100>0 && n%100<20)) ? 1 : 2);\n"
@@ -61,7 +61,7 @@ msgstr "1 oră"
#. Load average
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "1 min"
msgstr "1 min"
msgstr ""
#: src/lib/utils.ts
msgid "1 minute"
@@ -78,7 +78,7 @@ msgstr "12 ore"
#. Load average
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "15 min"
msgstr "15 min"
msgstr ""
#: src/lib/utils.ts
msgid "24 hours"
@@ -91,13 +91,13 @@ msgstr "30 zile"
#. Load average
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "5 min"
msgstr "5 min"
msgstr ""
#. Table column
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Acțiuni"
@@ -142,7 +142,7 @@ msgstr "Reglaţi lăţimea aspectului principal"
#: src/components/command-palette.tsx
#: src/components/navbar.tsx
msgid "Admin"
msgstr "Admin"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
@@ -154,7 +154,7 @@ msgstr "După setarea variabilelor de mediu, reporniţi centrul Beszel pentru ca
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
@@ -196,7 +196,7 @@ msgstr "Ești sigur?"
msgid "Automatic copy requires a secure context."
msgstr "Copierea automată necesită un context securizat."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr ""
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Capabilități"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Capacitate"
@@ -348,7 +348,7 @@ msgstr "Atenție - posibilă pierdere de date"
#: src/components/routes/settings/general.tsx
msgid "Celsius (°C)"
msgstr "Celsius (°C)"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Change display units for metrics."
@@ -391,14 +391,14 @@ msgstr ""
msgid "Check your notification service"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr ""
@@ -411,7 +411,7 @@ msgstr ""
msgid "Click on a device to view more information."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr ""
@@ -530,7 +530,7 @@ msgstr ""
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
@@ -732,7 +732,7 @@ msgstr "Editează {foo}"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/otp-forms.tsx
msgid "Email"
msgstr "Email"
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
@@ -875,8 +875,8 @@ msgstr ""
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr ""
msgid "Forgot password?"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr ""
@@ -924,7 +924,7 @@ msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
msgid "Global"
msgstr "Global"
msgstr ""
#: src/components/routes/system.tsx
msgid "GPU"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr ""
@@ -1144,9 +1144,9 @@ msgstr "Utilizarea memoriei de către containere"
#. Device model
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr ""
@@ -1185,7 +1185,7 @@ msgstr ""
msgid "No"
msgstr "Nu"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr ""
@@ -1212,7 +1212,7 @@ msgstr ""
msgid "No systems found."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr ""
@@ -1255,7 +1255,7 @@ msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr ""
@@ -1346,6 +1346,10 @@ msgstr ""
msgid "Persistence"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr ""
@@ -1379,17 +1383,17 @@ msgstr ""
msgid "Please sign in to your account"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr ""
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Container ports"
@@ -1432,10 +1436,21 @@ msgstr ""
msgid "Quiet Hours"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr ""
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr ""
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr ""
msgid "Read"
msgstr "Citit"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr ""
@@ -1454,7 +1469,7 @@ msgstr "Primit"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Actualizează"
@@ -1643,7 +1658,7 @@ msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr ""
@@ -1772,8 +1787,8 @@ msgstr ""
msgid "Throughput of {extraFsName}"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr ""
#: src/components/routes/settings/general.tsx
@@ -1806,7 +1821,7 @@ msgstr ""
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Total"
msgstr ""
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
@@ -1824,7 +1839,7 @@ msgstr ""
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Total: {0}"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
@@ -1897,6 +1912,7 @@ msgstr ""
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tip"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr ""
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr ""
@@ -1945,7 +1961,7 @@ msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr ""
@@ -1968,20 +1984,20 @@ msgstr ""
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Utilizare"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr ""
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Utilizat"
@@ -2058,7 +2074,7 @@ msgstr ""
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr ""
msgid "Write"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr ""
+61 -44
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ru\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 мин"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Действия"
@@ -196,7 +196,7 @@ msgstr "Вы уверены?"
msgid "Automatic copy requires a secure context."
msgstr "Автоматическое копирование требует безопасного контекста."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Доступно"
@@ -234,7 +234,7 @@ msgstr "Среднее время от очереди до завершения
#: src/components/routes/system/charts/cpu-charts.tsx
msgid "Average system-wide CPU utilization"
msgstr "Среднее использование CPU по всей системе"
msgstr "Среднее использование CPU в системе"
#. placeholder {0}: gpu.n
#: src/components/routes/system/charts/gpu-charts.tsx
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Возможности"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Емкость"
@@ -391,14 +391,14 @@ msgstr "Проверьте ваш сервис мониторинга"
msgid "Check your notification service"
msgstr "Проверьте ваш сервис уведомлений"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Ошибки контрольной суммы"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Очистить"
@@ -411,7 +411,7 @@ msgstr "Нажмите на контейнер для просмотра доп
msgid "Click on a device to view more information."
msgstr "Нажмите на устройство для просмотра дополнительной информации."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Нажмите на пул, чтобы просмотреть сведения о vdev и dataset."
@@ -875,8 +875,8 @@ msgstr "Вентиляторы"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "На <0>{min}</0> {min, plural, one {минуту} other {минут}}"
msgid "Forgot password?"
msgstr "Забыли пароль?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Свободно"
@@ -932,7 +932,7 @@ msgstr "GPU"
#: src/components/routes/system/charts/gpu-charts.tsx
msgid "GPU Engines"
msgstr "GPU движки"
msgstr "Ядра GPU"
#: src/components/routes/system/charts/gpu-charts.tsx
msgid "GPU Power Draw"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Сетка"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Здоровье"
@@ -1146,7 +1146,7 @@ msgstr "Использование памяти контейнерами"
msgid "Model"
msgstr "Модель"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Точка монтирования"
@@ -1185,7 +1185,7 @@ msgstr "Единицы измерения скорости сети"
msgid "No"
msgstr "Нет"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Подробные данные для этого пула отсутствуют."
@@ -1212,7 +1212,7 @@ msgstr "Для этого устройства нет доступных атр
msgid "No systems found."
msgstr "Системы не найдены."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Нет"
@@ -1255,7 +1255,7 @@ msgstr "Одноразовый пароль"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Открыть меню"
@@ -1346,6 +1346,10 @@ msgstr "Постоянный"
msgid "Persistence"
msgstr "Устойчивость"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Физическое пространство устройства. Реальная полезная ёмкость неизвестна. Оповещения об использовании дисков пула отключены."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Пожалуйста, <0>настройте SMTP-сервер</0>, чтобы гарантировать доставку оповещений."
@@ -1379,11 +1383,11 @@ msgstr "Пожалуйста, смотрите <0>документацию</0>
msgid "Please sign in to your account"
msgstr "Пожалуйста, войдите в свою учетную запись"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Состояние пула"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Использование пула"
@@ -1404,7 +1408,7 @@ msgstr "Включение питания"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
msgid "Precise utilization at the recorded time"
msgstr "Точное использование в записанное время"
msgstr "Использование по времени"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
@@ -1432,10 +1436,21 @@ msgstr "Глубина очереди"
msgid "Quiet Hours"
msgstr "Тихие часы"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Сырое"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Сырое использование пула хранения {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Тихие часы"
msgid "Read"
msgstr "Чтение"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Ошибки чтения"
@@ -1454,7 +1469,7 @@ msgstr "Получено"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Обновить"
@@ -1501,7 +1516,7 @@ msgstr "Возобновить"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Корневой"
msgstr "Системный"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
@@ -1643,7 +1658,7 @@ msgstr "Время начала"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Состояние"
@@ -1662,7 +1677,7 @@ msgstr "Подсостояние"
#: src/components/routes/system/charts/memory-charts.tsx
msgid "Swap space used by the system"
msgstr "Используемое системой пространство подкачки"
msgstr "Размер файла подкачки системы"
#: src/components/routes/system/charts/memory-charts.tsx
msgid "Swap Usage"
@@ -1694,7 +1709,7 @@ msgstr "Скорость вращения системных вентилято
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
msgstr "Средняя загрузка системы за время"
msgstr "Средняя загрузка системы по времени"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
@@ -1738,7 +1753,7 @@ msgstr "Единицы измерения температуры"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Temperatures of system sensors"
msgstr "Температуры датчиков системы"
msgstr "Температура датчиков системы"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
@@ -1772,9 +1787,9 @@ msgstr "Это навсегда удалит все выбранные запи
msgid "Throughput of {extraFsName}"
msgstr "Пропускная способность {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Пропускная способность ZFS-пула {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Пропускная способность пула хранения {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Срабатывает, когда нагрузка на любой из
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Тип"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Универсальный токен"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Неизвестно"
@@ -1945,7 +1961,7 @@ msgstr "Обновить"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Обновлено"
@@ -1968,20 +1984,20 @@ msgstr "Время работы"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Использование"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Использование ZFS-пула {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Использование пула хранения {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Использовано"
@@ -2058,7 +2074,7 @@ msgstr "Команда Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Команда Windows"
msgid "Write"
msgstr "Запись"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Ошибки записи"
@@ -2087,3 +2103,4 @@ msgstr "Да"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Ваши настройки пользователя были обновлены."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Dejanja"
@@ -196,7 +196,7 @@ msgstr "Ali ste prepričani?"
msgid "Automatic copy requires a secure context."
msgstr "Za samodejno kopiranje je potreben varen kontekst."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Na voljo"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Zmožnosti"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapaciteta"
@@ -391,14 +391,14 @@ msgstr "Preverite svojo storitev za spremljanje"
msgid "Check your notification service"
msgstr "Preverite storitev obveščanja"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Napake kontrolne vsote"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Počisti"
@@ -411,7 +411,7 @@ msgstr "Kliknite na kontejner za več informacij."
msgid "Click on a device to view more information."
msgstr "Kliknite na napravo za več informacij."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Kliknite pool za ogled podrobnosti o vdev in dataset."
@@ -503,7 +503,7 @@ msgstr "Kopiraj ime"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopiraj javni ključ"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Neuspešno: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilatorji"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Za <0>{min}</0> {min, plural, one {minuto} other {minut}}"
msgid "Forgot password?"
msgstr "Pozabljeno geslo?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Prosto"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Mreža"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Zdravje"
@@ -1146,7 +1146,7 @@ msgstr "Poraba pomnilnika vsebnikov"
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Točka priklopa"
@@ -1185,7 +1185,7 @@ msgstr "Enota omrežja"
msgid "No"
msgstr "Ne"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Za ta pool ni podrobnih podatkov."
@@ -1212,7 +1212,7 @@ msgstr "Za to napravo ni na voljo atributov S.M.A.R.T."
msgid "No systems found."
msgstr "Ne najdem sistema."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Brez"
@@ -1255,7 +1255,7 @@ msgstr "Enkratno geslo"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Odpri menu"
@@ -1346,6 +1346,10 @@ msgstr "Trajen"
msgid "Persistence"
msgstr "Vztrajnost"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fizični prostor naprave. Dejanska uporabna zmogljivost ni znana. Opozorila o uporabi diskov poola so onemogočena."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "<0>Nastavite strežnik SMTP</0>, da zagotovite dostavo opozoril."
@@ -1379,11 +1383,11 @@ msgstr "Za navodila glejte <0>dokumentacijo</0>."
msgid "Please sign in to your account"
msgstr "Prijavite se v svoj račun"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Stanje poola"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Uporaba poola"
@@ -1416,7 +1420,7 @@ msgstr "Proces začet"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Javni ključ"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Globina čakalne vrste"
msgid "Quiet Hours"
msgstr "Tihi čas"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Surovo"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Surova uporaba shranjevalnega poola {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Tihi čas"
msgid "Read"
msgstr "Preberano"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Napake pri branju"
@@ -1454,7 +1469,7 @@ msgstr "Prejeto"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Osveži"
@@ -1643,7 +1658,7 @@ msgstr "Čas začetka"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stanje"
@@ -1671,7 +1686,7 @@ msgstr "Swap uporaba"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Zamenjaj temo"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistemsko"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Hitrosti ventilatorjev sistema (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "To bo trajno izbrisalo vse izbrane zapise iz zbirke podatkov."
msgid "Throughput of {extraFsName}"
msgstr "Prepustnost {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Prepustnost ZFS poola {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Prepustnost shranjevalnega poola {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Skupni poslani podatki za vsak vmesnik"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Skupni čas, porabljen za branje/pisanje (lahko preseže 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Sproži se, ko uporaba katerega koli diska preseže prag"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Vrsta"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Univerzalni žeton"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Neznana"
@@ -1945,7 +1961,7 @@ msgstr "Posodobi"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Posodobljeno"
@@ -1968,20 +1984,20 @@ msgstr "Čas delovanja"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Uporaba"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Uporaba ZFS poola {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Uporaba shranjevalnega poola {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Uporabljeno"
@@ -2058,7 +2074,7 @@ msgstr "Ukaz Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Ukaz Windows"
msgid "Write"
msgstr "Pisanje"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Napake pri zapisovanju"
@@ -2087,3 +2103,4 @@ msgstr "Da"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše uporabniške nastavitve so posodobljene."
+55 -38
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Serbian (Cyrillic)\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"
@@ -97,7 +97,7 @@ msgstr "5 мин"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Акције"
@@ -196,7 +196,7 @@ msgstr "Да ли сте сигурни?"
msgid "Automatic copy requires a secure context."
msgstr "Аутоматско копирање захтева безбедан контекст."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Доступно"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Могућности"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Капацитет"
@@ -391,14 +391,14 @@ msgstr "Proverite svoju uslugu monitoringa"
msgid "Check your notification service"
msgstr "Проверите ваш сервис за обавештавања"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Грешке контролне суме"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Обриши"
@@ -411,7 +411,7 @@ msgstr "Кликните на контејнер да видите више ин
msgid "Click on a device to view more information."
msgstr "Кликните на уређај да видите више информација."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Кликните на pool да бисте видели детаље о vdev и dataset."
@@ -875,8 +875,8 @@ msgstr "Вентилатори"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "За <0>{min}</0> {min, plural, one {минуту} few {минута} ot
msgid "Forgot password?"
msgstr "Заборављена лозинка?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Слободно"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Мрежа"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Здравље"
@@ -1146,7 +1146,7 @@ msgstr "Коришћење меморије контејнера"
msgid "Model"
msgstr "Модел"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Тачка монтирања"
@@ -1185,7 +1185,7 @@ msgstr "Мрежна јединица"
msgid "No"
msgstr "Не"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Нема детаљних података за овај pool."
@@ -1212,7 +1212,7 @@ msgstr "Нема доступних S.M.A.R.T. атрибута за овај у
msgid "No systems found."
msgstr "Нису пронађени системи."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Нема"
@@ -1255,7 +1255,7 @@ msgstr "Једнократна лозинка"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Отвори мени"
@@ -1346,6 +1346,10 @@ msgstr "Трајан"
msgid "Persistence"
msgstr "Упорност"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Физички простор уређаја. Стварни искористиви капацитет није познат. Упозорења о искоришћености дискова pool-а су онемогућена."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Молимо вас <0>конфигуришите SMTP сервер</0> да бисте осигурали да се упозорења испоручују."
@@ -1379,11 +1383,11 @@ msgstr "Молимо вас погледајте <0>документацију</
msgid "Please sign in to your account"
msgstr "Молимо вас да се пријавите на ваш налог"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Стање pool-а"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Коришћење pool-а"
@@ -1432,10 +1436,21 @@ msgstr "Дубина реда"
msgid "Quiet Hours"
msgstr "Тихи сати"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Сирово"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Сирова искоришћеност pool-а за складиштење {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Тихи сати"
msgid "Read"
msgstr "Читање"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Грешке при читању"
@@ -1454,7 +1469,7 @@ msgstr "Примљено"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Освежи"
@@ -1643,7 +1658,7 @@ msgstr "Време почетка"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Стање"
@@ -1690,7 +1705,7 @@ msgstr "Систем"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Брзине вентилатора система (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Ово ће трајно избрисати све изабране за
msgid "Throughput of {extraFsName}"
msgstr "Проток {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Пропусност ZFS pool-а {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Проток pool-а за складиштење {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Окида се када употреба било ког диска п
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Тип"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Универзални токен"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Непознато"
@@ -1945,7 +1961,7 @@ msgstr "Ажурирај"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Ажурирано"
@@ -1968,20 +1984,20 @@ msgstr "Време рада"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Употреба"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Коришћење ZFS pool-а {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Искоришћеност pool-а за складиштење {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Коришћено"
@@ -2058,7 +2074,7 @@ msgstr "Windows команда"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows команда"
msgid "Write"
msgstr "Писање"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Грешке при писању"
@@ -2087,3 +2103,4 @@ msgstr "Да"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Ваша корисничка подешавања су ажурирана."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sv\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Swedish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 min"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Åtgärder"
@@ -196,7 +196,7 @@ msgstr "Är du säker?"
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering kräver en säker kontext."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Tillgängligt"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Förmågor"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapacitet"
@@ -391,14 +391,14 @@ msgstr "Kontrollera din övervakningstjänst"
msgid "Check your notification service"
msgstr "Kontrollera din aviseringstjänst"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Kontrollsummefel"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Rensa"
@@ -411,7 +411,7 @@ msgstr "Klicka på en behållare för att visa mer information."
msgid "Click on a device to view more information."
msgstr "Klicka på en enhet för att visa mer information."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Klicka på en pool för att visa detaljer om vdev och dataset."
@@ -503,7 +503,7 @@ msgstr "Kopiera namn"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Kopiera publik nyckel"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Misslyckades: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Fläktar"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Under <0>{min}</0> {min, plural, one {minut} other {minuter}}"
msgid "Forgot password?"
msgstr "Glömt lösenordet?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Ledigt"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Rutnät"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Hälsa"
@@ -1146,7 +1146,7 @@ msgstr "Minnesanvändning för containrar"
msgid "Model"
msgstr "Modell"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Monteringspunkt"
@@ -1185,7 +1185,7 @@ msgstr "Nätverksenhet"
msgid "No"
msgstr "Nej"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Det finns inga detaljerade data för denna pool."
@@ -1212,7 +1212,7 @@ msgstr "Inga S.M.A.R.T.-attribut tillgängliga för den här enheten."
msgid "No systems found."
msgstr "Inga system hittades."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Ingen"
@@ -1255,7 +1255,7 @@ msgstr "Engångslösenord"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Öppna menyn"
@@ -1346,6 +1346,10 @@ msgstr ""
msgid "Persistence"
msgstr "Beständighet"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fysiskt enhetsutrymme. Den verkliga användbara kapaciteten är okänd. Varningar om diskanvändning för poolen är inaktiverade."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Vänligen se <0>dokumentationen</0> för instruktioner."
msgid "Please sign in to your account"
msgstr "Vänligen logga in på ditt konto"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Poolstatus"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Poolanvändning"
@@ -1416,7 +1420,7 @@ msgstr "Process startad"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Publik nyckel"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Kö-djup"
msgid "Quiet Hours"
msgstr "Tysta timmar"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Rå"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Rå användning av lagringspool {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Tysta timmar"
msgid "Read"
msgstr "Läs"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Läsfel"
@@ -1454,7 +1469,7 @@ msgstr "Mottaget"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Uppdatera"
@@ -1643,7 +1658,7 @@ msgstr "Starttid"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Tillstånd"
@@ -1671,7 +1686,7 @@ msgstr "Swap-användning"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Byt tema"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "System"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Systemfläkthastigheter (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Detta kommer permanent att ta bort alla valda poster från databasen."
msgid "Throughput of {extraFsName}"
msgstr "Genomströmning av {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Genomströmning för ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Genomströmning av lagringspool {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Totalt skickad data för varje gränssnitt"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Total tid för läsning/skrivning (kan överstiga 100 %)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Utlöses när användningen av någon disk överskrider ett tröskelvär
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Typ"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universell nyckel"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Okänd"
@@ -1945,7 +1961,7 @@ msgstr "Uppdatera"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Uppdaterad"
@@ -1968,20 +1984,20 @@ msgstr "Drifttid"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Användning"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Användning av ZFS-pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Användning av lagringspool {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Använt"
@@ -2058,7 +2074,7 @@ msgstr "Windows-kommando"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows-kommando"
msgid "Write"
msgstr "Skriv"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Skrivfel"
@@ -2087,3 +2103,4 @@ msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dina användarinställningar har uppdaterats."
+51 -35
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: th\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 19:06\n"
"PO-Revision-Date: 2026-09-10 00:33\n"
"Last-Translator: \n"
"Language-Team: Thai\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr ""
@@ -196,7 +196,7 @@ msgstr ""
msgid "Automatic copy requires a secure context."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr ""
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr ""
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr ""
@@ -391,14 +391,14 @@ msgstr ""
msgid "Check your notification service"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr ""
@@ -411,7 +411,7 @@ msgstr ""
msgid "Click on a device to view more information."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr ""
@@ -875,8 +875,8 @@ msgstr ""
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr ""
msgid "Forgot password?"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr ""
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr ""
@@ -1146,7 +1146,7 @@ msgstr "การใช้หน่วยความจำของคอนเ
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr ""
@@ -1185,7 +1185,7 @@ msgstr ""
msgid "No"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr ""
@@ -1212,7 +1212,7 @@ msgstr ""
msgid "No systems found."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr ""
@@ -1255,7 +1255,7 @@ msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr ""
@@ -1346,6 +1346,10 @@ msgstr ""
msgid "Persistence"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr ""
@@ -1379,11 +1383,11 @@ msgstr ""
msgid "Please sign in to your account"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr ""
@@ -1432,10 +1436,21 @@ msgstr ""
msgid "Quiet Hours"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr ""
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr ""
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr ""
msgid "Read"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr ""
@@ -1454,7 +1469,7 @@ msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr ""
@@ -1643,7 +1658,7 @@ msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr ""
@@ -1772,8 +1787,8 @@ msgstr ""
msgid "Throughput of {extraFsName}"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr ""
#: src/components/routes/settings/general.tsx
@@ -1897,6 +1912,7 @@ msgstr ""
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr ""
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr ""
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr ""
@@ -1945,7 +1961,7 @@ msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr ""
@@ -1968,20 +1984,20 @@ msgstr ""
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr ""
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr ""
@@ -2058,7 +2074,7 @@ msgstr ""
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr ""
msgid "Write"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr ""
+59 -42
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: tr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Turkish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 dk"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Eylemler"
@@ -196,7 +196,7 @@ msgstr "Emin misiniz?"
msgid "Automatic copy requires a secure context."
msgstr "Otomatik kopyalama güvenli bir bağlam gerektirir."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Kullanılabilir"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Yetenekler"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Kapasite"
@@ -391,14 +391,14 @@ msgstr "İzleme servisinizi kontrol edin"
msgid "Check your notification service"
msgstr "Bildirim hizmetinizi kontrol edin"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Sağlama toplamı hataları"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Temizle"
@@ -411,7 +411,7 @@ msgstr "Daha fazla bilgi görüntülemek için bir konteynere tıklayın."
msgid "Click on a device to view more information."
msgstr "Daha fazla bilgi görüntülemek için bir cihaza tıklayın."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Pool'a tıklayarak vdev ve dataset ayrıntılarını görüntüleyin."
@@ -503,7 +503,7 @@ msgstr "Adı kopyala"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Açık anahtarı kopyala"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Başarısız: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Fanlar"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "<0>{min}</0> {min, plural, one {dakika} other {dakika}} için"
msgid "Forgot password?"
msgstr "Şifrenizi mi unuttunuz?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Boş"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Izgara"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Sağlık"
@@ -1146,7 +1146,7 @@ msgstr "Konteynerlerin bellek kullanımı"
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Bağlama noktası"
@@ -1185,7 +1185,7 @@ msgstr "Ağ birimi"
msgid "No"
msgstr "Hayır"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Bu pool için ayrıntılı veri mevcut değil."
@@ -1212,7 +1212,7 @@ msgstr "Bu cihaz için kullanılabilir S.M.A.R.T. özelliği yok."
msgid "No systems found."
msgstr "Sistem bulunamadı."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Yok"
@@ -1255,7 +1255,7 @@ msgstr "Tek kullanımlık şifre"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Menüyü aç"
@@ -1346,6 +1346,10 @@ msgstr "Kalıcı"
msgid "Persistence"
msgstr "Kalıcılık"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Fiziksel cihaz alanı. Gerçek kullanılabilir kapasite bilinmiyor. Pool disk kullanımı uyarıları devre dışı."
#: src/components/routes/settings/notifications.tsx
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>."
@@ -1379,11 +1383,11 @@ msgstr "Talimatlar için lütfen <0>dokümantasyonu</0> inceleyin."
msgid "Please sign in to your account"
msgstr "Lütfen hesabınıza giriş yapın"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pool sağlığı"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Pool kullanımı"
@@ -1416,7 +1420,7 @@ msgstr "Süreç başlatıldı"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Açık anahtar"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Kuyruk Derinliği"
msgid "Quiet Hours"
msgstr "Sessiz Saatler"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Ham"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Depolama pool'u {displayName} ham kullanımı"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Sessiz Saatler"
msgid "Read"
msgstr "Oku"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Okuma hataları"
@@ -1454,7 +1469,7 @@ msgstr "Alındı"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Yenile"
@@ -1643,7 +1658,7 @@ msgstr "Başlangıç Saati"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Durum"
@@ -1671,7 +1686,7 @@ msgstr "Takas Kullanımı"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Temayı değiştir"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Sistem"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Sistem fan hızları (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Bu, seçilen tüm kayıtları veritabanından kalıcı olarak silecektir
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName} verimliliği"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} aktarım hızı"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Depolama pool'u {displayName} veri aktarım hızı"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Herhangi bir diskin kullanımı bir eşiği aştığında tetiklenir"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tür"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Evrensel token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Bilinmiyor"
@@ -1945,7 +1961,7 @@ msgstr "Güncelle"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Güncellendi"
@@ -1968,20 +1984,20 @@ msgstr "Çalışma Süresi"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Kullanım"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} kullanımı"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Depolama pool'u {displayName} kullanımı"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Kullanıldı"
@@ -2058,7 +2074,7 @@ msgstr "Windows komutu"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows komutu"
msgid "Write"
msgstr "Yaz"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Yazma hataları"
@@ -2087,3 +2103,4 @@ msgstr "Evet"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Kullanıcı ayarlarınız güncellendi."
+51 -35
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ug\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 19:06\n"
"PO-Revision-Date: 2026-09-10 00:33\n"
"Last-Translator: \n"
"Language-Team: Uyghur\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -97,7 +97,7 @@ msgstr ""
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr ""
@@ -196,7 +196,7 @@ msgstr ""
msgid "Automatic copy requires a secure context."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr ""
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr ""
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr ""
@@ -391,14 +391,14 @@ msgstr ""
msgid "Check your notification service"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr ""
@@ -411,7 +411,7 @@ msgstr ""
msgid "Click on a device to view more information."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr ""
@@ -875,8 +875,8 @@ msgstr ""
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr ""
msgid "Forgot password?"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr ""
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr ""
@@ -1146,7 +1146,7 @@ msgstr "كونتېينېرلارنىڭ ئەسلەك ئىشلىتىشى"
msgid "Model"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr ""
@@ -1185,7 +1185,7 @@ msgstr ""
msgid "No"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr ""
@@ -1212,7 +1212,7 @@ msgstr ""
msgid "No systems found."
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr ""
@@ -1255,7 +1255,7 @@ msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr ""
@@ -1346,6 +1346,10 @@ msgstr ""
msgid "Persistence"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr ""
@@ -1379,11 +1383,11 @@ msgstr ""
msgid "Please sign in to your account"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr ""
@@ -1432,10 +1436,21 @@ msgstr ""
msgid "Quiet Hours"
msgstr ""
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr ""
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr ""
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr ""
msgid "Read"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr ""
@@ -1454,7 +1469,7 @@ msgstr ""
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr ""
@@ -1643,7 +1658,7 @@ msgstr ""
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr ""
@@ -1772,8 +1787,8 @@ msgstr ""
msgid "Throughput of {extraFsName}"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr ""
#: src/components/routes/settings/general.tsx
@@ -1897,6 +1912,7 @@ msgstr ""
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr ""
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr ""
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr ""
@@ -1945,7 +1961,7 @@ msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr ""
@@ -1968,20 +1984,20 @@ msgstr ""
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr ""
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr ""
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr ""
@@ -2058,7 +2074,7 @@ msgstr ""
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr ""
msgid "Write"
msgstr ""
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr ""
+54 -37
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: uk\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \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"
@@ -97,7 +97,7 @@ msgstr "5 хв"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Дії"
@@ -196,7 +196,7 @@ msgstr "Ви впевнені?"
msgid "Automatic copy requires a secure context."
msgstr "Автоматичне копіювання вимагає безпечного контексту."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Доступно"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Можливості"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Ємність"
@@ -391,14 +391,14 @@ msgstr "Перевірте ваш сервіс моніторингу"
msgid "Check your notification service"
msgstr "Перевірте ваш сервіс сповіщень"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Помилки контрольної суми"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Очистити"
@@ -411,7 +411,7 @@ msgstr "Натисніть на контейнер, щоб переглянут
msgid "Click on a device to view more information."
msgstr "Натисніть на пристрій, щоб переглянути більше інформації."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Натисніть на pool, щоб переглянути відомості про vdev і dataset."
@@ -875,8 +875,8 @@ msgstr "Вентилятори"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Протягом <0>{min}</0> {min, plural, one {хвилини} other {
msgid "Forgot password?"
msgstr "Забули пароль?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Вільно"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Сітка"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Здоров’я"
@@ -1146,7 +1146,7 @@ msgstr "Використання пам’яті контейнерами"
msgid "Model"
msgstr "Модель"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Точка монтування"
@@ -1185,7 +1185,7 @@ msgstr "Одиниця виміру мережі"
msgid "No"
msgstr "Ні"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Докладні дані для цього pool недоступні."
@@ -1212,7 +1212,7 @@ msgstr "Для цього пристрою немає доступних атр
msgid "No systems found."
msgstr "Систем не знайдено."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Немає"
@@ -1255,7 +1255,7 @@ msgstr "Одноразовий пароль"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Відкрити меню"
@@ -1346,6 +1346,10 @@ msgstr "Постійний"
msgid "Persistence"
msgstr "Стійкість"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Фізичний простір пристрою. Справжня корисна ємність невідома. Сповіщення про використання дисків пулу вимкнено."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Будь ласка, <0>налаштуйте SMTP сервер</0>, щоб забезпечити доставку сповіщень."
@@ -1379,11 +1383,11 @@ msgstr "Будь ласка, перегляньте <0>документацію<
msgid "Please sign in to your account"
msgstr "Будь ласка, увійдіть у свій обліковий запис"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Стан pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Використання pool"
@@ -1432,10 +1436,21 @@ msgstr "Глибина черги"
msgid "Quiet Hours"
msgstr "Тихі години"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Необроблене"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Необроблене використання пулу сховища {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Тихі години"
msgid "Read"
msgstr "Читання"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Помилки читання"
@@ -1454,7 +1469,7 @@ msgstr "Отримано"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Оновити"
@@ -1643,7 +1658,7 @@ msgstr "Час початку"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Стан"
@@ -1772,9 +1787,9 @@ msgstr "Це назавжди видалить усі вибрані запис
msgid "Throughput of {extraFsName}"
msgstr "Пропускна здатність {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Пропускна здатність ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Пропускна здатність пулу сховища {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "Спрацьовує, коли використання будь-яко
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Тип"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Універсальний токен"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Невідомо"
@@ -1945,7 +1961,7 @@ msgstr "Оновити"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Оновлено"
@@ -1968,20 +1984,20 @@ msgstr "Час роботи"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Використання"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Використання ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Використання пулу сховища {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Використано"
@@ -2058,7 +2074,7 @@ msgstr "Команда Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Команда Windows"
msgid "Write"
msgstr "Запис"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Помилки запису"
@@ -2087,3 +2103,4 @@ msgstr "Так"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Ваші налаштування користувача були оновлені."
+63 -46
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: uz\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: Uzbek\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -97,7 +97,7 @@ msgstr "5 daq"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Amallar"
@@ -196,7 +196,7 @@ msgstr "Ishonchingiz komilmi?"
msgid "Automatic copy requires a secure context."
msgstr "Avtomatik nusxalash xavfsiz kontekstni talab qiladi."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Mavjud"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Imkoniyatlar"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Sig'im"
@@ -391,14 +391,14 @@ msgstr "Monitoring xizmatingizni tekshiring"
msgid "Check your notification service"
msgstr "Bildirishnoma xizmatingizni tekshiring"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Nazorat summasi xatolari"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Tozalash"
@@ -411,7 +411,7 @@ msgstr "Batafsil ma'lumot uchun konteynerni bosing."
msgid "Click on a device to view more information."
msgstr "Batafsil ma'lumot uchun qurilmani bosing."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Pool ustiga bosib, vdev va dataset tafsilotlarini koring."
@@ -447,11 +447,11 @@ msgstr "Ulanish uzildi"
#: src/lib/alerts.ts
msgid "Container"
msgstr ""
msgstr "Konteyner"
#: src/lib/alerts.ts
msgid "Container Health"
msgstr ""
msgstr "Konteyner holati"
#: src/components/routes/system.tsx
msgid "Containers"
@@ -503,7 +503,7 @@ msgstr "Nomni nusxalash"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Ochiq kalitni nusxalash"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Muvaffaqiyatsiz: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Ventilyatorlar"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "<0>{min}</0> {min, plural, other {daqiqa}} uchun"
msgid "Forgot password?"
msgstr "Parolni unutdingizmi?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Bosh"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Grid"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Sog'lik"
@@ -1139,14 +1139,14 @@ msgstr "Xotira ishlatilishi"
#: src/components/routes/system/charts/memory-charts.tsx
msgid "Memory usage of containers"
msgstr ""
msgstr "Konteynerlarning xotira ishlatilishi"
#. Device model
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Model"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Ulash nuqtasi"
@@ -1165,7 +1165,7 @@ msgstr "Tarmoq"
#: src/components/routes/system/charts/network-charts.tsx
msgid "Network traffic of containers"
msgstr ""
msgstr "Konteynerlarning tarmoq trafigi"
#: src/components/routes/system/charts/network-charts.tsx
#: src/components/routes/system/network-sheet.tsx
@@ -1185,7 +1185,7 @@ msgstr "Tarmoq birligi"
msgid "No"
msgstr "Yo'q"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Bu pool uchun batafsil malumot mavjud emas."
@@ -1212,7 +1212,7 @@ msgstr "Ushbu qurilma uchun S.M.A.R.T. atributlari mavjud emas."
msgid "No systems found."
msgstr "Tizimlar topilmadi."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Yoq"
@@ -1255,7 +1255,7 @@ msgstr "Bir martalik parol"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Menyuni ochish"
@@ -1346,6 +1346,10 @@ msgstr "Doimiy"
msgid "Persistence"
msgstr "Saqlash"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Jismoniy qurilma maydoni. Haqiqiy foydalanish mumkin bo'lgan sig'im noma'lum. Pool diskidan foydalanish ogohlantirishlari o'chirilgan."
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Ogohlantirishlar yetkazilishini ta'minlash uchun <0>SMTP serverni sozlang</0>."
@@ -1379,11 +1383,11 @@ msgstr "Ko'rsatmalar uchun <0>hujjatlarni</0> ko'ring."
msgid "Please sign in to your account"
msgstr "Hisobingizga kiring"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pool holati"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Pool ishlatilishi"
@@ -1416,7 +1420,7 @@ msgstr "Jarayon boshlandi"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Ochiq kalit"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Navbat chuqurligi"
msgid "Quiet Hours"
msgstr "Tinch soatlar"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Xom"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "{displayName} saqlash pool'ining xom ishlatilishi"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Tinch soatlar"
msgid "Read"
msgstr "O'qish"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Oqish xatolari"
@@ -1454,7 +1469,7 @@ msgstr "Qabul qilindi"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Yangilash"
@@ -1643,7 +1658,7 @@ msgstr "Boshlanish vaqti"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Holat"
@@ -1690,7 +1705,7 @@ msgstr "Tizim"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Tizim ventilyatorlari tezligi (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Bu barcha tanlangan yozuvlarni ma'lumotlar bazasidan butunlay o'chiradi.
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName} ning o'tkazish qobiliyati"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} otkazuvchanligi"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "{displayName} saqlash pool'ining o'tkazish qobiliyati"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,12 +1912,13 @@ msgstr "Biron-bir disk ishlatilishi chegaradan oshganda ishga tushadi"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Tur"
#: src/lib/alerts.ts
msgid "Unhealthy"
msgstr ""
msgstr "Nosog'lom"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Universal token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Noma'lum"
@@ -1945,7 +1961,7 @@ msgstr "Yangilash"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Yangilandi"
@@ -1968,20 +1984,20 @@ msgstr "Ishlash vaqti"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Ishlatilishi"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} ishlatilishi"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "{displayName} saqlash pool'ining ishlatilishi"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Ishlatilgan"
@@ -2058,7 +2074,7 @@ msgstr "Windows buyrug'i"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows buyrug'i"
msgid "Write"
msgstr "Yozish"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Yozish xatolari"
@@ -2087,3 +2103,4 @@ msgstr "Ha"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Foydalanuvchi sozlamalaringiz yangilandi."
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: vi\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: Vietnamese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5 phút"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "Hành động"
@@ -196,7 +196,7 @@ msgstr "Bạn có chắc không?"
msgid "Automatic copy requires a secure context."
msgstr "Sao chép tự động yêu cầu một ngữ cảnh an toàn."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "Khả dụng"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "Khả năng"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "Dung lượng"
@@ -391,14 +391,14 @@ msgstr "Kiểm tra dịch vụ giám sát của bạn"
msgid "Check your notification service"
msgstr "Kiểm tra dịch vụ thông báo của bạn"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "Lỗi checksum"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "Xóa"
@@ -411,7 +411,7 @@ msgstr "Nhấp vào container để xem thêm thông tin."
msgid "Click on a device to view more information."
msgstr "Nhấp vào thiết bị để xem thêm thông tin."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "Nhấp vào pool để xem chi tiết về vdev và dataset."
@@ -503,7 +503,7 @@ msgstr "Sao chép tên"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "Sao chép khóa công khai"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "Thất bại: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "Quạt"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "Trong <0>{min}</0> {min, plural, one {phút} other {phút}}"
msgid "Forgot password?"
msgstr "Quên mật khẩu?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "Trống"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "Lưới"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "Sức khỏe"
@@ -1146,7 +1146,7 @@ msgstr "Mức sử dụng bộ nhớ của các container"
msgid "Model"
msgstr "Mô hình"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "Điểm gắn kết"
@@ -1185,7 +1185,7 @@ msgstr "Đơn vị mạng"
msgid "No"
msgstr "Không"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "Không có dữ liệu chi tiết cho pool này."
@@ -1212,7 +1212,7 @@ msgstr "Không có thuộc tính S.M.A.R.T. nào khả dụng cho thiết bị n
msgid "No systems found."
msgstr "Không tìm thấy hệ thống."
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "Không có"
@@ -1255,7 +1255,7 @@ msgstr "Mật khẩu một lần"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Mở menu"
@@ -1346,6 +1346,10 @@ msgstr "Vĩnh viễn"
msgid "Persistence"
msgstr "Tính bền vững"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "Dung lượng thiết bị vật lý. Dung lượng khả dụng thực tế không xác định. Cảnh báo sử dụng đĩa pool đã bị tắt."
#: src/components/routes/settings/notifications.tsx
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."
@@ -1379,11 +1383,11 @@ msgstr "Vui lòng xem <0>tài liệu</0> để biết hướng dẫn."
msgid "Please sign in to your account"
msgstr "Vui lòng đăng nhập vào tài khoản của bạn"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Tình trạng pool"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Mức sử dụng pool"
@@ -1416,7 +1420,7 @@ msgstr "Tiến trình đã khởi động"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "Khóa công khai"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "Độ sâu hàng đợi"
msgid "Quiet Hours"
msgstr "Giờ yên tĩnh"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "Thô"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Mức sử dụng thô của pool lưu trữ {displayName}"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "Giờ yên tĩnh"
msgid "Read"
msgstr "Đọc"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "Lỗi đọc"
@@ -1454,7 +1469,7 @@ msgstr "Đã nhận"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "Làm mới"
@@ -1643,7 +1658,7 @@ msgstr "Thời gian bắt đầu"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Trạng thái"
@@ -1671,7 +1686,7 @@ msgstr "Sử dụng Hoán đổi"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "Đổi giao diện"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "Hệ thống"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "Tốc độ quạt hệ thống (RPM)"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "Thao tác này sẽ xóa vĩnh viễn tất cả các bản ghi đã ch
msgid "Throughput of {extraFsName}"
msgstr "Thông lượng của {extraFsName}"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "Thông lượng ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Thông lượng của pool lưu trữ {displayName}"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "Tổng dữ liệu gửi đi cho mỗi giao diện"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "Tổng thời gian đọc/ghi (có thể vượt quá 100%)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "Kích hoạt khi sử dụng bất kỳ đĩa nào vượt quá ngưỡn
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "Loại"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "Token chung"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "Không xác định"
@@ -1945,7 +1961,7 @@ msgstr "Cập nhật"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Đã cập nhật"
@@ -1968,20 +1984,20 @@ msgstr "Thời gian hoạt động"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Sử dụng"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "Mức sử dụng ZFS pool {poolName}"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Mức sử dụng của pool lưu trữ {displayName}"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "Đã sử dụng"
@@ -2058,7 +2074,7 @@ msgstr "Lệnh Windows"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Lệnh Windows"
msgid "Write"
msgstr "Ghi"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "Lỗi ghi"
@@ -2087,3 +2103,4 @@ msgstr "Có"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Cài đặt người dùng của bạn đã được cập nhật."
+54 -37
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5 分钟"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "操作"
@@ -196,7 +196,7 @@ msgstr "您确定吗?"
msgid "Automatic copy requires a secure context."
msgstr "自动复制所需的安全上下文。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "可用"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "能力"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "容量"
@@ -391,14 +391,14 @@ msgstr "检查您的监控服务"
msgid "Check your notification service"
msgstr "检查您的通知服务"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "校验和错误"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "清除"
@@ -411,7 +411,7 @@ msgstr "点击容器查看更多信息。"
msgid "Click on a device to view more information."
msgstr "点击设备查看更多信息。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "点击存储池以查看 vdev 和数据集详情。"
@@ -875,8 +875,8 @@ msgstr "风扇"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "持续<0>{min}</0> {min, plural, one {分钟} other {分钟}}"
msgid "Forgot password?"
msgstr "忘记密码?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "可用空间"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "网格"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "健康"
@@ -1146,7 +1146,7 @@ msgstr "容器内存使用量"
msgid "Model"
msgstr "型号"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "挂载点"
@@ -1185,7 +1185,7 @@ msgstr "网络单位"
msgid "No"
msgstr "否"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "此存储池没有可用的详细数据。"
@@ -1212,7 +1212,7 @@ msgstr "此设备没有可用的 S.M.A.R.T. 属性。"
msgid "No systems found."
msgstr "未找到系统。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "无"
@@ -1255,7 +1255,7 @@ msgstr "一次性密码"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "打开菜单"
@@ -1346,6 +1346,10 @@ msgstr "永久"
msgid "Persistence"
msgstr "持久性"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "物理设备空间。真实可用容量未知。存储池磁盘使用率警报已禁用。"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "请<0>配置 SMTP 服务器</0>以确保警报被传递。"
@@ -1379,11 +1383,11 @@ msgstr "请参阅<0>文档</0>以获取说明。"
msgid "Please sign in to your account"
msgstr "请登录您的账户"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "存储池健康状态"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "存储池使用率"
@@ -1432,10 +1436,21 @@ msgstr "队列深度"
msgid "Quiet Hours"
msgstr "静默时间"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "原始"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "存储池 {displayName} 的原始使用量"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "静默时间"
msgid "Read"
msgstr "读取"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "读取错误"
@@ -1454,7 +1469,7 @@ msgstr "接收"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "刷新"
@@ -1643,7 +1658,7 @@ msgstr "开始时间"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "状态"
@@ -1772,9 +1787,9 @@ msgstr "这将永久删除数据库中所有选定的记录。"
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的吞吐量"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS 存储池 {poolName} 吞吐量"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "存储池 {displayName} 吞吐量"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "当任何磁盘的使用率超过阈值时触发"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "类型"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "通用令牌"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "未知"
@@ -1945,7 +1961,7 @@ msgstr "更新"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "更新于"
@@ -1968,20 +1984,20 @@ msgstr "运行时间"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "使用"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS 存储池 {poolName} 使用"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "存储池 {displayName} 使用"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "已用"
@@ -2058,7 +2074,7 @@ msgstr "Windows 安装命令"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows 安装命令"
msgid "Write"
msgstr "写入"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "写入错误"
@@ -2087,3 +2103,4 @@ msgstr "是"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "您的用户设置已更新。"
+60 -43
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:46\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional, Hong Kong\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5 分鐘"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "操作"
@@ -196,7 +196,7 @@ msgstr "您確定嗎?"
msgid "Automatic copy requires a secure context."
msgstr "自動複製需要安全的上下文。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "可用"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "能力"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "容量"
@@ -391,14 +391,14 @@ msgstr "檢查您的監控服務"
msgid "Check your notification service"
msgstr "檢查您的通知服務"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "校驗和錯誤"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "清除"
@@ -411,7 +411,7 @@ msgstr "點擊容器以查看更多資訊。"
msgid "Click on a device to view more information."
msgstr "點擊裝置以查看更多資訊。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "按一下 pool 以查看 vdev 和 dataset 的詳細資料。"
@@ -503,7 +503,7 @@ msgstr "複製名稱"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy public key"
msgstr ""
msgstr "複製公鑰"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
@@ -869,14 +869,14 @@ msgstr "失敗: {0}"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "Fans"
msgstr ""
msgstr "風扇"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "持續<0>{min}</0> {min, plural, one {分鐘} other {分鐘}}"
msgid "Forgot password?"
msgstr "忘記密碼?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "可用空間"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "網格"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "健康狀態"
@@ -1146,7 +1146,7 @@ msgstr "容器記憶體使用量"
msgid "Model"
msgstr "型號"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "掛載點"
@@ -1185,7 +1185,7 @@ msgstr "網路單位"
msgid "No"
msgstr "否"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "此 pool 沒有可用的詳細資料。"
@@ -1212,7 +1212,7 @@ msgstr "此裝置沒有可用的 S.M.A.R.T. 屬性。"
msgid "No systems found."
msgstr "未找到系統。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "無"
@@ -1255,7 +1255,7 @@ msgstr "一次性密碼"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "開啟選單"
@@ -1346,6 +1346,10 @@ msgstr "永久"
msgid "Persistence"
msgstr "持久性"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "實體裝置空間。真實可用容量未知。Pool 磁碟使用量警報已停用。"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "請<0>配置SMTP伺服器</0>以確保警報被傳送。"
@@ -1379,11 +1383,11 @@ msgstr "請參閱<0>文件</0>以取得說明。"
msgid "Please sign in to your account"
msgstr "請登入您的帳號"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "Pool 健康狀態"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "Pool 使用量"
@@ -1416,7 +1420,7 @@ msgstr "進程啟動"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Public key"
msgstr ""
msgstr "公鑰"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
@@ -1432,10 +1436,21 @@ msgstr "隊列深度"
msgid "Quiet Hours"
msgstr "靜音時段"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "原始"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "Pool {displayName} 的原始使用量"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "靜音時段"
msgid "Read"
msgstr "讀取"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "讀取錯誤"
@@ -1454,7 +1469,7 @@ msgstr "接收"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "重新整理"
@@ -1643,7 +1658,7 @@ msgstr "開始時間"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "狀態"
@@ -1671,7 +1686,7 @@ msgstr "交換使用"
#: src/components/mode-toggle.tsx
#: src/components/mode-toggle.tsx
msgid "Switch theme"
msgstr ""
msgstr "切換主題"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
@@ -1690,7 +1705,7 @@ msgstr "系統"
#: src/components/routes/system/charts/sensor-charts.tsx
msgid "System fan speeds (RPM)"
msgstr ""
msgstr "系統風扇速度(RPM"
#: src/components/routes/system/charts/load-average-chart.tsx
msgid "System load averages over time"
@@ -1772,9 +1787,9 @@ msgstr "這將從資料庫中永久刪除所有選定的記錄。"
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的吞吐量"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} 輸送量"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "Pool {displayName} 的吞吐量"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1819,7 +1834,7 @@ msgstr "每個介面的總傳送資料量"
#: src/components/routes/system/disk-io-sheet.tsx
msgctxt "Disk I/O"
msgid "Total time spent on read/write (can exceed 100%)"
msgstr ""
msgstr "讀取/寫入所用的總時間(可能超過 100%)"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
@@ -1897,6 +1912,7 @@ msgstr "當任何磁碟的使用超過閾值時觸發"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "類型"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "通用令牌"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "未知"
@@ -1945,7 +1961,7 @@ msgstr "更新"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "已更新"
@@ -1968,20 +1984,20 @@ msgstr "運行時間"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "使用"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS pool {poolName} 使用量"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "Pool {displayName} 使用量"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "已用"
@@ -2058,7 +2074,7 @@ msgstr "Windows 指令"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows 指令"
msgid "Write"
msgstr "寫入"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "寫入錯誤"
@@ -2087,3 +2103,4 @@ msgstr "是"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "您的用戶設置已更新。"
+54 -37
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-09-02 21:43\n"
"PO-Revision-Date: 2026-09-10 01:45\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -97,7 +97,7 @@ msgstr "5 分鐘"
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Actions"
msgstr "操作"
@@ -196,7 +196,7 @@ msgstr "您確定嗎?"
msgid "Automatic copy requires a secure context."
msgstr "只有在受保護的環境(HTTPS)才能自動複製。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Disk space available"
msgid "Available"
msgstr "可用"
@@ -338,7 +338,7 @@ msgid "Capabilities"
msgstr "能力"
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Capacity"
msgstr "容量"
@@ -391,14 +391,14 @@ msgstr "檢查您的監控服務"
msgid "Check your notification service"
msgstr "檢查您的通知服務"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Checksum errors"
msgstr "校驗和錯誤"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Clear"
msgstr "清除"
@@ -411,7 +411,7 @@ msgstr "點擊容器以查看更多資訊。"
msgid "Click on a device to view more information."
msgstr "點擊裝置以查看更多資訊。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Click on a pool to view vdev and dataset details."
msgstr "點選儲存池以檢視 vdev 和資料集詳細資訊。"
@@ -875,8 +875,8 @@ msgstr "風扇"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/chart-card.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
@@ -898,8 +898,8 @@ msgstr "持續<0>{min}</0> {min, plural, one {分鐘} other {分鐘}}"
msgid "Forgot password?"
msgstr "忘記密碼?"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgctxt "Free space"
msgid "Free"
msgstr "可用空間"
@@ -948,7 +948,7 @@ msgid "Grid"
msgstr "網格"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Health"
msgstr "健康狀態"
@@ -1146,7 +1146,7 @@ msgstr "容器的記憶體使用量"
msgid "Model"
msgstr "型號"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Mountpoint"
msgstr "掛載點"
@@ -1185,7 +1185,7 @@ msgstr "網路單位"
msgid "No"
msgstr "否"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "No detail data for this pool."
msgstr "此儲存池沒有可用的詳細資料。"
@@ -1212,7 +1212,7 @@ msgstr "此裝置沒有可用的 S.M.A.R.T. 屬性。"
msgid "No systems found."
msgstr "找不到任何系統。"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "None"
msgstr "無"
@@ -1255,7 +1255,7 @@ msgstr "一次性密碼"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "開啟選單"
@@ -1346,6 +1346,10 @@ msgstr "永久"
msgid "Persistence"
msgstr "持久性"
#: src/components/routes/system/raw-capacity-label.tsx
msgid "Physical device space. True usable capacity is unknown. Pool disk usage alerts are disabled."
msgstr "實體裝置空間。真實可用容量未知。儲存池磁碟使用率警報已停用。"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "請<0>設定一個 SMTP 伺服器</0>以確保能傳送警報。"
@@ -1379,11 +1383,11 @@ msgstr "請參閱<0>文件</0>以取得說明。"
msgid "Please sign in to your account"
msgstr "請登入您的帳號"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Pool Health"
msgstr "儲存池健康狀態"
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Pool Usage"
msgstr "儲存池使用率"
@@ -1432,10 +1436,21 @@ msgstr "隊列深度"
msgid "Quiet Hours"
msgstr "靜音時段"
#: src/components/routes/system/raw-capacity-label.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Raw"
msgstr "原始"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Raw usage of storage pool {displayName}"
msgstr "儲存池 {displayName} 的原始使用量"
#. Disk read
#. Disk read
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -1443,7 +1458,7 @@ msgstr "靜音時段"
msgid "Read"
msgstr "讀取"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Read errors"
msgstr "讀取錯誤"
@@ -1454,7 +1469,7 @@ msgstr "接收"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Refresh"
msgstr "重新整理"
@@ -1643,7 +1658,7 @@ msgstr "開始時間"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/quiet-hours.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "狀態"
@@ -1772,9 +1787,9 @@ msgstr "這將從資料庫中永久刪除所有選定的記錄。"
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的傳輸速率"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Throughput of ZFS pool {poolName}"
msgstr "ZFS 儲存池 {poolName} 吞吐量"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Throughput of storage pool {displayName}"
msgstr "儲存池 {displayName} 的傳輸速率"
#: src/components/routes/settings/general.tsx
msgid "Time format"
@@ -1897,6 +1912,7 @@ msgstr "當任何磁碟使用率超過閾值時觸發"
#: 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/storage-pools-table.tsx
msgid "Type"
msgstr "類型"
@@ -1919,7 +1935,7 @@ msgid "Universal token"
msgstr "通用 Token"
#. Context: Battery state
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/lib/i18n.ts
msgid "Unknown"
msgstr "未知"
@@ -1945,7 +1961,7 @@ msgstr "更新"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "已更新"
@@ -1968,20 +1984,20 @@ msgstr "運行時間"
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/gpu-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "使用量"
#: src/components/routes/system/charts/zfs-charts.tsx
msgid "Usage of ZFS pool {poolName}"
msgstr "ZFS 儲存池 {poolName} 使用"
#: src/components/routes/system/charts/storage-pool-charts.tsx
msgid "Usage of storage pool {displayName}"
msgstr "儲存池 {displayName} 使用"
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/charts/memory-charts.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Used"
msgstr "已使用"
@@ -2058,7 +2074,7 @@ msgstr "Windows 指令"
#. Disk write
#. Disk write
#: src/components/routes/system/charts/disk-charts.tsx
#: src/components/routes/system/charts/zfs-charts.tsx
#: src/components/routes/system/charts/storage-pool-charts.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
#: src/components/routes/system/disk-io-sheet.tsx
@@ -2066,7 +2082,7 @@ msgstr "Windows 指令"
msgid "Write"
msgstr "寫入"
#: src/components/routes/system/zfs-table.tsx
#: src/components/routes/system/storage-pools-table.tsx
msgid "Write errors"
msgstr "寫入錯誤"
@@ -2087,3 +2103,4 @@ msgstr "是"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "已更新您的使用者設定"
+8
View File
@@ -181,6 +181,12 @@ export interface GPUData {
}
export interface ZfsPool {
/** Friendly name; map keys are stable pool identities. */
n?: string
/** Equivalent filesystem charts are already displayed. */
hu?: boolean
hi?: boolean
raw?: boolean
/** total capacity (GiB) */
d: number
/** allocated (GiB) */
@@ -217,6 +223,8 @@ export interface ZfsDataset {
}
export interface ZfsPoolRecord extends RecordModel {
display_name?: string
raw?: boolean
system: string
name: string
health: string
+2 -2
View File
@@ -2,9 +2,9 @@ apiVersion: v1
description: Installs beszel-agent in kubernetes
home: https://github.com/henrygd/beszel/tree/main/supplemental/helm/beszel-agent
name: beszel-agent
appVersion: "0.18.8"
appVersion: "0.19.0"
# Bump this version when publishing chart changes.
version: 0.1.5
version: 0.1.6
sources:
- https://github.com/henrygd/beszel/tree/main/supplemental/helm/beszel-agent
- https://www.beszel.dev/
+3 -3
View File
@@ -80,7 +80,7 @@ Essential parameters to configure:
| `secret.sshKey` | `ssh-key` | Key name in the secret for the SSH public key |
| `secret.tokenKey` | `token` | Key name in the secret for the authentication token |
| `image.repository` | `henrygd/beszel-agent` | Container image |
| `image.tag` | Chart AppVersion (0.18.8) | Image version |
| `image.tag` | Chart AppVersion (0.19.0) | Image version |
| `hostNetwork` | `false` | Use host network for network monitoring |
| `tolerations` | Allows all taints | Tolerations for running on tainted nodes |
@@ -385,7 +385,7 @@ helm upgrade beszel-agent ./beszel-agent \
# Change image version
helm upgrade beszel-agent ./beszel-agent \
--set image.tag="0.18.8"
--set image.tag="0.19.0"
```
### Restart All Agents
@@ -522,7 +522,7 @@ kubectl get secret beszel-agent -o jsonpath='{.data.ssh-key}' | base64 -d
## Chart Information
- **Chart Version**: 0.1.0
- **App Version**: 0.18.8
- **App Version**: 0.19.0
- **Kubernetes Version**: 1.19+
- **Maintainer**: cloudwithdan (nikoloskid@pm.me)
+2 -2
View File
@@ -2,9 +2,9 @@ apiVersion: v1
description: Installs beszel-hub in kubernetes
home: https://github.com/henrygd/beszel/tree/main/supplemental/helm/beszel-hub
name: beszel-hub
appVersion: "0.18.8"
appVersion: "0.19.0"
# Bump this version when publishing chart changes.
version: 0.1.5
version: 0.1.6
sources:
- https://github.com/henrygd/beszel/tree/main/supplemental/helm/beszel-hub
- https://www.beszel.dev/

Some files were not shown because too many files have changed in this diff Show More