From ea80f6d49cc5814ad6ce324ec3e0ea5293129e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Roth?= Date: Sun, 1 Dec 2024 10:51:58 +0100 Subject: [PATCH] write commented json default config --- aptly/conf.go | 4 + context/context.go | 15 +- context/context_test.go | 5 +- debian/aptly.conf | 36 ++- main.go | 4 + main_test.go | 1 + system/t02_config/CreateConfigTest_gold | 397 ++++++++++++++++++++++-- utils/config.go | 12 + 8 files changed, 421 insertions(+), 53 deletions(-) create mode 100644 aptly/conf.go diff --git a/aptly/conf.go b/aptly/conf.go new file mode 100644 index 00000000..b39c2b8b --- /dev/null +++ b/aptly/conf.go @@ -0,0 +1,4 @@ +package aptly + +// Default aptly.conf (filled in at link time) +var AptlyConf []byte diff --git a/context/context.go b/context/context.go index e599102d..5df5bbfd 100644 --- a/context/context.go +++ b/context/context.go @@ -3,7 +3,6 @@ package context import ( gocontext "context" - "errors" "fmt" "math/rand" "os" @@ -116,9 +115,11 @@ func (context *AptlyContext) config() *utils.ConfigStructure { if err != nil { fmt.Fprintf(os.Stderr, "Config file not found, creating default config at %s\n\n", homeLocation) - // as this is fresh aptly installation, we don't need to support legacy pool locations - utils.Config.SkipLegacyPool = true - utils.SaveConfig(configLocations[0], &utils.Config) + utils.SaveConfigRaw(homeLocation, aptly.AptlyConf) + err = utils.LoadConfig(homeLocation, &utils.Config) + if err != nil { + Fatal(fmt.Errorf("error loading config file %s: %s", homeLocation, err)) + } } } @@ -293,10 +294,10 @@ func (context *AptlyContext) _database() (database.Storage, error) { var err error switch context.config().DatabaseBackend.Type { case "leveldb": - if len(context.config().DatabaseBackend.DbPath) == 0 { - return nil, errors.New("leveldb databaseBackend config invalid") + dbPath := filepath.Join(context.config().GetRootDir(), "db") + if len(context.config().DatabaseBackend.DbPath) != 0 { + dbPath = context.config().DatabaseBackend.DbPath } - dbPath := filepath.Join(context.config().GetRootDir(), context.config().DatabaseBackend.DbPath) context.database, err = goleveldb.NewDB(dbPath) case "etcd": context.database, err = etcddb.NewDB(context.config().DatabaseBackend.URL) diff --git a/context/context_test.go b/context/context_test.go index 0a48f920..f83d42f2 100644 --- a/context/context_test.go +++ b/context/context_test.go @@ -1,6 +1,8 @@ package context import ( + "fmt" + "os" "reflect" "testing" @@ -82,5 +84,6 @@ func (s *AptlyContextSuite) TestGetPublishedStorageBadFS(c *C) { // storage never exists. c.Assert(func() { s.context.GetPublishedStorage("filesystem:fuji") }, FatalErrorPanicMatches, - &FatalError{ReturnCode: 1, Message: "published local storage fuji not configured"}) + &FatalError{ReturnCode: 1, Message: fmt.Sprintf("error loading config file %s/.aptly.conf: EOF", + os.Getenv("HOME"))}) } diff --git a/debian/aptly.conf b/debian/aptly.conf index 321adc4e..0d498e3f 100644 --- a/debian/aptly.conf +++ b/debian/aptly.conf @@ -1,6 +1,6 @@ // vim: : filetype=json // json configuration file with comments -// validate with: sed '/\/\//d' debian/aptly.conf | json_pp +// validate with: sed '/\/\//d' aptly.conf | json_pp { // General @@ -30,7 +30,7 @@ "logFormat": "default", // Default Architectures - // * empty defaults to all available architectures + // empty array defaults to all available architectures "architectures": [], // Follow contents of `Suggests:` field when processing dependencies for the package @@ -49,7 +49,7 @@ "dependencyVerboseResolve": false, // Specifies paramaters for short PPA url expansion - // * empty defaults to output of `lsb_release` command + // empty defaults to output of `lsb_release` command "ppaDistributorID": "ubuntu", // Codename for short PPA url expansion @@ -84,14 +84,20 @@ //////////// // Database backend + // Type must be one of: + // * leveldb (default) + // * etcd "databaseBackend": { - // - "type": "", - // - "url": "", - // + // LevelDB + "type": "leveldb", + // Path to leveldb files + // empty dbPath defaults to `rootDir`/db "dbPath": "" - // + + // // etcd + // "type": "etcd", + // // URL to db server + // "url": "127.0.0.1:2379" }, @@ -171,7 +177,7 @@ // // File Copare Method for comparing existing links from the internal pool to the published directory // // Only used when "linkMethod" is set to "copy" // // * md5 (default: compare md5 sum) - // // * size (only compare file size) + // // * size (compare file size) // "verifyMethod": "md5" // } }, @@ -325,7 +331,7 @@ // // // Endpoint URL // // See: Azure documentation https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string - // // defaults to "https://$accountName.blob.core.windows.net" + // // defaults to "https://.blob.core.windows.net" // "endpoint": "" // } }, @@ -336,9 +342,11 @@ // * local // * azure "packagePoolStorage": { - // Local Pool Path + // Local Pool "type": "local", - "path": "$ROOTDIR/pool" + // Local Pool Path + // empty path defaults to `rootDir`/pool + "path": "" // // Azure Azure Blob Storage Pool // "type": "azure", @@ -357,7 +365,7 @@ // // // Endpoint URL // // See: Azure documentation https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string - // // defaults to "https://$accountName.blob.core.windows.net" + // // defaults to "https://.blob.core.windows.net" // "endpoint": "" // } } diff --git a/main.go b/main.go index 337575a4..6a5247cc 100644 --- a/main.go +++ b/main.go @@ -13,12 +13,16 @@ import ( //go:embed VERSION var Version string +//go:embed debian/aptly.conf +var AptlyConf []byte + func main() { if Version == "" { Version = "unknown" } aptly.Version = Version + aptly.AptlyConf = AptlyConf os.Exit(cmd.Run(cmd.RootCommand(), os.Args[1:], true)) } diff --git a/main_test.go b/main_test.go index 81ef138d..750073b7 100644 --- a/main_test.go +++ b/main_test.go @@ -51,6 +51,7 @@ func TestRunMain(t *testing.T) { } aptly.Version = Version + aptly.AptlyConf = AptlyConf args := filterOutTestArgs(os.Args[1:]) root := cmd.RootCommand() diff --git a/system/t02_config/CreateConfigTest_gold b/system/t02_config/CreateConfigTest_gold index 181efa4d..0d498e3f 100644 --- a/system/t02_config/CreateConfigTest_gold +++ b/system/t02_config/CreateConfigTest_gold @@ -1,39 +1,374 @@ +// vim: : filetype=json +// json configuration file with comments +// validate with: sed '/\/\//d' aptly.conf | json_pp { - "rootDir": "${HOME}/.aptly", - "downloadConcurrency": 4, - "downloadSpeedLimit": 0, - "downloadRetries": 0, - "downloader": "default", + +// General +/////////// + + // Aptly storage directory + // Directory for storing: + // - downloaded packages (`rootDir`/pool) + // - database (`rootDir`/db) + // - published repositories (`rootDir`/public) + "rootDir": "~/.aptly", + + // Number of attempts to open database if it's locked by other instance + // * -1 (no retry) "databaseOpenAttempts": -1, - "architectures": [], - "dependencyFollowSuggests": false, - "dependencyFollowRecommends": false, - "dependencyFollowAllVariants": false, - "dependencyFollowSource": false, - "dependencyVerboseResolve": false, - "gpgDisableSign": false, - "gpgDisableVerify": false, - "gpgProvider": "gpg", - "downloadSourcePackages": false, - "packagePoolStorage": {}, - "skipLegacyPool": true, - "ppaDistributorID": "ubuntu", - "ppaCodename": "", - "skipContentsPublishing": false, - "skipBz2Publishing": false, - "FileSystemPublishEndpoints": {}, - "S3PublishEndpoints": {}, - "SwiftPublishEndpoints": {}, - "AzurePublishEndpoints": {}, - "AsyncAPI": false, - "enableMetricsEndpoint": false, - "logLevel": "debug", + + // Log Level + // * debug + // * info + // * warning + // * error + "logLevel": "info", + + // Log Format + // * default (text) + // * json "logFormat": "default", + + // Default Architectures + // empty array defaults to all available architectures + "architectures": [], + + // Follow contents of `Suggests:` field when processing dependencies for the package + "dependencyFollowSuggests": false, + + // Follow contents of `Recommends:` field when processing dependencies for the package + "dependencyFollowRecommends": false, + + // When dependency looks like `package-a | package-b`, follow both variants always + "dependencyFollowAllVariants": false, + + // Follow dependency from binary package to source package + "dependencyFollowSource": false, + + // Log additional details while resolving dependencies (useful for debugging) + "dependencyVerboseResolve": false, + + // Specifies paramaters for short PPA url expansion + // empty defaults to output of `lsb_release` command + "ppaDistributorID": "ubuntu", + + // Codename for short PPA url expansion + "ppaCodename": "", + + // OBSOLETE + // in aptly up to version 1.0.0, package files were stored in internal package pool + // with MD5-dervied path, since 1.1.0 package pool layout was changed; + // if option is enabled, aptly stops checking for legacy paths; + // by default option is enabled for new aptly installations and disabled when + // upgrading from older versions + "skipLegacyPool": true, + + +// Aptly Server +//////////////// + + // Serve published repos as well as API "serveInAPIMode": false, + + // Enable metrics for Prometheus client + "enableMetricsEndpoint": false, + + // Enable API documentation on /docs + "enableSwaggerEndpoint": false, + + // OBSOLETE: use via url param ?_async=true + "AsyncAPI": false, + + +// Database +//////////// + + // Database backend + // Type must be one of: + // * leveldb (default) + // * etcd "databaseBackend": { - "type": "", - "url": "", + // LevelDB + "type": "leveldb", + // Path to leveldb files + // empty dbPath defaults to `rootDir`/db "dbPath": "" + + // // etcd + // "type": "etcd", + // // URL to db server + // "url": "127.0.0.1:2379" }, - "enableSwaggerEndpoint": false + + +// Mirroring +///////////// + + // Downloader + // * "default" + // * "grab" (more robust) + "downloader": "default", + + // Number of parallel download threads to use when downloading packages + "downloadConcurrency": 4, + + // Limit in kbytes/sec on download speed while mirroring remote repositories + "downloadSpeedLimit": 0, + + // Number of retries for download attempts + "downloadRetries": 0, + + // Download source packages per default + "downloadSourcePackages": false, + + +// Signing +/////////// + + // GPG Provider + // * "internal" (Go internal implementation) + // * "gpg" (External `gpg` utility) + "gpgProvider": "gpg", + + // Disable signing of published repositories + "gpgDisableSign": false, + + // Disable signature verification of remote repositories + "gpgDisableVerify": false, + + +// Publishing +////////////// + + // Do not publish Contents files + "skipContentsPublishing": false, + + // Do not create bz2 files + "skipBz2Publishing": false, + + +// Storage +/////////// + + // Filesystem publishing endpoints + // + // aptly defaults to publish to a single publish directory under `rootDir`/public. For + // a more advanced publishing strategy, you can define one or more filesystem endpoints in the + // `FileSystemPublishEndpoints` list of the aptly configuration file. Each endpoint has a name + // and the following associated settings. + // + // In order to publish to such an endpoint, specify the endpoint as `filesystem:endpoint-name` + // with `endpoint-name` as the name given in the aptly configuration file. For example: + // + // `aptly publish snapshot wheezy-main filesystem:test1:wheezy/daily` + // + "FileSystemPublishEndpoints": { + // // Endpoint Name + // "test1": { + // // Directory for publishing + // "rootDir": "/opt/srv/aptly_public", + // + // // File Link Method for linking files from the internal pool to the published directory + // // * hardlink + // // * symlink + // // * copy + // "linkMethod": "hardlink", + // + // // File Copare Method for comparing existing links from the internal pool to the published directory + // // Only used when "linkMethod" is set to "copy" + // // * md5 (default: compare md5 sum) + // // * size (compare file size) + // "verifyMethod": "md5" + // } + }, + + // S3 Endpoint Support + // + // cloud storage). First, publishing + // endpoints should be described in aptly configuration file. Each endpoint has name + // and associated settings. + // + // In order to publish to S3, specify endpoint as `s3:endpoint-name:` before + // publishing prefix on the command line, e.g.: + // + // `aptly publish snapshot wheezy-main s3:test:` + // + "S3PublishEndpoints": { + // // Endpoint Name + // "test": { + // + // // Amazon region for S3 bucket + // "region": "us-east-1", + // + // // Bucket name + // "bucket": "test-bucket", + // + // // Endpoint (optional) + // // When using S3-compatible cloud storage, specify hostname of service endpoint here, + // // region is ignored if endpoint is set (set region to some human-readable name) + // // (should be left blank for real Amazon S3) + // "endpoint": "", + // + // // Prefix (optional) + // // publishing under specified prefix in the bucket, defaults to + // // no prefix (bucket root) + // "prefix": "", + // + // // Default ACLs (optional) + // // assign ACL to published files (one of the canned ACLs in Amazon + // // terminology). Useful values: `private` (default), `public-read` (public + // // repository) or `none` (don't set ACL). Public repositories could be consumed by `apt` using + // // HTTP endpoint (Amazon bucket should be configured for "website hosting"), + // // for private repositories special apt S3 transport is required. + // "acl": "private", + // + // // Credentials (optional) + // // Amazon credentials to access S3 bucket. If not supplied, + // // environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` + // // are used. + // "awsAccessKeyID": "", + // "awsSecretAccessKey": "", + // + // // Storage Class (optional) + // // Amazon S3 storage class, defaults to `STANDARD`. Other values + // // available: `REDUCED_REDUNDANCY` (lower price, lower redundancy) + // "storageClass": "STANDARD", + // + // // Encryption Method (optional) + // // Server-side encryption method, defaults to none. Currently + // // the only available encryption method is `AES256` + // "encryptionMethod": "none", + // + // // Plus Workaround (optional) + // // Workaround misbehavior in apt and Amazon S3 for files with `+` in filename by + // // creating two copies of package files with `+` in filename: one original + // // and another one with spaces instead of plus signs + // // With `plusWorkaround` enabled, package files with plus sign + // // would be stored twice. aptly might not cleanup files with spaces when published + // // repository is dropped or updated (switched) to new version of repository (snapshot) + // "plusWorkaround": false, + // + // // Disable MultiDel (optional) + // // For S3-compatible cloud storages which do not support `MultiDel` S3 API, + // // enable this setting (file deletion would be slower with this setting enabled) + // "disableMultiDel": false, + // + // // ForceSig2 (optional) + // // Disable Signature V4 support, useful with non-AWS S3-compatible object stores + // // which do not support SigV4, shouldn't be enabled for AWS + // "forceSigV2": false, + // + // // ForceVirtualHostedStyle (optional) + // // Disable path style visit, useful with non-AWS S3-compatible object stores + // // which only support virtual hosted style + // "forceVirtualHostedStyle": false, + // + // // Debug (optional) + // // Enables detailed request/response dump for each S3 operation + // "debug": false + // } + }, + + // Swift Endpoint Support + // + // aptly could be configured to publish repository directly to OpenStack Swift. First, + // publishing endpoints should be described in aptly configuration file. Each endpoint + // has name and associated settings. + // + // In order to publish to Swift, specify endpoint as `swift:endpoint-name:` before + // publishing prefix on the command line, e.g.: + // + // `aptly publish snapshot jessie-main swift:test:` + // + "SwiftPublishEndpoints": { + // // Endpoint Name + // "test": { + // + // // Container Name + // "container": "container1", + // + // // Prefix (optional) + // // Publish under specified prefix in the container, defaults to no prefix (container root) + // "prefix": "", + + // // Credentials (optional) + // // OpenStack credentials to access Keystone. If not supplied, environment variables `OS_USERNAME` and `OS_PASSWORD` are used + // "osname": "", + // "password": "", + + // // Tenant (optional) + // // OpenStack tenant name and id (in order to use v2 authentication) + // "tenant": "", + // "tenantid": "", + + // // Auth URL (optional) + // // Full url of Keystone server (including port, and version). + // // Example `http://identity.example.com:5000/v2.0` + // "authurl": "" + // } + }, + + // Azure Endpoint Support + // + // aptly can be configured to publish repositories directly to Microsoft Azure Blob + // Storage. First, publishing endpoints should be described in the aptly + // configuration file. Each endpoint has its name and associated settings. + "AzurePublishEndpoints": { + // // Endpoint Name + // "test": { + // + // // Container Name + // "container": "container1", + // + // // Prefix (optional) + // // Publishing under specified prefix in the container, defaults to no prefix (container root) + // "prefix": "", + // + // // Credentials + // // Azure storage account access key to access blob storage + // "accountName": "", + // "accountKey": "", + // + // // Endpoint URL + // // See: Azure documentation https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string + // // defaults to "https://.blob.core.windows.net" + // "endpoint": "" + // } + }, + + // Package Pool + // Location for storing downloaded packages + // Type must be one of: + // * local + // * azure + "packagePoolStorage": { + // Local Pool + "type": "local", + // Local Pool Path + // empty path defaults to `rootDir`/pool + "path": "" + + // // Azure Azure Blob Storage Pool + // "type": "azure", + // "azure": { + // // Container Name + // "container": "pool1", + // + // // Prefix (optional) + // // Publishing under specified prefix in the container, defaults to no prefix (container root) + // "prefix": "", + // + // // Credentials + // // Azure storage account access key to access blob storage + // "accountName": "", + // "accountKey": "", + // + // // Endpoint URL + // // See: Azure documentation https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string + // // defaults to "https://.blob.core.windows.net" + // "endpoint": "" + // } + } + +// End of config } diff --git a/utils/config.go b/utils/config.go index b061649f..4665c830 100644 --- a/utils/config.go +++ b/utils/config.go @@ -215,6 +215,18 @@ func SaveConfig(filename string, config *ConfigStructure) error { return err } +// SaveConfigRaw write configuration to file +func SaveConfigRaw(filename string, conf []byte) error { + f, err := os.Create(filename) + if err != nil { + return err + } + defer f.Close() + + _, err = f.Write(conf) + return err +} + // GetRootDir returns the RootDir with expanded ~ as home directory func (conf *ConfigStructure) GetRootDir() string { return strings.Replace(conf.RootDir, "~", os.Getenv("HOME"), 1)