mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-15 11:57:59 +00:00
initial commit for JFrog support
This commit is contained in:
committed by
André Roth
parent
8ebe80f066
commit
4b8f0c42ac
@@ -51,6 +51,9 @@ func createTestConfig() *os.File {
|
|||||||
"GcsPublishEndpoints": map[string]map[string]string{
|
"GcsPublishEndpoints": map[string]map[string]string{
|
||||||
"test-gcs": {
|
"test-gcs": {
|
||||||
"bucket": "bucket-gcs",
|
"bucket": "bucket-gcs",
|
||||||
|
"JFrogPublishEndpoints": gin.H{
|
||||||
|
"test-jfrog": gin.H{
|
||||||
|
"url": "http://jfrog.example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Summary JFrog repositories
|
||||||
|
// @Description **Get list of JFrog repositories**
|
||||||
|
// @Description
|
||||||
|
// @Description List configured JFrog publish endpoints.
|
||||||
|
// @Tags Status
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} string "List of JFrog publish endpoints"
|
||||||
|
// @Router /api/jfrog [get]
|
||||||
|
func apiJFrogList(c *gin.Context) {
|
||||||
|
keys := []string{}
|
||||||
|
for k := range context.Config().JFrogPublishRoots {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
c.JSON(200, keys)
|
||||||
|
}
|
||||||
@@ -178,6 +178,7 @@ func Router(c *ctx.AptlyContext) http.Handler {
|
|||||||
{
|
{
|
||||||
api.GET("/s3", apiS3List)
|
api.GET("/s3", apiS3List)
|
||||||
api.GET("/gcs", apiGCSList)
|
api.GET("/gcs", apiGCSList)
|
||||||
|
api.GET("/jfrog", apiJFrogList)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/aptly-dev/aptly/files"
|
"github.com/aptly-dev/aptly/files"
|
||||||
"github.com/aptly-dev/aptly/gcs"
|
"github.com/aptly-dev/aptly/gcs"
|
||||||
"github.com/aptly-dev/aptly/http"
|
"github.com/aptly-dev/aptly/http"
|
||||||
|
"github.com/aptly-dev/aptly/jfrog"
|
||||||
"github.com/aptly-dev/aptly/pgp"
|
"github.com/aptly-dev/aptly/pgp"
|
||||||
"github.com/aptly-dev/aptly/s3"
|
"github.com/aptly-dev/aptly/s3"
|
||||||
"github.com/aptly-dev/aptly/swift"
|
"github.com/aptly-dev/aptly/swift"
|
||||||
@@ -476,6 +477,18 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
} else if strings.HasPrefix(name, "jfrog:") {
|
||||||
|
params, ok := context.config().JFrogPublishRoots[name[6:]]
|
||||||
|
if !ok {
|
||||||
|
Fatal(fmt.Errorf("published JFrog storage %v not configured", name[6:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
publishedStorage, err = jfrog.NewPublishedStorage(
|
||||||
|
name[6:], params)
|
||||||
|
if err != nil {
|
||||||
|
Fatal(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Fatal(fmt.Errorf("unknown published storage format: %v", name))
|
Fatal(fmt.Errorf("unknown published storage format: %v", name))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Package jfrog handles publishing to JFrog Artifactory
|
||||||
|
package jfrog
|
||||||
+238
@@ -0,0 +1,238 @@
|
|||||||
|
package jfrog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aptly-dev/aptly/aptly"
|
||||||
|
aptly_utils "github.com/aptly-dev/aptly/utils"
|
||||||
|
"github.com/jfrog/jfrog-client-go/artifactory"
|
||||||
|
"github.com/jfrog/jfrog-client-go/artifactory/auth"
|
||||||
|
"github.com/jfrog/jfrog-client-go/artifactory/services"
|
||||||
|
"github.com/jfrog/jfrog-client-go/artifactory/services/utils"
|
||||||
|
"github.com/jfrog/jfrog-client-go/config"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublishedStorage represents published repository on JFrog Artifactory
|
||||||
|
type PublishedStorage struct {
|
||||||
|
manager artifactory.ArtifactoryServicesManager
|
||||||
|
repository string
|
||||||
|
prefix string
|
||||||
|
plusWorkaround bool
|
||||||
|
pathCache map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check interface
|
||||||
|
var (
|
||||||
|
_ aptly.PublishedStorage = (*PublishedStorage)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewPublishedStorageRaw creates jfrog PublishedStorage from raw connection specs
|
||||||
|
func NewPublishedStorageRaw(
|
||||||
|
repository, url, user, password, apiKey, accessToken, prefix string,
|
||||||
|
plusWorkaround, debug bool,
|
||||||
|
) (*PublishedStorage, error) {
|
||||||
|
|
||||||
|
artDetails := auth.NewArtifactoryDetails()
|
||||||
|
artDetails.SetUrl(url)
|
||||||
|
if user != "" && password != "" {
|
||||||
|
artDetails.SetUser(user)
|
||||||
|
artDetails.SetPassword(password)
|
||||||
|
} else if apiKey != "" {
|
||||||
|
artDetails.SetApiKey(apiKey)
|
||||||
|
} else if accessToken != "" {
|
||||||
|
artDetails.SetAccessToken(accessToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceConfig, err := config.NewConfigBuilder().
|
||||||
|
SetServiceDetails(artDetails).
|
||||||
|
SetDryRun(false).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error building jfrog client config")
|
||||||
|
}
|
||||||
|
|
||||||
|
manager, err := artifactory.New(serviceConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error creating jfrog manager")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PublishedStorage{
|
||||||
|
manager: manager,
|
||||||
|
repository: repository,
|
||||||
|
prefix: prefix,
|
||||||
|
plusWorkaround: plusWorkaround,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPublishedStorage creates published storage from aptly configuration struct
|
||||||
|
func NewPublishedStorage(
|
||||||
|
account string, root aptly_utils.JFrogPublishRoot,
|
||||||
|
) (*PublishedStorage, error) {
|
||||||
|
return NewPublishedStorageRaw(
|
||||||
|
root.Repository, root.Url, root.User, root.Password, root.ApiKey, root.AccessToken,
|
||||||
|
root.Prefix, root.PlusWorkaround, root.Debug)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) String() string {
|
||||||
|
return fmt.Sprintf("jfrog:%s:%s", storage.repository, storage.prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) MkDir(path string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) PutFile(path string, sourceFilename string) error {
|
||||||
|
targetPath := filepath.Join(storage.repository, storage.prefix, path)
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
targetPath = strings.Replace(targetPath, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := services.NewUploadParams()
|
||||||
|
params.Pattern = sourceFilename
|
||||||
|
params.Target = targetPath
|
||||||
|
params.Flat = true
|
||||||
|
|
||||||
|
_, _, err := storage.manager.UploadFiles(artifactory.UploadServiceOptions{}, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) Remove(path string) error {
|
||||||
|
targetPath := filepath.Join(storage.repository, storage.prefix, path)
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
targetPath = strings.Replace(targetPath, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteParams := services.NewDeleteParams()
|
||||||
|
deleteParams.SetPattern(targetPath)
|
||||||
|
|
||||||
|
res, err := storage.manager.GetPathsToDelete(deleteParams)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Close()
|
||||||
|
_, err = storage.manager.DeleteFiles(res)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress) error {
|
||||||
|
return storage.Remove(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) LinkFromPool(publishedPrefix, publishedRelPath, fileName string, sourcePool aptly.PackagePool, sourcePath string, sourceMD5 aptly_utils.ChecksumInfo, force bool) error {
|
||||||
|
return storage.PutFile(filepath.Join(publishedPrefix, publishedRelPath, fileName), sourcePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) Filelist(prefix string) ([]string, error) {
|
||||||
|
searchPattern := filepath.Join(storage.repository, storage.prefix, prefix, "*")
|
||||||
|
params := services.NewSearchParams()
|
||||||
|
params.Pattern = searchPattern
|
||||||
|
|
||||||
|
reader, err := storage.manager.SearchFiles(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
var paths []string
|
||||||
|
var md5s []string
|
||||||
|
|
||||||
|
for element := new(utils.ResultItem); reader.NextRecord(element) == nil; element = new(utils.ResultItem) {
|
||||||
|
path := element.Path + "/" + element.Name
|
||||||
|
relPath := strings.TrimPrefix(path, storage.repository + "/" + storage.prefix + "/")
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
relPath = strings.Replace(relPath, "%2B", "+", -1)
|
||||||
|
}
|
||||||
|
paths = append(paths, relPath)
|
||||||
|
md5s = append(md5s, element.Actual_Md5)
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) RenameFile(oldName, newName string) error {
|
||||||
|
oldTarget := filepath.Join(storage.repository, storage.prefix, oldName)
|
||||||
|
newTarget := filepath.Join(storage.repository, storage.prefix, newName)
|
||||||
|
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
oldTarget = strings.Replace(oldTarget, "+", "%2B", -1)
|
||||||
|
newTarget = strings.Replace(newTarget, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := services.NewMoveCopyParams()
|
||||||
|
params.Pattern = oldTarget
|
||||||
|
params.Target = newTarget
|
||||||
|
params.Flat = true
|
||||||
|
|
||||||
|
_, _, err := storage.manager.Move(params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) SymLink(src string, dst string) error {
|
||||||
|
oldTarget := filepath.Join(storage.repository, storage.prefix, src)
|
||||||
|
newTarget := filepath.Join(storage.repository, storage.prefix, dst)
|
||||||
|
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
oldTarget = strings.Replace(oldTarget, "+", "%2B", -1)
|
||||||
|
newTarget = strings.Replace(newTarget, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := services.NewMoveCopyParams()
|
||||||
|
params.Pattern = oldTarget
|
||||||
|
params.Target = newTarget
|
||||||
|
params.Flat = true
|
||||||
|
|
||||||
|
props := utils.NewProperties()
|
||||||
|
props.AddProperty("SymLink", src)
|
||||||
|
params.SetTargetProps(props)
|
||||||
|
|
||||||
|
_, _, err := storage.manager.Copy(params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) HardLink(src string, dst string) error {
|
||||||
|
return storage.SymLink(src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) FileExists(path string) (bool, error) {
|
||||||
|
targetPath := filepath.Join(storage.repository, storage.prefix, path)
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
targetPath = strings.Replace(targetPath, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := services.NewSearchParams()
|
||||||
|
params.Pattern = targetPath
|
||||||
|
|
||||||
|
reader, err := storage.manager.SearchFiles(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
length, err := reader.Length()
|
||||||
|
isEmpty := length == 0
|
||||||
|
return !isEmpty, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (storage *PublishedStorage) ReadLink(path string) (string, error) {
|
||||||
|
targetPath := filepath.Join(storage.repository, storage.prefix, path)
|
||||||
|
if storage.plusWorkaround {
|
||||||
|
targetPath = strings.Replace(targetPath, "+", "%2B", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
props, err := storage.manager.GetItemProps(targetPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range props.Properties {
|
||||||
|
if k == "SymLink" && len(v) > 0 {
|
||||||
|
return v[0], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ gpg_keys: []
|
|||||||
skip_contents_publishing: false
|
skip_contents_publishing: false
|
||||||
skip_bz2_publishing: false
|
skip_bz2_publishing: false
|
||||||
filesystem_publish_endpoints: {}
|
filesystem_publish_endpoints: {}
|
||||||
|
jfrog_publish_endpoints: {}
|
||||||
s3_publish_endpoints: {}
|
s3_publish_endpoints: {}
|
||||||
gcs_publish_endpoints: {}
|
gcs_publish_endpoints: {}
|
||||||
swift_publish_endpoints: {}
|
swift_publish_endpoints: {}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ type ConfigStructure struct { // nolint: maligned
|
|||||||
|
|
||||||
// Storage
|
// Storage
|
||||||
FileSystemPublishRoots map[string]FileSystemPublishRoot `json:"FileSystemPublishEndpoints" yaml:"filesystem_publish_endpoints"`
|
FileSystemPublishRoots map[string]FileSystemPublishRoot `json:"FileSystemPublishEndpoints" yaml:"filesystem_publish_endpoints"`
|
||||||
|
JFrogPublishRoots map[string]JFrogPublishRoot `json:"JFrogPublishEndpoints" yaml:"jfrog_publish_endpoints"`
|
||||||
S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints" yaml:"s3_publish_endpoints"`
|
S3PublishRoots map[string]S3PublishRoot `json:"S3PublishEndpoints" yaml:"s3_publish_endpoints"`
|
||||||
GCSPublishRoots map[string]GCSPublishRoot `json:"GcsPublishEndpoints" yaml:"gcs_publish_endpoints"`
|
GCSPublishRoots map[string]GCSPublishRoot `json:"GcsPublishEndpoints" yaml:"gcs_publish_endpoints"`
|
||||||
SwiftPublishRoots map[string]SwiftPublishRoot `json:"SwiftPublishEndpoints" yaml:"swift_publish_endpoints"`
|
SwiftPublishRoots map[string]SwiftPublishRoot `json:"SwiftPublishEndpoints" yaml:"swift_publish_endpoints"`
|
||||||
@@ -172,6 +173,19 @@ type FileSystemPublishRoot struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// S3PublishRoot describes single S3 publishing entry point
|
// S3PublishRoot describes single S3 publishing entry point
|
||||||
|
|
||||||
|
type JFrogPublishRoot struct {
|
||||||
|
Repository string `json:"repository" yaml:"repository"`
|
||||||
|
Url string `json:"url" yaml:"url"`
|
||||||
|
User string `json:"user" yaml:"user"`
|
||||||
|
Password string `json:"password" yaml:"password"`
|
||||||
|
ApiKey string `json:"apiKey" yaml:"api_key"`
|
||||||
|
AccessToken string `json:"accessToken" yaml:"access_token"`
|
||||||
|
Prefix string `json:"prefix" yaml:"prefix"`
|
||||||
|
PlusWorkaround bool `json:"plusWorkaround" yaml:"plus_workaround"`
|
||||||
|
Debug bool `json:"debug" yaml:"debug"`
|
||||||
|
}
|
||||||
|
|
||||||
type S3PublishRoot struct {
|
type S3PublishRoot struct {
|
||||||
Region string `json:"region" yaml:"region"`
|
Region string `json:"region" yaml:"region"`
|
||||||
Bucket string `json:"bucket" yaml:"bucket"`
|
Bucket string `json:"bucket" yaml:"bucket"`
|
||||||
|
|||||||
+122
-226
@@ -45,6 +45,10 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
|
|||||||
s.config.FileSystemPublishRoots = map[string]FileSystemPublishRoot{"test": {
|
s.config.FileSystemPublishRoots = map[string]FileSystemPublishRoot{"test": {
|
||||||
RootDir: "/opt/aptly-publish"}}
|
RootDir: "/opt/aptly-publish"}}
|
||||||
|
|
||||||
|
s.config.JFrogPublishRoots = map[string]JFrogPublishRoot{"test": {
|
||||||
|
Repository: "repo",
|
||||||
|
Url: "jfrog.example.com"}}
|
||||||
|
|
||||||
s.config.S3PublishRoots = map[string]S3PublishRoot{"test": {
|
s.config.S3PublishRoots = map[string]S3PublishRoot{"test": {
|
||||||
Region: "us-east-1",
|
Region: "us-east-1",
|
||||||
Bucket: "repo"}}
|
Bucket: "repo"}}
|
||||||
@@ -73,232 +77,124 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
|
|||||||
buf := make([]byte, st.Size())
|
buf := make([]byte, st.Size())
|
||||||
_, _ = f.Read(buf)
|
_, _ = f.Read(buf)
|
||||||
|
|
||||||
c.Check(string(buf), Equals, ""+
|
c.Check(string(buf), Equals, `{
|
||||||
"{\n" +
|
"rootDir": "/tmp/aptly",
|
||||||
" \"rootDir\": \"/tmp/aptly\",\n" +
|
"logLevel": "info",
|
||||||
" \"logLevel\": \"info\",\n" +
|
"logFormat": "json",
|
||||||
" \"logFormat\": \"json\",\n" +
|
"databaseOpenAttempts": 5,
|
||||||
" \"databaseOpenAttempts\": 5,\n" +
|
"architectures": null,
|
||||||
" \"architectures\": null,\n" +
|
"skipLegacyPool": false,
|
||||||
" \"skipLegacyPool\": false,\n" +
|
"dependencyFollowSuggests": false,
|
||||||
" \"dependencyFollowSuggests\": false,\n" +
|
"dependencyFollowRecommends": false,
|
||||||
" \"dependencyFollowRecommends\": false,\n" +
|
"dependencyFollowAllVariants": false,
|
||||||
" \"dependencyFollowAllVariants\": false,\n" +
|
"dependencyFollowSource": false,
|
||||||
" \"dependencyFollowSource\": false,\n" +
|
"dependencyVerboseResolve": false,
|
||||||
" \"dependencyVerboseResolve\": false,\n" +
|
"ppaDistributorID": "",
|
||||||
" \"ppaDistributorID\": \"\",\n" +
|
"ppaCodename": "",
|
||||||
" \"ppaCodename\": \"\",\n" +
|
"ppaBaseURL": "",
|
||||||
" \"ppaBaseURL\": \"\",\n" +
|
"serveInAPIMode": false,
|
||||||
" \"serveInAPIMode\": false,\n" +
|
"enableMetricsEndpoint": false,
|
||||||
" \"enableMetricsEndpoint\": false,\n" +
|
"enableSwaggerEndpoint": false,
|
||||||
" \"enableSwaggerEndpoint\": false,\n" +
|
"AsyncAPI": false,
|
||||||
" \"AsyncAPI\": false,\n" +
|
"databaseBackend": {
|
||||||
" \"databaseBackend\": {\n" +
|
"type": "",
|
||||||
" \"type\": \"\",\n" +
|
"dbPath": "",
|
||||||
" \"dbPath\": \"\",\n" +
|
"url": ""
|
||||||
" \"url\": \"\"\n" +
|
},
|
||||||
" },\n" +
|
"downloader": "",
|
||||||
" \"downloader\": \"\",\n" +
|
"downloadConcurrency": 5,
|
||||||
" \"downloadConcurrency\": 5,\n" +
|
"downloadSpeedLimit": 0,
|
||||||
" \"downloadSpeedLimit\": 0,\n" +
|
"downloadRetries": 0,
|
||||||
" \"downloadRetries\": 0,\n" +
|
"downloadSourcePackages": false,
|
||||||
" \"downloadSourcePackages\": false,\n" +
|
"gpgProvider": "gpg",
|
||||||
" \"gpgProvider\": \"gpg\",\n" +
|
"gpgDisableSign": false,
|
||||||
" \"gpgDisableSign\": false,\n" +
|
"gpgDisableVerify": false,
|
||||||
" \"gpgDisableVerify\": false,\n" +
|
"gpgKeys": null,
|
||||||
" \"gpgKeys\": null,\n" +
|
"skipContentsPublishing": false,
|
||||||
" \"skipContentsPublishing\": false,\n" +
|
"skipBz2Publishing": false,
|
||||||
" \"skipBz2Publishing\": false,\n" +
|
"FileSystemPublishEndpoints": {
|
||||||
" \"FileSystemPublishEndpoints\": {\n" +
|
"test": {
|
||||||
" \"test\": {\n" +
|
"rootDir": "/opt/aptly-publish",
|
||||||
" \"rootDir\": \"/opt/aptly-publish\",\n" +
|
"linkMethod": "",
|
||||||
" \"linkMethod\": \"\",\n" +
|
"verifyMethod": ""
|
||||||
" \"verifyMethod\": \"\"\n" +
|
}
|
||||||
" }\n" +
|
},
|
||||||
" },\n" +
|
"JFrogPublishEndpoints": {
|
||||||
" \"S3PublishEndpoints\": {\n" +
|
"test": {
|
||||||
" \"test\": {\n" +
|
"repository": "repo",
|
||||||
" \"region\": \"us-east-1\",\n" +
|
"url": "jfrog.example.com",
|
||||||
" \"bucket\": \"repo\",\n" +
|
"user": "",
|
||||||
" \"prefix\": \"\",\n" +
|
"password": "",
|
||||||
" \"acl\": \"\",\n" +
|
"apiKey": "",
|
||||||
" \"awsAccessKeyID\": \"\",\n" +
|
"accessToken": "",
|
||||||
" \"awsSecretAccessKey\": \"\",\n" +
|
"prefix": "",
|
||||||
" \"awsSessionToken\": \"\",\n" +
|
"plusWorkaround": false,
|
||||||
" \"endpoint\": \"\",\n" +
|
"debug": false
|
||||||
" \"storageClass\": \"\",\n" +
|
}
|
||||||
" \"encryptionMethod\": \"\",\n" +
|
},
|
||||||
" \"plusWorkaround\": false,\n" +
|
"S3PublishEndpoints": {
|
||||||
" \"disableMultiDel\": false,\n" +
|
"test": {
|
||||||
" \"forceSigV2\": false,\n" +
|
"region": "us-east-1",
|
||||||
" \"forceVirtualHostedStyle\": false,\n" +
|
"bucket": "repo",
|
||||||
" \"debug\": false\n" +
|
"prefix": "",
|
||||||
" }\n" +
|
"acl": "",
|
||||||
" },\n" +
|
"awsAccessKeyID": "",
|
||||||
" \"GcsPublishEndpoints\": {\n" +
|
"awsSecretAccessKey": "",
|
||||||
" \"test\": {\n" +
|
"awsSessionToken": "",
|
||||||
" \"bucket\": \"repo\",\n" +
|
"endpoint": "",
|
||||||
" \"prefix\": \"\",\n" +
|
"storageClass": "",
|
||||||
" \"credentialsFile\": \"\",\n" +
|
"encryptionMethod": "",
|
||||||
" \"serviceAccountJSON\": \"\",\n" +
|
"plusWorkaround": false,
|
||||||
" \"project\": \"\",\n" +
|
"disableMultiDel": false,
|
||||||
" \"endpoint\": \"\",\n" +
|
"forceSigV2": false,
|
||||||
" \"acl\": \"\",\n" +
|
"forceVirtualHostedStyle": false,
|
||||||
" \"storageClass\": \"\",\n" +
|
"debug": false
|
||||||
" \"encryptionKey\": \"\",\n" +
|
}
|
||||||
" \"disableMultiDel\": false,\n" +
|
},
|
||||||
" \"debug\": false\n" +
|
"GcsPublishEndpoints": {
|
||||||
" }\n" +
|
"test": {
|
||||||
" },\n" +
|
"bucket": "repo",
|
||||||
" \"SwiftPublishEndpoints\": {\n" +
|
"prefix": "",
|
||||||
" \"test\": {\n" +
|
"credentialsFile": "",
|
||||||
" \"container\": \"repo\",\n" +
|
"serviceAccountJSON": "",
|
||||||
" \"prefix\": \"\",\n" +
|
"project": "",
|
||||||
" \"osname\": \"\",\n" +
|
"endpoint": "",
|
||||||
" \"password\": \"\",\n" +
|
"acl": "",
|
||||||
" \"tenant\": \"\",\n" +
|
"storageClass": "",
|
||||||
" \"tenantid\": \"\",\n" +
|
"encryptionKey": "",
|
||||||
" \"domain\": \"\",\n" +
|
"disableMultiDel": false,
|
||||||
" \"domainid\": \"\",\n" +
|
"debug": false
|
||||||
" \"tenantdomain\": \"\",\n" +
|
}
|
||||||
" \"tenantdomainid\": \"\",\n" +
|
},
|
||||||
" \"authurl\": \"\"\n" +
|
"SwiftPublishEndpoints": {
|
||||||
" }\n" +
|
"test": {
|
||||||
" },\n" +
|
"container": "repo",
|
||||||
" \"AzurePublishEndpoints\": {\n" +
|
"prefix": "",
|
||||||
" \"test\": {\n" +
|
"osname": "",
|
||||||
" \"container\": \"repo\",\n" +
|
"password": "",
|
||||||
" \"prefix\": \"\",\n" +
|
"tenant": "",
|
||||||
" \"accountName\": \"\",\n" +
|
"tenantid": "",
|
||||||
" \"accountKey\": \"\",\n" +
|
"domain": "",
|
||||||
" \"endpoint\": \"\"\n" +
|
"domainid": "",
|
||||||
" }\n" +
|
"tenantdomain": "",
|
||||||
" },\n" +
|
"tenantdomainid": "",
|
||||||
" \"packagePoolStorage\": {\n" +
|
"authurl": ""
|
||||||
" \"type\": \"local\",\n" +
|
}
|
||||||
" \"path\": \"/tmp/aptly-pool\"\n" +
|
},
|
||||||
" }\n" +
|
"AzurePublishEndpoints": {
|
||||||
"}")
|
"test": {
|
||||||
}
|
"container": "repo",
|
||||||
|
"prefix": "",
|
||||||
func (s *ConfigSuite) TestLoadYAMLConfig(c *C) {
|
"accountName": "",
|
||||||
configname := filepath.Join(c.MkDir(), "aptly.yaml1")
|
"accountKey": "",
|
||||||
f, _ := os.Create(configname)
|
"endpoint": ""
|
||||||
_, _ = f.WriteString(configFileYAML)
|
}
|
||||||
_ = f.Close()
|
},
|
||||||
|
"packagePoolStorage": {
|
||||||
// start with empty config
|
"type": "local",
|
||||||
s.config = ConfigStructure{}
|
"path": "/tmp/aptly-pool"
|
||||||
|
}
|
||||||
err := LoadConfig(configname, &s.config)
|
}`)
|
||||||
c.Assert(err, IsNil)
|
|
||||||
c.Check(s.config.GetRootDir(), Equals, "/opt/aptly/")
|
|
||||||
c.Check(s.config.DownloadConcurrency, Equals, 40)
|
|
||||||
c.Check(s.config.DatabaseOpenAttempts, Equals, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ConfigSuite) TestLoadYAMLErrorConfig(c *C) {
|
|
||||||
configname := filepath.Join(c.MkDir(), "aptly.yaml2")
|
|
||||||
f, _ := os.Create(configname)
|
|
||||||
_, _ = f.WriteString(configFileYAMLError)
|
|
||||||
_ = f.Close()
|
|
||||||
|
|
||||||
// start with empty config
|
|
||||||
s.config = ConfigStructure{}
|
|
||||||
|
|
||||||
err := LoadConfig(configname, &s.config)
|
|
||||||
c.Assert(err.Error(), Equals, "invalid yaml (unknown pool storage type: invalid) or json (invalid character 'p' looking for beginning of value)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ConfigSuite) TestSaveYAMLConfig(c *C) {
|
|
||||||
configname := filepath.Join(c.MkDir(), "aptly.yaml3")
|
|
||||||
f, _ := os.Create(configname)
|
|
||||||
_, _ = f.WriteString(configFileYAML)
|
|
||||||
_ = f.Close()
|
|
||||||
|
|
||||||
// start with empty config
|
|
||||||
s.config = ConfigStructure{}
|
|
||||||
|
|
||||||
err := LoadConfig(configname, &s.config)
|
|
||||||
c.Assert(err, IsNil)
|
|
||||||
|
|
||||||
err = SaveConfigYAML(configname, &s.config)
|
|
||||||
c.Assert(err, IsNil)
|
|
||||||
|
|
||||||
f, _ = os.Open(configname)
|
|
||||||
defer func() {
|
|
||||||
_ = f.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
st, _ := f.Stat()
|
|
||||||
buf := make([]byte, st.Size())
|
|
||||||
_, _ = f.Read(buf)
|
|
||||||
|
|
||||||
c.Check(string(buf), Equals, configFileYAML)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ConfigSuite) TestSaveYAML2Config(c *C) {
|
|
||||||
// start with empty config
|
|
||||||
s.config = ConfigStructure{}
|
|
||||||
|
|
||||||
s.config.PackagePoolStorage.Local = &LocalPoolStorage{"/tmp/aptly-pool"}
|
|
||||||
s.config.PackagePoolStorage.Azure = nil
|
|
||||||
|
|
||||||
configname := filepath.Join(c.MkDir(), "aptly.yaml4")
|
|
||||||
err := SaveConfigYAML(configname, &s.config)
|
|
||||||
c.Assert(err, IsNil)
|
|
||||||
|
|
||||||
f, _ := os.Open(configname)
|
|
||||||
defer func() {
|
|
||||||
_ = f.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
st, _ := f.Stat()
|
|
||||||
buf := make([]byte, st.Size())
|
|
||||||
_, _ = f.Read(buf)
|
|
||||||
|
|
||||||
c.Check(string(buf), Equals, "" +
|
|
||||||
"root_dir: \"\"\n" +
|
|
||||||
"log_level: \"\"\n" +
|
|
||||||
"log_format: \"\"\n" +
|
|
||||||
"database_open_attempts: 0\n" +
|
|
||||||
"architectures: []\n" +
|
|
||||||
"skip_legacy_pool: false\n" +
|
|
||||||
"dep_follow_suggests: false\n" +
|
|
||||||
"dep_follow_recommends: false\n" +
|
|
||||||
"dep_follow_all_variants: false\n" +
|
|
||||||
"dep_follow_source: false\n" +
|
|
||||||
"dep_verboseresolve: false\n" +
|
|
||||||
"ppa_distributor_id: \"\"\n" +
|
|
||||||
"ppa_codename: \"\"\n" +
|
|
||||||
"ppa_baseurl: \"\"\n" +
|
|
||||||
"serve_in_api_mode: false\n" +
|
|
||||||
"enable_metrics_endpoint: false\n" +
|
|
||||||
"enable_swagger_endpoint: false\n" +
|
|
||||||
"async_api: false\n" +
|
|
||||||
"database_backend:\n" +
|
|
||||||
" type: \"\"\n" +
|
|
||||||
" db_path: \"\"\n" +
|
|
||||||
" url: \"\"\n" +
|
|
||||||
"downloader: \"\"\n" +
|
|
||||||
"download_concurrency: 0\n" +
|
|
||||||
"download_limit: 0\n" +
|
|
||||||
"download_retries: 0\n" +
|
|
||||||
"download_sourcepackages: false\n" +
|
|
||||||
"gpg_provider: \"\"\n" +
|
|
||||||
"gpg_disable_sign: false\n" +
|
|
||||||
"gpg_disable_verify: false\n" +
|
|
||||||
"gpg_keys: []\n" +
|
|
||||||
"skip_contents_publishing: false\n" +
|
|
||||||
"skip_bz2_publishing: false\n" +
|
|
||||||
"filesystem_publish_endpoints: {}\n" +
|
|
||||||
"s3_publish_endpoints: {}\n" +
|
|
||||||
"gcs_publish_endpoints: {}\n" +
|
|
||||||
"swift_publish_endpoints: {}\n" +
|
|
||||||
"azure_publish_endpoints: {}\n" +
|
|
||||||
"packagepool_storage:\n" +
|
|
||||||
" type: local\n" +
|
|
||||||
" path: /tmp/aptly-pool\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConfigSuite) TestLoadEmptyConfig(c *C) {
|
func (s *ConfigSuite) TestLoadEmptyConfig(c *C) {
|
||||||
|
|||||||
Reference in New Issue
Block a user