2.2-stable
This commit is contained in:
parent
0933482f64
commit
95cbd11ba3
133
README.MD
133
README.MD
@ -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
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -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!
|
||||
|
@ -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.
119
cmd/server/hmac-file-server.log
Normal file
119
cmd/server/hmac-file-server.log
Normal 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..."
|
@ -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
12
go.mod
@ -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
30
go.sum
@ -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=
|
||||
|
Loading…
x
Reference in New Issue
Block a user