Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ind Agent] Update packaging to properly package from manifest if given #4885

Merged
merged 37 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7a0913e
Download from manifest if version has +1 patch
dwhyrock Jun 6, 2024
e7d6a3e
Try modified globExpr
dwhyrock Jun 7, 2024
41fe9fb
use version package
dwhyrock Jun 7, 2024
9f1af73
catch err
dwhyrock Jun 7, 2024
1fad3b2
use panic
dwhyrock Jun 7, 2024
18456a9
Add the filepath
dwhyrock Jun 7, 2024
ac0f535
better package finding
dwhyrock Jun 12, 2024
5c13998
more intermediate work
dwhyrock Jun 13, 2024
9b0a181
more progress
dwhyrock Jun 17, 2024
bacda1f
it seems to maybe work
dwhyrock Jun 18, 2024
49a9dfc
fixed bug
dwhyrock Jun 18, 2024
8c9e21a
Copying spec files as well
dwhyrock Jun 18, 2024
2f05b52
temp test value
dwhyrock Jun 18, 2024
4f827be
fixing linting errors
dwhyrock Jun 18, 2024
01ead7e
Merge branch 'main' into ind-agent-fix-package-endpoint-next-version
dwhyrock Jun 18, 2024
3d9f4ca
Clean up manifest code
dwhyrock Jun 18, 2024
48c65c3
Cleaning up
dwhyrock Jun 18, 2024
5f1ab42
Cleanup 2
dwhyrock Jun 19, 2024
619512d
removing test variable
dwhyrock Jun 19, 2024
9afa054
addressing PR comments and cleanup
dwhyrock Jun 20, 2024
36c2fac
Adding manifest tests
dwhyrock Jun 20, 2024
5f11a2b
Update magefile.go
dwhyrock Jun 20, 2024
8d9bd37
Merge branch 'main' into ind-agent-fix-package-endpoint-next-version
pierrehilbert Jun 21, 2024
799ed15
Switch to go:embed for tests.
cmacknz Jun 24, 2024
4fd3c50
Build component specs from external binaries.
cmacknz Jun 26, 2024
ff3d84a
Convert component to project in var names
cmacknz Jun 26, 2024
6a8c4ae
Return error when package not found.
cmacknz Jun 26, 2024
9fd0ffa
Filter unsupported platforms.
cmacknz Jun 26, 2024
9eda0ac
Fix darwin/arm64 build.
cmacknz Jun 26, 2024
026ece7
Several renames for consistency.
cmacknz Jun 26, 2024
ab3ecae
A few more renames.
cmacknz Jun 26, 2024
b4ce8c7
Move code out of magefile
cmacknz Jun 26, 2024
11404b1
mage fmt
cmacknz Jun 26, 2024
539d648
Fix log message.
cmacknz Jun 26, 2024
c495c94
Fix lint warnings.
cmacknz Jun 26, 2024
03e64b1
Rename test.
cmacknz Jun 26, 2024
7754ffd
Refactor to share download from manifest logic.
cmacknz Jun 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 75 additions & 15 deletions dev-tools/mage/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"os"
"path"
"path/filepath"
"strings"
"time"

"github.com/magefile/mage/mg"
Expand All @@ -38,6 +39,17 @@ var errorNotAllowedManifestURL = errors.New("the provided ManifestURL is not all

var AllowedManifestHosts = []string{"snapshots.elastic.co", "staging.elastic.co"}

var ComponentSpec = map[string][]string{
"apm-server": {"apm-server"},
"beats": {"agentbeat"},
"cloud-defend": {"cloud-defend"},
"cloudbeat": {"cloudbeat"},
"elastic-agent-shipper": {"elastic-agent-shipper"},
"endpoint-dev": {"endpoint-security"},
"fleet-server": {"fleet-server"},
"prodfiler": {"pf-elastic-collector", "pf-elastic-symbolizer", "pf-host-agent"},
}

// DownloadManifest is going to download the given manifest file and return the ManifestResponse
func DownloadManifest(manifest string) (tools.Build, error) {
manifestUrl, urlError := url.Parse(manifest)
Expand Down Expand Up @@ -68,32 +80,80 @@ func DownloadManifest(manifest string) (tools.Build, error) {
}

func resolveManifestPackage(project tools.Project, pkg string, reqPackage string, version string) []string {
var val tools.Package
var ok bool

// Try the normal/easy case first
packageName := fmt.Sprintf("%s-%s-%s", pkg, version, reqPackage)
val, ok := project.Packages[packageName]
val, ok = project.Packages[packageName]
cmacknz marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return nil
// If we didn't find it, it may be an Independent Agent Release, where
// the opted-in projects will have a patch version one higher than
// the rest of the projects, so we need to seek that out
if mg.Verbose() {
log.Printf(">>>>>>>>>>> Looking for package [%s] of type [%s]", pkg, reqPackage)
}

var foundIt bool
for pkgName := range project.Packages {
if strings.HasPrefix(pkgName, pkg) {
firstSplit := strings.Split(pkgName, pkg+"-")
if len(firstSplit) < 2 {
continue
}

secondHalf := firstSplit[1]
// Make sure we're finding one w/ the same required package type
if strings.Contains(secondHalf, reqPackage) {

// Split again after the version with the required package string
secondSplit := strings.Split(secondHalf, "-"+reqPackage)
if len(secondSplit) < 2 {
continue
}

// The first element after the split should normally be the version
pkgVersion := secondSplit[0]
if mg.Verbose() {
log.Printf(">>>>>>>>>>> Using derived version for package [%s]: %s ", pkgName, pkgVersion)
}

// Create a project/package key with the package, derived version, and required package
foundPkgKey := fmt.Sprintf("%s-%s-%s", pkg, pkgVersion, reqPackage)
if mg.Verbose() {
log.Printf(">>>>>>>>>>> Looking for project package key: [%s]", foundPkgKey)
}

// Get the package value, if it exists
val, ok = project.Packages[foundPkgKey]
if !ok {
continue
}

if mg.Verbose() {
log.Printf(">>>>>>>>>>> Found package key [%s]", foundPkgKey)
}

foundIt = true
}
}
}

if !foundIt {
return nil
}
cmacknz marked this conversation as resolved.
Show resolved Hide resolved
}

if mg.Verbose() {
log.Printf(">>>>>>>>>>> Project branch/commit [%s, %s]", project.Branch, project.CommitHash)
}
return []string{val.URL, val.ShaURL, val.AscURL}

return []string{val.URL, val.ShaURL, val.AscURL}
}

// DownloadComponentsFromManifest is going to download a set of components from the given manifest into the destination
// dropPath folder in order to later use that folder for packaging
func DownloadComponentsFromManifest(manifest string, platforms []string, platformPackages map[string]string, dropPath string) error {
componentSpec := map[string][]string{
"apm-server": {"apm-server"},
"beats": {"agentbeat"},
"cloud-defend": {"cloud-defend"},
"cloudbeat": {"cloudbeat"},
"elastic-agent-shipper": {"elastic-agent-shipper"},
"endpoint-dev": {"endpoint-security"},
"fleet-server": {"fleet-server"},
"prodfiler": {"pf-elastic-collector", "pf-elastic-symbolizer", "pf-host-agent"},
}

manifestResponse, err := DownloadManifest(manifest)
if err != nil {
return fmt.Errorf("failed to download remote manifest file %w", err)
Expand All @@ -111,7 +171,7 @@ func DownloadComponentsFromManifest(manifest string, platforms []string, platfor
majorMinorPatchVersion := parsedManifestVersion.VersionWithPrerelease()

errGrp, downloadsCtx := errgroup.WithContext(context.Background())
for component, pkgs := range componentSpec {
for component, pkgs := range ComponentSpec {
for _, platform := range platforms {
targetPath := filepath.Join(dropPath)
err := os.MkdirAll(targetPath, 0755)
Expand Down
138 changes: 138 additions & 0 deletions dev-tools/mage/manifest/manifest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package manifest

import (
"encoding/json"
"log"
"os"
"path"
"runtime"
"testing"

"github.com/elastic/elastic-agent/pkg/testing/tools"
"github.com/stretchr/testify/assert"
)

// Helper to get the absolute path of the parent directory name of the current file
cmacknz marked this conversation as resolved.
Show resolved Hide resolved
func ParentDir() string {
_, filename, _, _ := runtime.Caller(1)
return path.Dir(filename)
}

func getManifestJsonData(t *testing.T, filePath string) tools.Build {
var response tools.Build

contents, err := os.Open(filePath)
assert.NoError(t, err)

err = json.NewDecoder(contents).Decode(&response)
assert.NoError(t, err)

return response
}

func TestBlah(t *testing.T) {
parentDir := ParentDir()

tcs := []struct {
name string
filePath string
componentName string
packageName string
requiredPackage string
expectedUrlList []string
}{
{
name: "Unified Release Staging 8.14 apm-server",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.2.json"),
componentName: "apm-server",
packageName: "apm-server",
requiredPackage: "linux-x86_64.tar.gz",
expectedUrlList: []string{
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/apm-server/apm-server-8.14.2-linux-x86_64.tar.gz",
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/apm-server/apm-server-8.14.2-linux-x86_64.tar.gz.sha512",
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/apm-server/apm-server-8.14.2-linux-x86_64.tar.gz.asc",
},
},
{
name: "Unified Release Snapshot 8.14 apm-server",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.2-SNAPSHOT.json"),
componentName: "apm-server",
packageName: "apm-server",
requiredPackage: "linux-x86_64.tar.gz",
expectedUrlList: []string{
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/apm-server/apm-server-8.14.2-SNAPSHOT-linux-x86_64.tar.gz",
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/apm-server/apm-server-8.14.2-SNAPSHOT-linux-x86_64.tar.gz.sha512",
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/apm-server/apm-server-8.14.2-SNAPSHOT-linux-x86_64.tar.gz.asc",
},
},
{
name: "Independent Agent Staging 8.14 apm-server",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.0+build202406201002.json"),
componentName: "apm-server",
packageName: "apm-server",
requiredPackage: "linux-x86_64.tar.gz",
expectedUrlList: []string{
"https://staging.elastic.co/8.14.0-fe696c51/downloads/apm-server/apm-server-8.14.0-linux-x86_64.tar.gz",
"https://staging.elastic.co/8.14.0-fe696c51/downloads/apm-server/apm-server-8.14.0-linux-x86_64.tar.gz.sha512",
"https://staging.elastic.co/8.14.0-fe696c51/downloads/apm-server/apm-server-8.14.0-linux-x86_64.tar.gz.asc",
},
},
{
name: "Unified Release Staging 8.14 endpoint-dev",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.2.json"),
componentName: "endpoint-dev",
packageName: "endpoint-security",
requiredPackage: "linux-x86_64.tar.gz",
expectedUrlList: []string{
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/endpoint-dev/endpoint-security-8.14.2-linux-x86_64.tar.gz",
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/endpoint-dev/endpoint-security-8.14.2-linux-x86_64.tar.gz.sha512",
"https://staging.elastic.co/8.14.2-cfd42f49/downloads/endpoint-dev/endpoint-security-8.14.2-linux-x86_64.tar.gz.asc",
},
},
{
name: "Unified Release Snapshot 8.14 endpoint-dev",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.2-SNAPSHOT.json"),
componentName: "endpoint-dev",
packageName: "endpoint-security",
requiredPackage: "linux-x86_64.tar.gz",
expectedUrlList: []string{
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/endpoint-dev/endpoint-security-8.14.2-SNAPSHOT-linux-x86_64.tar.gz",
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/endpoint-dev/endpoint-security-8.14.2-SNAPSHOT-linux-x86_64.tar.gz.sha512",
"https://snapshots.elastic.co/8.14.2-1ceac187/downloads/endpoint-dev/endpoint-security-8.14.2-SNAPSHOT-linux-x86_64.tar.gz.asc",
},
},
{
name: "Independent Agent Staging 8.14 endpoint-dev",
filePath: path.Join(parentDir, "test_payload", "manifest-8.14.0+build202406201002.json"),
componentName: "endpoint-dev",
packageName: "endpoint-security",
requiredPackage: "linux-x86_64.tar.gz",
// Note how the version is one patch release higher than the manifest - this is expected
expectedUrlList: []string{
"https://staging.elastic.co/independent-agent/8.14.1+build202406201002/downloads/endpoint-dev/endpoint-security-8.14.1-linux-x86_64.tar.gz",
"https://staging.elastic.co/independent-agent/8.14.1+build202406201002/downloads/endpoint-dev/endpoint-security-8.14.1-linux-x86_64.tar.gz.sha512",
"https://staging.elastic.co/independent-agent/8.14.1+build202406201002/downloads/endpoint-dev/endpoint-security-8.14.1-linux-x86_64.tar.gz.asc",
},
},
}

for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
manifestJson := getManifestJsonData(t, tc.filePath)
log.Printf("Manifest Version: [%s]", manifestJson.Version)

projects := manifestJson.Projects

// Verify the component name is in the ComponentSpec
_, ok := ComponentSpec[tc.componentName]
assert.True(t, ok)

urlList := resolveManifestPackage(projects[tc.componentName], tc.packageName, tc.requiredPackage, manifestJson.Version)

assert.Len(t, urlList, 3)
for _, url := range urlList {
assert.Contains(t, tc.expectedUrlList, url)
}
})
}
}
Loading
Loading