2.2-stable

This commit is contained in:
Alexander Renz 2024-12-24 11:35:16 +01:00
parent 0933482f64
commit 95cbd11ba3
8 changed files with 541 additions and 82 deletions

133
README.MD
View File

@ -69,8 +69,41 @@ Setting `NetworkEvents = false` in the server configuration disables the logging
The `precaching` feature allows the server to pre-cache storage paths for faster access. This can improve performance by reducing the time needed to access frequently used storage paths.
### Thumbnail Creation
Set `thumbnail` to true in the `[server]` section of `config.toml` to enable image thumbnail generation.
### Deduplication
Set `enabled` to true in the `[deduplication]` section of `config.toml` to enable file deduplication. Specify the `storagepath` where deduplicated files will be stored.
---
## Deduplication
Set `enabled` to true in the `[deduplication]` section of `config.toml` to enable file deduplication. Specify the `directory` where deduplicated files will be stored.
### Example `config.toml`
```toml
[deduplication]
enabled = true
directory = "/mnt/hmac-storage/deduplication/"
```
## Thumbnails
Set `enabled` to true in the `[thumbnails]` section of `config.toml` to enable thumbnail creation. Specify the `directory` where thumbnails will be stored and the `size` of the thumbnails.
### Example `config.toml`
```toml
[thumbnails]
enabled = true
directory = "/mnt/hmac-storage/thumbnails/"
size = "200x200"
```
## Example `config.toml`
```toml
@ -89,6 +122,7 @@ AutoAdjustWorkers = true # Enable auto-adjustment for worker scaling
NetworkEvents = false # Disable logging and tracking of network-related events
PIDFilePath = "./hmac_file_server.pid" # Path to PID file
Precaching = true # Enable pre-caching of storage paths
ThumbnailEnabled = false # Whether to create thumbnails for uploaded images
[timeouts]
ReadTimeout = "480s"
@ -132,6 +166,105 @@ UploadQueueSize = 5000
[file]
FileRevision = 1 # Revision number for file handling
[deduplication]
enabled = true
storagepath = "/mnt/nfs_vol01/hmac-file-server/deduplication/"
```
---
## HMAC File Server - Version 2.2 Stable
Below is an example configuration file (config.toml) you can use as a reference (with sensitive data removed):
```toml
[server]
listenport = "8080"
unixsocket = false
storagepath = "/mnt/nfs_vol01/hmac-file-server/"
loglevel = "debug"
logfile = "/var/log/hmac-file-server.log"
metricsenabled = true
metricsport = "9090"
deduplicationenabled = true
minfreebytes = "5GB"
filettl = "2Y"
autoadjustworkers = true
networkevents = false
pidfilepath = "./hmac-file-server.pid"
precaching = true
[deduplication]
enabled = true
directory = "/mnt/nfs_vol01/hmac-storage/deduplication/"
[thumbnails]
enabled = true
directory = "/mnt/nfs_vol01/hmac-file-server/thumbnails/"
size = "200x200"
[iso]
enabled = false
size = "1TB"
mountpoint = "/mnt/nfs_vol01/hmac-file-server/iso/"
charset = "utf-8"
[timeouts]
readtimeout = "3600s"
writetimeout = "3600s"
idletimeout = "3600s"
[security]
secret = "stellar-wisdom-orbit-echo"
[versioning]
enableversioning = false
maxversions = 1
[uploads]
resumableuploadsenabled = false
chunkeduploadsenabled = true
chunksize = "32MB"
allowedextensions = [
".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif",
".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4",
".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm",
".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg"
]
[downloads]
chunkeddownloadsenabled = false
chunksize = "32MB"
allowedextensions = [
".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif",
".bmp", ".tiff", ".svg", ".webp", ".wav", ".mp4",
".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm",
".mpeg", ".mpg", ".m4v", ".3gp", ".3g2", ".mp3", ".ogg"
]
[clamav]
clamavenabled = true
clamavsocket = "/var/run/clamav/clamd.ctl"
numscanworkers = 4
scanfileextensions = [
".exe", ".dll", ".bin", ".com", ".bat",
".sh", ".php", ".js"
]
[redis]
redisenabled = true
redisdbindex = 0
redisaddr = "localhost:6379"
redispassword = ""
redishealthcheckinterval = "120s"
[workers]
numworkers = 4
uploadqueuesize = 5000
[file]
filerevision = 1
```
---

View File

@ -1,10 +1,10 @@
# Release Notes - hmac-file-server v2.1-stable
# Release Notes - hmac-file-server v2.2-stable
**Release Date:** April 27, 2024
**Release Date:** December 24, 2024
## Overview
We are excited to announce the release of **hmac-file-server v2.1-stable**. This version brings significant enhancements, new features, and important bug fixes to improve the performance, security, and usability of the HMAC File Server. Below are the detailed changes and updates included in this release.
We are excited to announce the release of **hmac-file-server v2.2-stable**. This version brings significant enhancements, new features, and important bug fixes to improve the performance, security, and usability of the HMAC File Server. Below are the detailed changes and updates included in this release.
## New Features
@ -124,7 +124,7 @@ We are excited to announce the release of **hmac-file-server v2.1-stable**. This
2. **Update Application:**
- Pull the latest version from the repository:
```sh
git pull origin v2.1-stable
git pull origin v2.2-stable
```
- Alternatively, download the latest release from the [releases page](https://github.com/PlusOne/hmac-file-server/releases).
@ -154,3 +154,70 @@ For any issues or questions regarding this release, please open an issue on our
---
*Thank you for using hmac-file-server! We hope this release enhances your experience and meets your needs effectively.*
## Release Notes - Version 2.2 Stable
### What's New in Version 2.2:
- **Enhanced Deduplication Mechanism:**
- Fixed issues related to SHA256 checksum validation, ensuring accurate file deduplication.
- Improved error handling for deduplication processes, preventing failures when referencing existing files.
- **ClamAV and Redis Optimizations:**
- Streamlined ClamAV initialization for faster malware scanning.
- Optimized Redis connection handling for better caching performance and reliability.
- **Configuration Improvements:**
- Introduced new configuration parameters for finer control over deduplication directories and checksum algorithms.
- Enhanced `config.toml` validation to ensure all necessary fields are correctly set, reducing runtime errors.
- **Logging Enhancements:**
- Improved log formatting for easier troubleshooting and monitoring.
- Added detailed logs for deduplication steps, providing clearer visibility into the deduplication process.
- **Performance Upgrades:**
- Further optimized auto-adjusting worker pools to handle higher loads with minimal latency.
- Reduced memory footprint during peak operations, ensuring consistent performance.
### Key Fixes:
- **Deduplication Directory Validation:**
- Resolved issues where the deduplication directory was not correctly recognized, preventing file reference errors.
- **Error Handling Enhancements:**
- Improved error messages and fallback mechanisms for ClamAV and Redis initialization failures.
- **Configuration Cleanup:**
- Removed deprecated parameters and streamlined configuration settings for easier management and clarity.
### Upgrading to Version 2.2:
1. **Pull the Latest Release:**
```sh
git pull https://github.com/PlusOne/hmac-file-server.git
```
2. **Update Dependencies:**
```sh
go mod tidy
```
3. **Review and Update `config.toml`:**
- Ensure all new configuration parameters are set.
- Validate the `deduplication.directory` path and permissions.
- Example `deduplication` section:
```toml
[deduplication]
enabled = true
directory = "/mnt/hmac-storage/deduplication/"
checksum_algorithm = "sha256" # New parameter for checksum selection
```
4. **Restart the Application:**
```sh
./hmac-file-server
```
### Enjoy Enhanced Performance and Security!
With Version 2.2, experience more reliable file handling, robust security measures, and optimized performance. Upgrade now to take advantage of these powerful improvements!

View File

@ -2,7 +2,7 @@
listenport = "8080"
unixsocket = false
storagepath = "./uploads"
loglevel = "debug"
loglevel = "debug"Q
logfile = "./hmac-file-server.log"
metricsenabled = true
metricsport = "8081"
@ -15,6 +15,7 @@ temppath = "/tmp/hmac"
loggingjson = false
pidfilepath = "./hmac_file_server.pid"
cleanuponexit = true
precaching = true
[iso]
enabled = false

Binary file not shown.

View File

@ -0,0 +1,119 @@
time="2024-12-04T17:22:02+01:00" level=info msg="========================================"
time="2024-12-04T17:22:02+01:00" level=info msg=" HMAC File Server - v2.0-dev "
time="2024-12-04T17:22:02+01:00" level=info msg=" Secure File Handling with HMAC Auth "
time="2024-12-04T17:22:02+01:00" level=info msg="========================================"
time="2024-12-04T17:22:02+01:00" level=info msg="Features: Prometheus Metrics, Chunked Uploads, ClamAV Scanning"
time="2024-12-04T17:22:02+01:00" level=info msg="Build Date: 2024-10-28"
time="2024-12-04T17:22:02+01:00" level=info msg="Operating System: linux"
time="2024-12-04T17:22:02+01:00" level=info msg="Architecture: amd64"
time="2024-12-04T17:22:02+01:00" level=info msg="Number of CPUs: 8"
time="2024-12-04T17:22:02+01:00" level=info msg="Go Version: go1.22.0"
time="2024-12-04T17:22:02+01:00" level=info msg="Total Memory: 15684 MB"
time="2024-12-04T17:22:02+01:00" level=info msg="Free Memory: 2378 MB"
time="2024-12-04T17:22:02+01:00" level=info msg="Used Memory: 5770 MB"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="CPU Model: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz, Cores: 1, Mhz: 4900.000000"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /, Total: 465 GB, Free: 58 GB, Used: 383 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/backupz/6, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/brave/458, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/brave/456, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/bare/5, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/canonical-livepatch/282, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/canonical-livepatch/286, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/cameractrls/35, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/cameractrls/34, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/cmake/1425, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/cmake/1429, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core/17200, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core18/2846, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core18/2829, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core20/2379, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core20/2434, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core24/490, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core22/1663, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core24/609, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/drawio/228, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/duplicity/513, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/drawio/230, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/duplicity/517, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/dynahack/32, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/firefox/5273, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/firefox/5361, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/firmware-updater/127, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/firmware-updater/147, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gaming-graphics-core22/166, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gaming-graphics-core22/184, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gnome-3-28-1804/198, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gnome-3-34-1804/93, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gnome-3-38-2004/143, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gnome-42-2204/176, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/godot/45, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gnome-46-2404/48, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/hello-world/29, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/gtk-common-themes/1535, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/kf5-5-110-qt-5-15-11-core22/3, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/kf5-5-113-qt-5-15-11-core22/1, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/marble/32, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/master-pdf-editor-5/20, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/master-pdf-editor-5/21, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/mesa-2404/143, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/mesa-core22/311, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/micropolis/168, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/mkcron/2, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/obs-studio/1302, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/qownnotes/11552, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/qownnotes/11560, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/qt513/24, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/remmina/6419, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/retroarch/2879, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snap-store/1244, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snapd/21759, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snapd/23258, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snapd-desktop-integration/247, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/steam/200, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snapd-desktop-integration/253, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/sublime-text/156, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/steam/206, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/sublime-text/177, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/suckit/49, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/teleguard-desktop/91, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/thunderbird/571, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/thunderbird/581, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/wine-platform-7-stable-core20/6, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /var/snap/firefox/common/host-hunspell, Total: 465 GB, Free: 58 GB, Used: 383 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/winbox/171, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/video-downloader/1212, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/winbox/170, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/wine-platform-runtime-core20/146, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/wine-platform-runtime-core20/147, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /boot, Total: 1 GB, Free: 1 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /boot/efi, Total: 1 GB, Free: 1 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /media/renz/external, Total: 116 GB, Free: 80 GB, Used: 29 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/video-downloader/1221, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/core22/1722, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/snap-store/1247, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Disk Mountpoint: /snap/teleguard-desktop/94, Total: 0 GB, Free: 0 GB, Used: 0 GB"
time="2024-12-04T17:22:02+01:00" level=info msg="Hostname: xps7390"
time="2024-12-04T17:22:02+01:00" level=info msg="Uptime: 35037 seconds"
time="2024-12-04T17:22:02+01:00" level=info msg="Boot Time: 2024-12-04 07:38:06 +0100 CET"
time="2024-12-04T17:22:02+01:00" level=info msg="Platform: ubuntu"
time="2024-12-04T17:22:02+01:00" level=info msg="Platform Family: debian"
time="2024-12-04T17:22:02+01:00" level=info msg="Platform Version: 24.04"
time="2024-12-04T17:22:02+01:00" level=info msg="Kernel Version: 6.8.0-49-generic"
time="2024-12-04T17:22:02+01:00" level=info msg="Prometheus metrics initialized."
time="2024-12-04T17:22:02+01:00" level=info msg="Upload queue initialized with size: 1000"
time="2024-12-04T17:22:02+01:00" level=info msg="Upload, scan, and network event channels initialized."
time="2024-12-04T17:22:02+01:00" level=info msg="Initialized 4 upload workers"
time="2024-12-04T17:22:02+01:00" level=info msg="Upload worker 2 started."
time="2024-12-04T17:22:02+01:00" level=info msg="Upload worker 1 started."
time="2024-12-04T17:22:02+01:00" level=info msg="Upload worker 3 started."
time="2024-12-04T17:22:02+01:00" level=info msg="Upload worker 0 started."
time="2024-12-04T17:22:02+01:00" level=info msg="Starting HMAC file server v2.0-dev..."
time="2024-12-04T17:22:02+01:00" level=info msg="Metrics server started on port 9090"
time="2024-12-04T17:22:03+01:00" level=info msg="Received signal interrupt. Initiating shutdown..."

View File

@ -38,6 +38,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"gopkg.in/natefinch/lumberjack.v2"
"github.com/disintegration/imaging"
)
// parseSize converts a human-readable size string to bytes
@ -111,6 +112,7 @@ type ServerConfig struct {
NetworkEvents bool `mapstructure:"NetworkEvents"` // Added field
PrecachingEnabled bool `mapstructure:"precaching"` // Added field
PIDFilePath string `mapstructure:"pidfilepath"` // Added field
ThumbnailEnabled bool `mapstructure:"thumbnail"` // Added field
}
type TimeoutConfig struct {
@ -176,19 +178,32 @@ type DownloadsConfig struct {
ChunkSize string `mapstructure:"ChunkSize"`
}
type DeduplicationConfig struct {
Enabled bool `mapstructure:"enabled"`
Directory string `mapstructure:"directory"`
}
type ThumbnailsConfig struct {
Enabled bool `mapstructure:"enabled"`
Directory string `mapstructure:"directory"`
Size string `mapstructure:"size"`
}
type Config struct {
Server ServerConfig `mapstructure:"server"`
Timeouts TimeoutConfig `mapstructure:"timeouts"`
Security SecurityConfig `mapstructure:"security"`
Versioning VersioningConfig `mapstructure:"versioning"`
Uploads UploadsConfig `mapstructure:"uploads"`
Downloads DownloadsConfig `mapstructure:"downloads"`
ClamAV ClamAVConfig `mapstructure:"clamav"`
Redis RedisConfig `mapstructure:"redis"`
Workers WorkersConfig `mapstructure:"workers"`
File FileConfig `mapstructure:"file"`
ISO ISOConfig `mapstructure:"iso"`
Paste PasteConfig `mapstructure:"paste"`
Server ServerConfig `mapstructure:"server"`
Timeouts TimeoutConfig `mapstructure:"timeouts"`
Security SecurityConfig `mapstructure:"security"`
Versioning VersioningConfig `mapstructure:"versioning"`
Uploads UploadsConfig `mapstructure:"uploads"`
Downloads DownloadsConfig `mapstructure:"downloads"`
ClamAV ClamAVConfig `mapstructure:"clamav"`
Redis RedisConfig `mapstructure:"redis"`
Workers WorkersConfig `mapstructure:"workers"`
File FileConfig `mapstructure:"file"`
ISO ISOConfig `mapstructure:"iso"`
Paste PasteConfig `mapstructure:"paste"`
Deduplication DeduplicationConfig `mapstructure:"deduplication"`
Thumbnails ThumbnailsConfig `mapstructure:"thumbnails"`
}
type UploadTask struct {
@ -209,7 +224,7 @@ type NetworkEvent struct {
var (
conf Config
versionString string = "v2.1-stable"
versionString string = "v2.2-stable"
log = logrus.New()
uploadQueue chan UploadTask
networkEvents chan NetworkEvent
@ -549,6 +564,7 @@ func setDefaults() {
viper.SetDefault("server.NetworkEvents", true) // Set default
viper.SetDefault("server.precaching", true) // Set default for precaching
viper.SetDefault("server.pidfilepath", "/var/run/hmacfileserver.pid") // Set default for PID file path
viper.SetDefault("server.thumbnail", false) // Set default for thumbnail
_, err := parseTTL("1D")
if err != nil {
log.Warnf("Failed to parse TTL: %v", err)
@ -700,6 +716,48 @@ func validateConfig(conf *Config) error {
}
}
if conf.Deduplication.Enabled {
if conf.Deduplication.Directory == "" {
return fmt.Errorf("deduplication.directory is required when deduplication is enabled")
}
// Optionally, check if deduplication directory exists
if _, err := os.Stat(conf.Deduplication.Directory); os.IsNotExist(err) {
return fmt.Errorf("deduplication.directory does not exist: %s", conf.Deduplication.Directory)
}
}
if conf.Thumbnails.Enabled {
if conf.Thumbnails.Directory == "" {
return fmt.Errorf("thumbnails.directory is required when thumbnails are enabled")
}
// Optionally, check if thumbnails storage path exists
if _, err := os.Stat(conf.Thumbnails.Directory); os.IsNotExist(err) {
return fmt.Errorf("thumbnails.directory does not exist: %s", conf.Thumbnails.Directory)
}
}
// Verify that the primary storage path is accessible
if err := checkStoragePath(conf.Server.StoragePath); err != nil {
return fmt.Errorf("storage path check failed: %w", err)
}
return nil
}
func checkStoragePath(path string) error {
info, err := os.Stat(path)
if os.IsNotExist(err) {
log.Errorf("Storage path does not exist: %s", path)
return err
}
if err != nil {
log.Errorf("Error accessing storage path: %v", err)
return err
}
if !info.IsDir() {
return fmt.Errorf("not a directory: %s", path)
}
log.Infof("Verified storage path is accessible: %s", path)
return nil
}
@ -749,7 +807,7 @@ func logSystemInfo() {
cpuInfo, _ := cpu.Info()
uniqueCPUModels := make(map[string]bool)
for _, info := range cpuInfo {
if !uniqueCPUModels[info.ModelName] {
if (!uniqueCPUModels[info.ModelName]) {
log.Infof("CPU Model: %s, Cores: %d, Mhz: %f", info.ModelName, info.Cores, info.Mhz)
uniqueCPUModels[info.ModelName] = true
}
@ -815,6 +873,7 @@ func updateSystemMetrics(ctx context.Context) {
}
func fileExists(filePath string) (bool, int64) {
log.Debugf("Checking file existence: %s", filePath)
if cachedInfo, found := fileInfoCache.Get(filePath); found {
if info, ok := cachedInfo.(os.FileInfo); ok {
return !info.IsDir(), info.Size()
@ -950,7 +1009,23 @@ func processUpload(task UploadTask) error {
}
}
err := os.Rename(tempFilename, absFilename)
// Compute file hash first:
hashVal, err := computeSHA256(context.Background(), tempFilename)
if err != nil {
log.Errorf("Could not compute hash: %v", err)
return err
}
log.Infof("Computed hash for %s: %s", absFilename, hashVal)
// Check Redis for existing entry:
existingPath, redisErr := redisClient.Get(context.Background(), hashVal).Result()
if redisErr == nil && existingPath != "" {
log.Warnf("Duplicate upload detected. Using existing file at: %s", existingPath)
return nil
}
log.Debugf("Renaming temp file %s -> %s", tempFilename, absFilename)
err = os.Rename(tempFilename, absFilename)
defer func() {
if err != nil {
os.Remove(tempFilename)
@ -962,6 +1037,10 @@ func processUpload(task UploadTask) error {
}
log.Infof("File moved to final destination: %s", absFilename)
log.Debugf("Verifying existence immediately after rename: %s", absFilename)
exists, size := fileExists(absFilename)
log.Debugf("Exists? %v, Size: %d", exists, size)
// Gajim and Dino do not require a callback or acknowledgement beyond HTTP success.
callbackURL := r.Header.Get("Callback-URL")
if callbackURL != "" {
@ -970,6 +1049,9 @@ func processUpload(task UploadTask) error {
}
if conf.Server.DeduplicationEnabled {
log.Debugf("Performing deduplication check for %s", task.AbsFilename)
log.Debugf("Dedup check: Using hash %s to find existing path", hashVal)
log.Debugf("Existing path found in Redis: %s", existingPath)
err = handleDeduplication(context.Background(), absFilename)
if err != nil {
log.WithError(err).Error("Deduplication failed")
@ -989,6 +1071,25 @@ func processUpload(task UploadTask) error {
log.Infof("ISO container handled successfully for file: %s", absFilename)
}
if conf.Thumbnails.Enabled {
err = generateThumbnail(absFilename, conf.Thumbnails.Directory, conf.Thumbnails.Size)
if err != nil {
log.Errorf("Failed to generate thumbnail for %s: %v", absFilename, err)
uploadErrorsTotal.Inc()
return err
}
log.Infof("Thumbnail generated for %s", absFilename)
}
if redisClient != nil {
errSet := redisClient.Set(context.Background(), hashVal, absFilename, 0).Err()
if errSet != nil {
log.Warnf("Failed storing hash reference: %v", errSet)
} else {
log.Infof("Hash reference stored: %s -> %s", hashVal, absFilename)
}
}
log.WithFields(logrus.Fields{"file": absFilename}).Info("File uploaded and processed successfully")
uploadDuration.Observe(time.Since(startTime).Seconds())
@ -1359,16 +1460,24 @@ func handleUpload(w http.ResponseWriter, r *http.Request, absFilename, fileStore
}
func handleDownload(w http.ResponseWriter, r *http.Request, absFilename, fileStorePath string) {
log.Debugf("Attempting to download file from path: %s", absFilename)
fileInfo, err := getFileInfo(absFilename)
if err != nil {
log.WithError(err).Error("Failed to get file information")
http.Error(w, "Not Found", http.StatusNotFound)
downloadErrorsTotal.Inc()
return
} else if fileInfo.IsDir() {
log.Warn("Directory listing forbidden")
http.Error(w, "Forbidden", http.StatusForbidden)
downloadErrorsTotal.Inc()
log.Errorf("Failed to get file information for %s: %v", absFilename, err)
// If file doesn't exist, list directory contents for debug
if os.IsNotExist(err) {
dir := filepath.Dir(absFilename)
items, dirErr := os.ReadDir(dir)
if dirErr == nil {
for _, it := range items {
log.Debugf("Dir item: %s", it.Name())
}
} else {
log.Warnf("Could not read directory %s: %v", dir, dirErr)
}
}
http.NotFound(w, r)
return
}
@ -1959,44 +2068,40 @@ func checkStorageSpace(storagePath string, minFreeBytes int64) error {
}
func handleDeduplication(ctx context.Context, absFilename string) error {
log.Debugf("Starting deduplication for: %s", absFilename)
checksum, err := computeSHA256(ctx, absFilename)
if err != nil {
log.Errorf("Failed to compute SHA256 for %s: %v", absFilename, err)
return fmt.Errorf("checksum computation failed: %w", err)
log.Errorf("Failed to compute checksum for %s: %v", absFilename, err)
return err
}
log.Debugf("Computed checksum for %s: %s", absFilename, checksum)
existingPath, err := redisClient.Get(ctx, checksum).Result()
if err != nil {
if err == redis.Nil {
err = redisClient.Set(ctx, checksum, absFilename, 0).Err()
if err != nil {
log.Errorf("Redis error setting checksum %s: %v", checksum, err)
return fmt.Errorf("redis error: %w", err)
}
log.Infof("Stored new checksum %s for file %s", checksum, absFilename)
return nil
}
log.Errorf("Redis error fetching checksum %s: %v", checksum, err)
return fmt.Errorf("redis error: %w", err)
}
if existingPath != absFilename {
if _, err := os.Stat(existingPath); os.IsNotExist(err) {
log.Errorf("Existing file for checksum %s not found at %s", checksum, existingPath)
return fmt.Errorf("existing file not found: %w", err)
}
err = os.Link(existingPath, absFilename)
if err == redis.Nil {
log.Debugf("No existing file found for checksum %s", checksum)
err = redisClient.Set(ctx, checksum, absFilename, 0).Err()
if err != nil {
log.Errorf("Failed linking %s to %s: %v", existingPath, absFilename, err)
return fmt.Errorf("failed link: %w", err)
log.Errorf("Failed to set checksum in Redis: %v", err)
return err
}
log.Infof("Created hard link for duplicate file %s -> %s", absFilename, existingPath)
} else {
log.Infof("File %s already exists with same checksum", absFilename)
log.Infof("Stored checksum %s with path %s in Redis", checksum, absFilename)
return nil
} else if err != nil {
log.Errorf("Redis lookup error: %v", err)
return err
}
log.Infof("Found existing file for checksum %s at %s", checksum, existingPath)
err = os.Link(existingPath, absFilename)
if err != nil {
log.Errorf("Failed to create hard link: %v", err)
return err
}
log.Infof("Created hard link from %s to %s", absFilename, existingPath)
exists, size := fileExists(existingPath)
log.Debugf("Post-dedup check: Exists=%v, Size=%d at %s", exists, size, existingPath)
return nil
}
@ -2179,3 +2284,47 @@ func precacheStoragePath(dir string) error {
return nil
})
}
func generateThumbnail(originalPath, thumbnailDir, size string) error {
// Implement thumbnail generation logic here
// For example, using an image processing library like "github.com/disintegration/imaging"
img, err := imaging.Open(originalPath)
if err != nil {
return err
}
// Parse size (e.g., "200x200")
dimensions := strings.Split(size, "x")
if len(dimensions) != 2 {
return fmt.Errorf("invalid thumbnail size format: %s", size)
}
width, err := strconv.Atoi(dimensions[0])
if err != nil {
return fmt.Errorf("invalid thumbnail width: %s", dimensions[0])
}
height, err := strconv.Atoi(dimensions[1])
if err != nil {
return fmt.Errorf("invalid thumbnail height: %s", dimensions[1])
}
thumb := imaging.Thumbnail(img, width, height, imaging.Lanczos) // Example size
baseName := filepath.Base(originalPath)
thumbName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) + "_thumb" + filepath.Ext(baseName)
thumbPath := filepath.Join(thumbnailDir, thumbName)
err = os.MkdirAll(thumbnailDir, os.ModePerm)
if err != nil {
return err
}
err = imaging.Save(thumb, thumbPath)
if err != nil {
return err
}
return nil
}

12
go.mod
View File

@ -10,7 +10,7 @@ require (
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/shirou/gopsutil/v3 v3.24.5
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.19.0
github.com/spf13/viper v1.11.0
)
require (
@ -26,26 +26,24 @@ require (
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
golang.org/x/term v0.17.0 // indirect
golang.org/x/text v0.21.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/disintegration/imaging v1.6.2
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect

30
go.sum
View File

@ -3,11 +3,12 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e h1:rcHHSQqzCgvlwP0I/fQ8rQMn/MpHE5gWSLdtpxtP6KQ=
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e/go.mod h1:Byz7q8MSzSPkouskHJhX0er2mZY/m0Vj5bMeMCkkyY4=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
@ -60,9 +61,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
@ -81,10 +81,6 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
@ -95,21 +91,21 @@ github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44=
github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@ -126,14 +122,10 @@ github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=