Documentation
¶
Overview ¶
Package config loads the application configuration described in docs/operations/configuration-reference.md and decision record 0009.
The precedence is flag, then environment, then file, then default. The file is strict YAML: an unknown key is an error rather than a silently ignored typo, because a misspelt storage key would otherwise start the server on the wrong backend without any warning.
Index ¶
- Constants
- Variables
- func OSEnv(name string) (string, bool)
- type AQLConfig
- type AQLTimeoutConfig
- type BlobAzureCDNConfig
- type BlobAzureConfig
- type BlobBackendConfig
- type BlobConfig
- type BlobFSConfig
- type BlobGCSCDNConfig
- type BlobGCSConfig
- type BlobMirrorConfig
- type BlobS3CDNConfig
- type BlobS3Config
- type BlobStoreConfig
- type BootstrapConfig
- type BuildConfig
- type ByteSize
- type CloudCDNConfig
- type CloudFrontConfig
- type CompatConfig
- type Config
- type DatabaseConfig
- type DeployConfig
- type DockerConfig
- type DownloadConfig
- type EnvironmentsConfig
- type FolderDownloadConfig
- type FrontDoorConfig
- type GCConfig
- type LoadOptions
- type LogConfig
- type MavenConfig
- type NPMConfig
- type NPMLoginConfig
- type NPMPathConfig
- type NPMTagConfig
- type RedirectConfig
- type SearchConfig
- type TokenConfig
- type WorkConfig
Constants ¶
const ( AzureSAS = "sas" AzureConnectionString = "connection_string" AzureDefault = "default" AzureManagedIdentity = "managed_identity" AzureWorkloadIdentity = "workload_identity" )
Azure credential kinds.
const ( DefaultListen = ":8081" DefaultDataDir = "./data" DefaultCompatVersion = "7.155.0" DefaultDriver = "sqlite" DefaultBlobBackend = "fs" DefaultLogLevel = "info" DefaultLogFormat = "json" // DefaultRedirectMinSize matches Artifactory's self-hosted 1 MB: below // it a redirect costs the client more than the bytes it saves. DefaultRedirectMinSize ByteSize = 1 << 20 // DefaultRedirectTTL covers a client's retries and the later parts of a // split download, which Artifactory's 30 seconds do not (decision 0029). DefaultRedirectTTL = 5 * time.Minute // DefaultFolderMaxConcurrent is Artifactory's "Max Parallel Folder // Downloads" default (folderDownloadConfig.maxConcurrentRequests). DefaultFolderMaxConcurrent = 10 // DefaultAQLMaxResults is the cap JFrog SaaS sets with // aql.search.query.max.limit; self-managed Artifactory has none (DV-030). DefaultAQLMaxResults = 500000 // DefaultAQLScanFactor reads no extra rows for non-admin filtering, the // default of artifactory.aql.query.non.admin.scan.factor. DefaultAQLScanFactor = 1 // DefaultAQLQueryTimeout and DefaultAQLStreamedTimeout are the defaults // of artifactory.aql.query.timeout.seconds (900) and // artifactory.aql.streamed.query.timeout (7200). DefaultAQLQueryTimeout = 15 * time.Minute DefaultAQLStreamedTimeout = 2 * time.Hour // DefaultUserQueryLimit is artifactory.search.userQueryLimit's default. DefaultUserQueryLimit = 1000 // The persistent work queue's defaults (decision 0033). DefaultWorkWorkers = 4 DefaultWorkLease = 2 * time.Minute DefaultWorkMaxAttempts = 10 // DefaultNPMMaxPublishSize is decision 0034's cap on an npm publish // body. The body carries the tarball in base64, a third larger than the // tarball itself. DefaultNPMMaxPublishSize ByteSize = 1 << 30 // DefaultGlobalEnvironmentLimit is Access's environments.global-limit // default; it must match roles.DefaultGlobalEnvironmentLimit. DefaultGlobalEnvironmentLimit = 10 // DefaultNPMLoginTokenExpiry is the 30 days a token from npm login lasts // on 7.x (KB 000006713: 2592000 s). An hourly login would be unusable. DefaultNPMLoginTokenExpiry = 30 * 24 * time.Hour )
Defaults that the reference documents.
const DefaultMavenSnapshotCleanupInterval = 5 * time.Minute
DefaultMavenSnapshotCleanupInterval is how often Artifactory 7.x's background process deletes the unique snapshots over a repository's maxUniqueSnapshots: "every 5 minutes" (JFrog KB, "How does the max unique snapshots parameter work", 2025-05-15; decision 0036).
const EnvPrefix = "ARTIFACTWEAVE_"
EnvPrefix is prepended to every environment key. Nested keys join their segments with an underscore, so `database.dsn` is ARTIFACTWEAVE_DATABASE_DSN.
Variables ¶
var ( ErrUnknownKey = errors.New("unknown configuration key") ErrInvalidValue = errors.New("invalid configuration value") ErrUnknownDriver = errors.New("unknown database driver") ErrMissingDSN = errors.New("database.dsn is required for postgres") ErrUnknownBlob = errors.New("unknown blob backend") ErrMissingBucket = errors.New("a bucket is required for this blob backend") ErrMissingValue = errors.New("a required configuration value is missing") ErrBadListen = errors.New("listen is not a host:port address") ErrBadBaseURL = errors.New("base_url must be an absolute http or https URL") ErrMissingKey = errors.New("master_key is required (set ARTIFACTWEAVE_MASTER_KEY)") )
Sentinel errors for Validate; wrap them with context.
Functions ¶
Types ¶
type AQLConfig ¶
type AQLConfig struct {
// MaxResults caps the rows of every query, its own limit included; zero
// means no cap.
MaxResults int `yaml:"max_results"`
// NonAdminScanFactor multiplies a non-admin query's limit to read
// enough rows that the limit is still met once unreadable rows are
// filtered out. A request's scan-factor header overrides it.
NonAdminScanFactor int `yaml:"non_admin_scan_factor"`
}
AQLConfig limits POST /api/search/aql (decision 0012).
type AQLTimeoutConfig ¶
type AQLTimeoutConfig struct {
// Query is Artifactory's artifactory.aql.query.timeout.seconds.
Query time.Duration `yaml:"query"`
// Streamed applies to a request with a stream: true header, as
// Artifactory's artifactory.aql.streamed.query.timeout does.
Streamed time.Duration `yaml:"streamed"`
}
AQLTimeoutConfig bounds how long POST /api/search/aql reads the database (decision 0012). A query that runs longer is cancelled in the database and answers 408. Zero means no timeout.
type BlobAzureCDNConfig ¶
type BlobAzureCDNConfig struct {
FrontDoor FrontDoorConfig `yaml:"front_door"`
}
BlobAzureCDNConfig is the CDN in front of an azure store.
type BlobAzureConfig ¶
type BlobAzureConfig struct {
Account string `yaml:"account"`
Endpoint string `yaml:"endpoint"`
Container string `yaml:"container"`
Prefix string `yaml:"prefix"`
// Credential is shared_key, sas, connection_string, default (the Azure
// SDK's default chain), managed_identity or workload_identity. Empty
// picks connection_string, shared_key or sas when that secret is set,
// otherwise default.
Credential string `yaml:"credential"`
AccountKey string `yaml:"account_key"`
SASToken string `yaml:"sas_token"`
ConnectionString string `yaml:"connection_string"`
ManagedIdentityClientID string `yaml:"managed_identity_client_id"`
PartSize ByteSize `yaml:"part_size"`
CopyRangeSize ByteSize `yaml:"copy_range_size"`
Concurrency int `yaml:"concurrency"`
// CDN is a CDN in front of the container (decision 0029).
CDN BlobAzureCDNConfig `yaml:"cdn"`
}
BlobAzureConfig is the Azure Blob Storage backend (decision 0027). AccountKey, SASToken and ConnectionString are secrets: prefer their environment variables to the file, and they are redacted from every summary.
func (BlobAzureConfig) EffectiveCredential ¶
func (a BlobAzureConfig) EffectiveCredential() string
EffectiveCredential is Credential, or the kind the configured secrets imply when it is empty.
type BlobBackendConfig ¶
type BlobBackendConfig struct {
Backend string `yaml:"backend"`
FS BlobFSConfig `yaml:"fs"`
S3 BlobS3Config `yaml:"s3"`
GCS BlobGCSConfig `yaml:"gcs"`
Azure BlobAzureConfig `yaml:"azure"`
}
BlobBackendConfig is one store's backend and its settings.
type BlobConfig ¶
type BlobConfig struct {
BlobBackendConfig `yaml:",inline"`
// Stores are named stores, the members a mirror chooses from.
Stores map[string]BlobStoreConfig `yaml:"stores"`
Mirror BlobMirrorConfig `yaml:"mirror"`
}
BlobConfig selects one blob store: the hot store (blob) or the archive tier (cold_blob). Backend is fs, s3, gcs or azure for a single store, or mirror to keep every blob in several of the named Stores (decision 0028).
type BlobFSConfig ¶
type BlobFSConfig struct {
Root string `yaml:"root"`
}
BlobFSConfig is the local disk backend.
type BlobGCSCDNConfig ¶
type BlobGCSCDNConfig struct {
CloudCDN CloudCDNConfig `yaml:"cloud_cdn"`
}
BlobGCSCDNConfig is the CDN in front of a gcs store.
type BlobGCSConfig ¶
type BlobGCSConfig struct {
Bucket string `yaml:"bucket"`
Prefix string `yaml:"prefix"`
Endpoint string `yaml:"endpoint"`
CredentialsFile string `yaml:"credentials_file"`
// GoogleAccessID is the service account that signs download URLs when
// the credentials alone do not name one.
GoogleAccessID string `yaml:"google_access_id"`
PartSize ByteSize `yaml:"part_size"`
// CDN is a CDN in front of the bucket (decision 0029).
CDN BlobGCSCDNConfig `yaml:"cdn"`
}
BlobGCSConfig is the Google Cloud Storage backend (decision 0027). Credentials are Application Default Credentials unless CredentialsFile names a service-account key file.
type BlobMirrorConfig ¶
type BlobMirrorConfig struct {
// Members names the stores that hold copies.
Members []string `yaml:"members"`
// Redundancy is the number of copies of each blob; zero means every
// member.
Redundancy int `yaml:"redundancy"`
// WriteQuorum is how many copies must be stored before an upload
// succeeds; zero means Redundancy-1 (at least 1), so one member down
// does not stop uploads.
WriteQuorum int `yaml:"write_quorum"`
// Zone is this instance's zone; members in it are preferred.
Zone string `yaml:"zone"`
// MemberTimeout bounds how long a member may finish after the quorum;
// zero means 30s.
MemberTimeout time.Duration `yaml:"member_timeout"`
}
BlobMirrorConfig is the mirror (decision 0028).
func (BlobMirrorConfig) Effective ¶
func (m BlobMirrorConfig) Effective() (redundancy, quorum int)
Effective returns the redundancy and write quorum with their defaults applied for the configured members.
type BlobS3CDNConfig ¶
type BlobS3CDNConfig struct {
CloudFront CloudFrontConfig `yaml:"cloudfront"`
}
BlobS3CDNConfig is the CDN in front of an s3 store.
type BlobS3Config ¶
type BlobS3Config struct {
Bucket string `yaml:"bucket"`
Prefix string `yaml:"prefix"`
Endpoint string `yaml:"endpoint"`
Region string `yaml:"region"`
PathStyle bool `yaml:"path_style"`
Profile string `yaml:"profile"`
// CDN is a CDN in front of the bucket (decision 0029).
CDN BlobS3CDNConfig `yaml:"cdn"`
}
BlobS3Config is the S3-compatible backend. Credentials come from the AWS SDK's own chain, never from this file; Profile selects a named profile of the shared AWS configuration, so mirror members can use different accounts.
type BlobStoreConfig ¶
type BlobStoreConfig struct {
BlobBackendConfig ` yaml:",inline"`
Zone string `yaml:"zone"`
// WriteEnabled false drains the store: no new copies, reads continue.
// Unset means true.
WriteEnabled *bool `yaml:"write_enabled"`
}
BlobStoreConfig is a named store: a backend with its zone (a region or site label the mirror orders reads and writes by) and whether it accepts new copies.
func (BlobStoreConfig) Writable ¶
func (s BlobStoreConfig) Writable() bool
Writable reports whether the store accepts new copies.
type BootstrapConfig ¶
type BootstrapConfig struct {
AdminPassword string `yaml:"admin_password"`
Descriptor string `yaml:"descriptor"`
}
BootstrapConfig seeds the first start.
type BuildConfig ¶
type BuildConfig struct {
// BlockDuplicateEntries refuses a build-info publish whose module lists
// one file twice, as Artifactory 7.x's
// artifactory.build.block.duplicate.entries does by default.
BlockDuplicateEntries bool `yaml:"block_duplicate_entries"`
}
BuildConfig holds the build-info settings (decision 0014).
type ByteSize ¶
type ByteSize int64
ByteSize is a size in bytes, written in the file and the environment as a plain number of bytes or with a binary suffix: "512KiB", "16MiB", "1GiB".
func (ByteSize) MarshalYAML ¶
MarshalYAML renders the size as String does.
type CloudCDNConfig ¶
type CloudCDNConfig struct {
// Domain is the load balancer host, or an http(s) URL for a test edge.
Domain string `yaml:"domain"`
// KeyName names the signing key on the backend bucket.
KeyName string `yaml:"key_name"`
// KeyFile holds the 128-bit key, base64url, as gcloud reads it.
KeyFile string `yaml:"key_file"`
// PathPrefix is the path inside the bucket the load balancer serves at
// its root.
PathPrefix string `yaml:"path_prefix"`
}
CloudCDNConfig is a Cloud CDN backend bucket whose bucket is the store's. The signing key stays in its file, which is read at start: the configuration holds only the path.
func (CloudCDNConfig) Enabled ¶
func (c CloudCDNConfig) Enabled() bool
Enabled reports whether any field is set.
type CloudFrontConfig ¶
type CloudFrontConfig struct {
// Domain is the distribution host, or an http(s) URL for a test edge.
Domain string `yaml:"domain"`
// KeyPairID is the public key's ID in a trusted key group.
KeyPairID string `yaml:"key_pair_id"`
// PrivateKeyFile is the PEM key that signs URLs.
PrivateKeyFile string `yaml:"private_key_file"`
// Hash is sha1 (the default) or sha256.
Hash string `yaml:"hash"`
// PathPrefix is the distribution origin's path inside the bucket.
PathPrefix string `yaml:"path_prefix"`
}
CloudFrontConfig is a CloudFront distribution whose origin is the bucket. The private key stays in its file, which is read at start: the configuration holds only the path.
func (CloudFrontConfig) Enabled ¶
func (c CloudFrontConfig) Enabled() bool
Enabled reports whether any field is set.
type CompatConfig ¶
type CompatConfig struct {
ArtifactoryVersion string `yaml:"artifactory_version"`
}
CompatConfig holds the Artifactory version string reported to clients. Clients gate features on it (decision record 0005), so it is configurable rather than derived from the build.
type Config ¶
type Config struct {
Listen string `yaml:"listen"`
BaseURL string `yaml:"base_url"`
DataDir string `yaml:"data_dir"`
Compat CompatConfig `yaml:"compat"`
Database DatabaseConfig `yaml:"database"`
Blob BlobConfig `yaml:"blob"`
// ColdBlob is the archive tier (decision 0024); an empty backend means
// none is configured.
ColdBlob BlobConfig `yaml:"cold_blob"`
MasterKey string `yaml:"master_key"`
// MasterKeyPrevious is the key being rotated away from; it is kept
// until `artifactweave keys rotate` has re-sealed every value.
MasterKeyPrevious string `yaml:"master_key_previous"`
Bootstrap BootstrapConfig `yaml:"bootstrap"`
Docker DockerConfig `yaml:"docker"`
Log LogConfig `yaml:"log"`
GC GCConfig `yaml:"gc"`
Download DownloadConfig `yaml:"download"`
Search SearchConfig `yaml:"search"`
Work WorkConfig `yaml:"work"`
Build BuildConfig `yaml:"build"`
NPM NPMConfig `yaml:"npm"`
Token TokenConfig `yaml:"token"`
Deploy DeployConfig `yaml:"deploy"`
Environments EnvironmentsConfig `yaml:"environments"`
AQLTimeout AQLTimeoutConfig `yaml:"aql_timeout"`
Maven MavenConfig `yaml:"maven"`
}
Config is the application configuration. YAML tags are the file keys; the same dotted key names are used by the flag overlay and, upper-cased with the prefix, by the environment.
func Default ¶
func Default() Config
Default returns the configuration with every documented default applied.
func Load ¶
func Load(opts LoadOptions) (Config, error)
Load applies file, environment and flags over the defaults, in that order, and validates the result.
func (Config) DatabaseDSN ¶
DatabaseDSN is the explicit DSN or, for sqlite, the file under DataDir.
func (Config) RequireMasterKey ¶
RequireMasterKey is the extra check `serve` makes; `config validate` and `migrate` run without the key so operators can check a file before the secret exists.
func (Config) SQLitePath ¶
SQLitePath is the SQLite database file: the explicit DSN without a "file:" prefix, or artifactweave.db under DataDir.
type DatabaseConfig ¶
DatabaseConfig selects the metadata store.
type DeployConfig ¶
type DeployConfig struct {
// EnforceIdenticalChecksumDeploy makes a checksum deploy over a file
// with the same content need the delete permission, as Artifactory
// 7.x's enforce.permission.check.on.identical.checksum.deploy does. Off
// by default, as there, so that a CI re-run of jf rt u by a user who may
// deploy but not delete succeeds.
EnforceIdenticalChecksumDeploy bool `yaml:"enforce_permission_check_on_identical_checksum_deploy"`
}
DeployConfig holds the deploy settings.
type DockerConfig ¶
type DockerConfig struct {
// SubdomainMatch adds the subdomain method to repository-path routing:
// <repo>.<base_url host>/v2/<image> addresses an image in repo. It needs
// base_url, whose host the repository subdomains sit under.
SubdomainMatch bool `yaml:"subdomain_match"`
}
DockerConfig holds the Docker access-method options.
type DownloadConfig ¶
type DownloadConfig struct {
Redirect RedirectConfig `yaml:"redirect"`
Folder FolderDownloadConfig `yaml:"folder"`
}
DownloadConfig holds how downloads are served.
type EnvironmentsConfig ¶
type EnvironmentsConfig struct {
// GlobalLimit caps the global environments, DEV and PROD included, as
// Access's environments.global-limit does; creating one more answers
// 400.
GlobalLimit int `yaml:"global_limit"`
}
EnvironmentsConfig holds the environment settings.
type FolderDownloadConfig ¶
type FolderDownloadConfig struct {
// MaxConcurrentRequests is how many folder downloads may run at once on
// this node; one more answers 400 until one finishes.
MaxConcurrentRequests int `yaml:"max_concurrent_requests"`
}
FolderDownloadConfig bounds folder archive downloads. Whether they are on, and how large they may be, is the folder download setting in the store.
type FrontDoorConfig ¶
type FrontDoorConfig struct {
// Endpoint is the endpoint host, or an http(s) URL for a test edge.
Endpoint string `yaml:"endpoint"`
// PathPrefix is the route's origin path inside the account, starting
// with the container.
PathPrefix string `yaml:"path_prefix"`
}
FrontDoorConfig is an Azure Front Door endpoint whose origin is the storage account. Front Door checks no signature: the store signs a read SAS and Front Door passes it to storage, so the store's credential must be one that signs (not sas).
func (FrontDoorConfig) Enabled ¶
func (c FrontDoorConfig) Enabled() bool
Enabled reports whether any field is set.
type GCConfig ¶
type GCConfig struct {
// Interval is the time between scheduled passes.
Interval time.Duration `yaml:"interval"`
// GracePeriod is how long unreferenced content is kept before it is
// deleted. It must outlast the slowest upload: content is written before
// the reference that keeps it.
GracePeriod time.Duration `yaml:"grace_period"`
}
GCConfig schedules garbage collection (decision 0010). Zero values mean the defaults: a pass every four hours, as Artifactory schedules it, and an hour's grace.
type LoadOptions ¶
type LoadOptions struct {
// File is the YAML path; empty means no file.
File string
// Env looks up an environment variable; nil means no environment.
Env func(string) (string, bool)
// Flags maps dotted keys (for example "database.dsn") to values given on
// the command line. Only keys the caller actually set belong here.
Flags map[string]string
}
LoadOptions are the inputs to Load. Env and Flags are injected so tests never read the process environment.
type MavenConfig ¶
type MavenConfig struct {
// SnapshotCleanupInterval is how often each node runs the
// maxUniqueSnapshots cleanups that deploys have marked in the work
// queue (maven.snapshot_cleanup_interval).
SnapshotCleanupInterval time.Duration `yaml:"snapshot_cleanup_interval"`
}
MavenConfig holds the Maven, Gradle, Ivy and SBT repositories' options (decision 0036).
type NPMConfig ¶
type NPMConfig struct {
NPMLoginConfig `yaml:",inline"`
NPMTagConfig `yaml:",inline"`
NPMPathConfig `yaml:",inline"`
// MaxPublishSize is the largest npm publish request accepted; a larger
// one answers 413.
MaxPublishSize ByteSize `yaml:"max_publish_size"`
}
NPMConfig holds the npm registry's options (decision 0034).
type NPMLoginConfig ¶
type NPMLoginConfig struct {
// LoginTokenExpiry is how long a token from npm login lasts. 7.x sets it
// only with the global artifactory.artifactory.tokens.expiration.timeSecs.
LoginTokenExpiry time.Duration `yaml:"login_token_expiry"`
}
NPMLoginConfig holds npm's legacy login options (decision 0034).
type NPMPathConfig ¶
type NPMPathConfig struct {
// EnforcePath refuses the upload of a package tarball whose file name
// is not the one its package.json gives, in every npm local
// repository, as 7.x's global artifactory.npm.enforce.path does. Off
// by default, as there.
EnforcePath bool `yaml:"enforce_path"`
}
NPMPathConfig holds the npm format's upload path option (decision 0034).
type NPMTagConfig ¶
type NPMTagConfig struct {
// TagLatestByPublish gives latest to the version deployed last rather
// than the highest, as 7.x's global
// artifactory.npm.tag.tagLatestByPublish does. Off by default, as
// there.
TagLatestByPublish bool `yaml:"tag_latest_by_publish"`
}
NPMTagConfig holds the npm format's dist-tag option (decision 0034).
type RedirectConfig ¶
type RedirectConfig struct {
// MinSize is the smallest file that redirects; smaller files stream.
MinSize ByteSize `yaml:"min_size"`
// TTL is the least time a signed URL stays valid once handed out.
TTL time.Duration `yaml:"ttl"`
}
RedirectConfig tunes downloadRedirect and cdnRedirect (decision 0029).
type SearchConfig ¶
type SearchConfig struct {
AQL AQLConfig `yaml:"aql"`
// UserQueryLimit caps the results of a GET search for anonymous
// callers, and for every non-admin unless LimitAnonymousUsersOnly; zero
// means no cap. search.aql.max_results caps every caller's.
UserQueryLimit int `yaml:"user_query_limit"`
// LimitAnonymousUsersOnly spares signed-in users UserQueryLimit, as
// Artifactory's artifactory.search.limitAnonymousUsersOnly does by
// default.
LimitAnonymousUsersOnly bool `yaml:"limit_anonymous_users_only"`
}
SearchConfig holds the search limits.
type TokenConfig ¶
type TokenConfig struct {
// AllowBasicAuth lets a user name and password sent with HTTP Basic
// create tokens through POST /access/api/v1/tokens. Off by default, as
// Artifactory 7.x ships token.allow-basic-auth ("Enable Token Generation
// via API"): a token outlives a change of the password that minted it,
// so a leaked password would otherwise leave credentials behind.
AllowBasicAuth bool `yaml:"allow_basic_auth"`
}
TokenConfig holds the access token settings (decision 0005).
type WorkConfig ¶
type WorkConfig struct {
// Workers is how many work items run at once on this node.
Workers int `yaml:"workers"`
// Lease is how long a run holds its item before another node may take
// it over; a running item's lease is renewed every half lease.
Lease time.Duration `yaml:"lease"`
// MaxAttempts is how many runs an item gets before it is parked.
MaxAttempts int `yaml:"max_attempts"`
}
WorkConfig sizes the persistent work queue (decision 0033), which runs derived work such as package metadata after the change that needs it.