Commit Graph

158 Commits

Author SHA1 Message Date
Nick Bozhenko 40ba104838 Add comprehensive CI/CD improvements and test coverage
This commit introduces major enhancements to the CI/CD pipeline and testing infrastructure:

CI/CD Improvements:
- Consolidated modern and legacy CI workflows into a single comprehensive pipeline
- Removed all publishing functionality from CI (no longer needed)
- Added 8 new advanced testing jobs for pull requests:
  * advanced-coverage: Detailed coverage analysis with base branch comparison
  * performance-profile: CPU and memory profiling with benchmarks
  * fuzz-test: Automated fuzz testing for supported packages
  * deep-analysis: Multiple static analysis tools (shadow, ineffassign, gosec, staticcheck)
  * mutation-test: Tests effectiveness of test suite on changed files
  * dependency-audit: Security vulnerabilities and outdated dependency checks
  * stress-test: Race detection with 100 iterations and parallel testing
  * test-report-summary: Aggregates all reports into a single PR comment
- Enabled RUN_LONG_TESTS by default for thorough testing
- Added automatic PR comment generation with all test results

Testing Infrastructure:
- Added comprehensive test files across all packages to improve coverage
- Implemented unit tests for previously untested packages
- Added race condition tests for concurrent operations
- Created integration tests for API endpoints
- Added storage backend tests (etcd, goleveldb)
- Implemented command-line interface tests

Local Testing Support:
- Added act configuration for testing GitHub Actions locally
- Created docker-compose.ci.yml for full CI environment simulation
- Updated CONTRIBUTING.md with detailed local testing instructions

Documentation Updates:
- Added comprehensive CI documentation to CONTRIBUTING.md
- Removed obsolete references to Travis CI
- Updated Go version requirements to 1.24
- Added act usage instructions and examples

Other Improvements:
- Updated .gitignore to exclude coverage reports and build artifacts
- Added test-act.yml workflow for testing act functionality
- Created CI_SUMMARY.md documenting all CI capabilities

These changes transform aptly's CI from a basic testing pipeline into a comprehensive quality assurance system that provides immediate feedback on code quality, performance, security, and test effectiveness.
2025-07-10 12:00:54 -04:00
Nick Bozhenko cd30723750 feat: upgrade Go version and improve build system
- Upgrade Go version from 1.22 to 1.24 for better performance and security
- Add comprehensive golangci-lint configuration with:
  - Enable additional linters: bodyclose, dupl, exportloopref, gocognit, gocritic, gosec, prealloc
  - Configure complexity thresholds (cyclomatic: 15, cognitive: 20)
  - Set up security scanning with gosec
  - Add code quality rules with revive
  - Exclude test files from certain strict checks
- Update dependencies to latest stable versions:
  - aws-sdk-go-v2: various components updated
  - Azure SDK: updated to v1.18.0 for azcore
  - etcd client: remains at v3.6.1 for stability
  - prometheus client: updated to v1.22.0
  - zerolog: updated to v1.34.0
- Enhance logging utilities:
  - Add GetLogLevelOrDebug function for flexible log level configuration
  - Support "warning" as alias for "warn" level
  - Improve error handling for invalid log levels

These changes improve code quality checks, leverage latest Go features,
and ensure dependencies are up-to-date with security patches.
2025-07-10 10:21:48 -04:00
Nick Bozhenko f7b4df2f32 Add comprehensive test coverage for utils package improvements
This commit adds extensive test coverage for the recent improvements to the utils
package, achieving 91.5% coverage (up from 76.8%). The tests ensure the reliability
and correctness of critical utility functions.

## Test Files Added

### utils/config_accessor_test.go
Tests for the new safe accessor methods that prevent concurrent map access:
- TestGetFileSystemPublishRoots: Verifies safe copying of FileSystemPublishRoots map
- TestGetS3PublishRoots: Tests S3 publish roots accessor with nil map handling
- TestGetSwiftPublishRoots: Tests Swift publish roots accessor
- TestGetAzurePublishRoots: Tests Azure publish roots accessor
- All tests verify that modifications to returned maps don't affect the original

### utils/sanitize_test.go
Comprehensive tests for the SanitizePath security function:
- TestSanitizePath: Tests various path sanitization scenarios including:
  - Path traversal attempts (../)
  - Absolute paths (leading /)
  - Shell expansion attempts ($, `)
  - Environment variable references
  - Command injection attempts
- TestSanitizePathSecurity: Focused security tests for malicious inputs
- Ensures dangerous patterns are properly removed

### utils/checksum_extra_test.go
Tests for additional utility functions:
- TestComplete: Verifies ChecksumInfo.Complete() correctly identifies when all
  checksums (MD5, SHA1, SHA256, SHA512) are present
- TestSaveConfigRaw: Tests configuration file saving with error handling
- TestPackagePoolStorageUnmarshalJSON: Tests JSON unmarshaling for different
  storage types (Azure, Local, S3, Swift)

## Test Characteristics

1. **Comprehensive Coverage**: Tests cover both normal operation and edge cases
2. **Security Focus**: Special attention to security-sensitive functions
3. **Error Handling**: Tests verify proper error handling and edge cases
4. **Concurrency Safety**: Tests ensure thread-safe operations for shared data
5. **Real-world Scenarios**: Test cases based on actual usage patterns

## Testing Approach

All tests use the gopkg.in/check.v1 framework for consistency with the existing
codebase. Tests are designed to be:
- Fast: No external dependencies or network calls
- Deterministic: No random failures or timing dependencies
- Isolated: Each test is independent and can run in any order
- Clear: Test names and assertions clearly indicate what is being tested

These tests provide confidence that the recent race condition fixes and
improvements work correctly and don't introduce regressions.
2025-07-10 10:12:43 -04:00
Nick Bozhenko 463c34a38e Fix race conditions and improve etcd timeout handling
This commit addresses several critical race conditions and improves the reliability
of etcd operations through better timeout and retry handling.

## Race Condition Fixes

1. **Task Resource Management Bug**
   - Fixed incorrect variable usage in task/list.go:78
   - Was using completed task's resources instead of idle task's resources
   - This caused resource conflicts and potential deadlocks

2. **Database Channel Initialization**
   - Added sync.Once pattern to ensure thread-safe channel initialization
   - Prevents panic from concurrent access during startup
   - Created initDBRequests() function for safe initialization

3. **Published Storage Double-Checked Locking**
   - Implemented double-checked locking pattern in GetPublishedStorage
   - Reduces lock contention while preventing concurrent initialization
   - Improves performance for frequently accessed storage

4. **File Operation Synchronization**
   - Created FileLockRegistry in utils/filelock.go
   - Prevents concurrent file operations (create, rename, delete, link)
   - Implements deadlock prevention for multi-file operations
   - Critical for preventing file corruption during parallel publishes

5. **WaitGroup Miscount Prevention**
   - Added defer pattern to ensure Done() is always called
   - Protects against panics during task execution
   - Prevents "negative WaitGroup counter" errors

## etcd Improvements

1. **Timeout Protection**
   - Replaced global context.TODO() with per-operation timeout contexts
   - Default timeout: 60 seconds (configurable)
   - Prevents indefinite hangs when etcd is unresponsive

2. **Environment Variable Configuration**
   - APTLY_ETCD_TIMEOUT: Operation timeout (default: 60s)
   - APTLY_ETCD_DIAL_TIMEOUT: Connection timeout (default: 60s)
   - APTLY_ETCD_KEEPALIVE: Keep-alive timeout (default: 7200s)
   - APTLY_ETCD_MAX_MSG_SIZE: Max message size (default: 50MB)

3. **Retry Logic for Read Operations**
   - Get operations retry up to 3 times with exponential backoff
   - Only retries on temporary/network errors
   - Improves reliability without risking data inconsistency

4. **Enhanced Error Logging**
   - All etcd errors now logged with operation context
   - Replaces silent failures with actionable error messages
   - Improves debugging and monitoring capabilities

5. **Increased Message Size Limits**
   - Default increased from 10MB to 50MB
   - Configurable via environment variable
   - Prevents "message too large" errors for large operations

## Testing

- Added comprehensive tests for etcd timeout functionality
- Tests verify context timeout, retry logic, and configuration
- All existing tests pass with the new implementation

## Documentation

- Updated README.rst with etcd configuration section
- Documented all environment variables and their defaults
- Added examples and feature descriptions

These changes significantly improve the reliability and debuggability of aptly
when using etcd as the database backend, while also fixing critical race
conditions that could cause data corruption or service crashes.
2025-07-10 10:05:49 -04:00
Nick Bozhenko 660cee2ce3 Fix concurrent map access race conditions in config publish roots
This commit addresses critical race conditions that were causing "map write failed"
errors and pod crashes in production environments. The issue occurred when multiple
goroutines accessed shared configuration maps simultaneously without proper synchronization.

Root Cause:
The global utils.Config structure contains several maps (FileSystemPublishRoots,
S3PublishRoots, SwiftPublishRoots, AzurePublishRoots) that were being accessed
directly by concurrent HTTP handlers. While context.Config() uses a mutex, it
returns a pointer to the global config, leaving subsequent map access unprotected.

Changes Made:

1. Added safe accessor methods in utils/config.go:
   - GetFileSystemPublishRoots() - returns defensive copy of map
   - GetS3PublishRoots() - returns defensive copy of map
   - GetSwiftPublishRoots() - returns defensive copy of map
   - GetAzurePublishRoots() - returns defensive copy of map

2. Updated API handlers to use safe accessors:
   - api/s3.go: apiS3List() now uses GetS3PublishRoots()
   - api/router.go: reposListInAPIMode() now uses GetFileSystemPublishRoots()

3. Updated context package storage initialization:
   - context/context.go: GetPublishedStorage() now uses safe accessors for all
     storage type configurations (filesystem, s3, swift, azure)

Impact:
- Eliminates "concurrent map writes" panics that were causing service instability
- Prevents pod crashes and restarts in Kubernetes environments
- Ensures thread-safe access to configuration maps during concurrent API requests
- Minimal performance overhead (microseconds) from creating map copies

The fix is backward compatible and requires no configuration changes. The defensive
copying approach ensures that even if config maps are modified after initialization
(which shouldn't happen in production), concurrent readers remain safe.

This addresses the production issues observed in lf-aptly-* pods where multiple
parallel publish requests or API calls were triggering race conditions.
2025-07-10 01:35:09 -04:00
André Roth f7057a9517 go1.24: fix lint, unit and system tests
- development env: base on debian trixie with go1.24
- lint: run with default config
- fix lint errors
- fix unit tests
- fix system test
2025-04-26 13:29:50 +02:00
André Roth c07bf2b108 s3: add debug logs for commands
* initialize zerolog for commands
* Change default log format: remote colors and timestamp
2025-04-24 12:13:38 +02:00
André Roth e50a5e175f update documentation and man page 2024-12-11 12:02:52 +01:00
André Roth a7d6782176 add test and improve config error messages 2024-12-11 12:02:52 +01:00
André Roth a15d8a3f7b add test 2024-12-11 12:02:52 +01:00
André Roth 4e566b4692 fix tests and lint 2024-12-11 12:02:52 +01:00
André Roth 87a36633e9 group and order config items
and fix lint
2024-12-11 12:02:52 +01:00
André Roth 0e0189f0eb use yaml config file 2024-12-11 12:02:52 +01:00
André Roth a880a88fc0 yaml config 2024-12-11 12:02:52 +01:00
André Roth ea80f6d49c write commented json default config 2024-12-11 10:40:44 +01:00
André Roth cc1fc7ccfe allow comments in config file 2024-12-11 10:40:43 +01:00
André Roth 5ddb718eab support ~ in rootDir 2024-11-17 14:09:37 +01:00
André Roth cefc09a41b more sanitize 2024-10-11 14:11:09 +02:00
André Roth 57639c4adf Sanitize path api params
- fix path traversal complains by CodeQL
2024-10-11 12:56:08 +02:00
André Roth 1d1bd41bb8 add swagger support
- install swaggo
- add swagger config option
2024-10-01 01:07:09 +02:00
André Roth 32a3943821 support ~ in rootDir as home directory 2024-09-24 10:14:39 +02:00
André Roth f10acb3df8 etcd: fix db config and test
fix unit test for adapted config file
2024-07-31 22:16:00 +02:00
hudeng 59bf4501e8 feat: Use databaseBackend config repace databaseEtcd
databaseBackend config contains type and url sub config, It can facilitate the expansion of other types of databases in the future.
2024-07-31 22:16:00 +02:00
hudeng 78172d11d7 feat: Add etcd database support
improve concurrent access and high availability of aptly with the help of the characteristics of etcd
2024-07-31 22:16:00 +02:00
André Roth deae90485a fix DirIsAccessible
perms 0000 need to be checked explicitly
2024-07-24 21:19:47 +02:00
André Roth 9f1860dff7 fix unit test 2024-07-24 21:19:47 +02:00
Ryan Gonzalez f9325fbc91 Add support for Azure package pools
This adds support for storing packages directly on Azure, with no truly
"local" (on-disk) repo used. The existing Azure PublishedStorage
implementation was refactored to move the shared code to a separate
context struct, which can then be re-used by the new PackagePool. In
addition, the files package's mockChecksumStorage was made public so
that it could be used in the Azure PackagePool tests as well.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2024-06-17 11:51:18 +02:00
Ryan Gonzalez 8e37813129 Add support for custom package pool locations
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2024-06-17 11:51:18 +02:00
Mauro Regli ae61706a34 Fix: Implement golangci-lint suggestions 2023-09-21 11:25:18 +02:00
Markus Muellner 0fdba29d51 make serving published repos in api mode configurable 2023-03-22 17:22:54 +01:00
Markus Muellner f74217ed9c implement system tests for serving api and published repos simultaneously 2023-03-22 17:22:54 +01:00
Markus Muellner 8e62195eb5 implement structured logging 2023-02-20 13:42:50 +01:00
Markus Muellner 352f4e8772 update golangci-lint and replace deprecated calls to io/ioutil 2022-12-12 10:21:39 +01:00
boxjan 268c39ea8c add forceVirtualHostedStyle for stores which only support virtual hosted style 2022-09-09 09:02:52 +02:00
Benj Fassbind bfc86d3b30 Test copyfile 2022-07-13 08:33:48 +02:00
Benj Fassbind 3ce27743ae Test utils 2022-07-13 08:33:48 +02:00
Sjoerd Simons f61514edaf Allow disabling bzip2 compression for index files
Using bzip2 generates smaller index files (roughly 20% smaller Packages
files) but it comes with a big performance penalty.  When publishing a
debian mirror snapshot (amd64, arm64, armhf, source) without contents
skipping bzip speeds things up around 1.8 times.

```
$ hyperfine -w 1 -L skip-bz2 true,false  -m 3 -p "aptly -config aptly.conf publish drop bullseye || true" "aptly -config aptly.conf  publish snapshot  --skip-bz2={skip-bz2} --skip-contents --skip-signing bullseye"
Benchmark 1: aptly -config aptly.conf  publish snapshot  --skip-bz2=true --skip-contents --skip-signing bullseye
  Time (mean ± σ):     35.567 s ±  0.307 s    [User: 39.366 s, System: 10.075 s]
  Range (min … max):   35.311 s … 35.907 s    3 runs

Benchmark 2: aptly -config aptly.conf  publish snapshot  --skip-bz2=false --skip-contents --skip-signing bullseye
  Time (mean ± σ):     64.740 s ±  0.135 s    [User: 68.565 s, System: 10.129 s]
  Range (min … max):   64.596 s … 64.862 s    3 runs

Summary
  'aptly -config aptly.conf  publish snapshot  --skip-bz2=true --skip-contents --skip-signing bullseye' ran
    1.82 ± 0.02 times faster than 'aptly -config aptly.conf  publish snapshot  --skip-bz2=false --skip-contents --skip-signing bullseye'
```

Allow skipping bz2 creation for setups where faster publishing is more
important then Package file size.

Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
2022-06-22 11:25:45 +02:00
Sjoerd Simons 2aca913e92 Use parallel gzip instead of gzip for compression
golangs compress/gzip isn't a parallel implementation, so it's quite a
bit slower on most modern servers then pgzip. The below benchmark
run shows that publishing a debian bullseye mirror snapshot (amd64, arm64,
armhf, source) shows a gain of about 35% in publishing time (when skipping
bz2 using MR #1081)

```
 hyperfine -w 1 -m 3 -L aptly aptly-nobz2,aptly-nobz2-pgzip -p "{aptly} -config aptly.conf publish drop bullseye || true" "{aptly} -config aptly.conf  publish snapshot --skip-bz2=true --skip-contents --skip-signing bullseye"
Benchmark 1: aptly-nobz2 -config aptly.conf  publish snapshot --skip-bz2=true --skip-contents --skip-signing bullseye
  Time (mean ± σ):     35.548 s ±  0.378 s    [User: 39.465 s, System: 10.046 s]
  Range (min … max):   35.149 s … 35.902 s    3 runs

Benchmark 2: aptly-nobz2-pgzip -config aptly.conf  publish snapshot --skip-bz2=true --skip-contents --skip-signing bullseye
  Time (mean ± σ):     26.592 s ±  0.069 s    [User: 42.207 s, System: 9.676 s]
  Range (min … max):   26.521 s … 26.660 s    3 runs

Summary
  'aptly-nobz2-pgzip -config aptly.conf  publish snapshot --skip-bz2=true --skip-contents --skip-signing bullseye' ran
    1.34 ± 0.01 times faster than 'aptly-nobz2 -config aptly.conf  publish snapshot --skip-bz2=true --skip-contents --skip-signing bullseye'
```

Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
2022-06-21 15:43:58 +02:00
Chuan Liu 152538ccc1 Support custom Azure publish endpoint 2022-04-25 11:41:04 +02:00
Markus Muellner 6539e1b856 Add metrics endpoint with http metrics using Prometheus client lib 2022-04-12 14:39:16 +02:00
Lorenzo Bolla 1afcd68e01 Make downloader type configurable 2022-01-31 10:32:54 +01:00
Lorenzo Bolla 9bf1a44f75 Fix test after merge 2022-01-27 09:30:14 +01:00
Lorenzo Bolla 9b28d8984f Configurable background task execution 2022-01-27 09:30:14 +01:00
chuan bb42a2158d Add support for Azure storage as a publishing backend
This adds a new configuration setting: AzurePublishEndpoints, similar
to the existing S3PublishEndpoints and SwiftPublishEndpoints.

For each endpoint, the following has to be defined:
 - accountName
 - accountKey
 - container
 - prefix

Azure tests require the following environment variables to be set:
 - AZURE_STORAGE_ACCOUNT
 - AZURE_STORAGE_ACCESS_KEY

With either of these not set, Azure-specific tests are skipped.
2022-01-21 11:46:36 +01:00
Frank Steinborn 98e75f6d97 Make database open attempts configurable also via config file 2019-09-03 00:52:24 +03:00
Andrey Smirnov f0a370db24 Rework HTTP downloader retry logic
Apply retries as global, config-level option `downloadRetries` so that
it can be applied to any aptly command which downloads objects.

Unwrap `errors.Wrap` which is used in downloader.

Unwrap `*url.Error` which should be the actual error returned from the
HTTP client, catch more cases, be more specific around failures.
2019-08-07 20:23:05 +03:00
Andrey Smirnov 3b5840e248 Fix linter list and fix errors discovered by new staticcheck 2019-01-20 00:01:17 +03:00
Harald Sitter 46c2182ade fix linting by using new maligned linter instead of aligncheck
upstream switched the alignment check backend and in doing so fails to run
if the old backend is defined in the config.

also skip alignment linting on a struct we use for byte decoding as we have
no choice in its member order.
2017-10-31 12:24:31 +01:00
Andrey Smirnov 499ab35012 Implement flag/config falue for GPG provider 2017-07-21 01:01:58 +03:00
Andrey Smirnov 1be8d39105 Refactor GPG signer/verifier
Goal is to make it easier to plug in another implementation.
2017-05-23 02:54:56 +03:00