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

add update testing target msi to pipeline #32627

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitlab/e2e_install_packages/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- E2E_MSI_TEST: TestInstall
- E2E_MSI_TEST: TestRepair
- E2E_MSI_TEST: TestUpgrade
- E2E_MSI_TEST: TestUpgradeFromLatest
- E2E_MSI_TEST: TestUpgradeRollback
- E2E_MSI_TEST: TestUpgradeRollbackWithoutCWS
- E2E_MSI_TEST: TestUpgradeChangeUser
Expand Down
1 change: 1 addition & 0 deletions .gitlab/e2e_testing_deploy/e2e_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ deploy_windows_testing-a7:
--recursive
--exclude "*"
--include "datadog-agent-7.*.msi"
--include "datadog-agent-upgrade-test-7.*.msi"
--include "datadog-installer-*-1-x86_64.msi"
--include "datadog-installer-*-1-x86_64.exe"
$OMNIBUS_PACKAGE_DIR s3://$WIN_S3_BUCKET/$WINDOWS_TESTING_S3_BUCKET_A7
Expand Down
2 changes: 1 addition & 1 deletion .gitlab/package_build/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
-e OMNIBUS_GIT_CACHE_DIR=${Env:TEMP}/${CI_PIPELINE_ID}/omnibus-git-cache
-e AGENT_FLAVOR=${AGENT_FLAVOR}
${WINBUILDIMAGE}
powershell -C "c:\mnt\tasks\winbuildscripts\Build-AgentPackages.ps1 -BuildOutOfSource 1 -InstallDeps 1 -CheckGoVersion 1"
powershell -C "c:\mnt\tasks\winbuildscripts\Build-AgentPackages.ps1 -BuildOutOfSource 1 -InstallDeps 1 -CheckGoVersion 1 -BuildUpgrade 1"
- If ($lastExitCode -ne "0") { throw "Previous command returned $lastExitCode" }
- get-childitem omnibus\pkg
- !reference [.upload_sbom_artifacts_windows]
Expand Down
34 changes: 25 additions & 9 deletions tasks/msi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from invoke.exceptions import Exit, UnexpectedExit

from tasks.libs.common.utils import download_to_tempfile, timed
from tasks.libs.releasing.version import get_version, load_release_versions
from tasks.libs.releasing.version import VERSION_RE, _create_version_from_match, get_version, load_release_versions

# Windows only import
try:
Expand Down Expand Up @@ -80,6 +80,7 @@ def _get_env(ctx, major_version='7', release_version='nightly'):
env['AGENT_FLAVOR'] = os.getenv("AGENT_FLAVOR", "")
env['AGENT_INSTALLER_OUTPUT_DIR'] = BUILD_OUTPUT_DIR
env['NUGET_PACKAGES_DIR'] = NUGET_PACKAGES_DIR
env['AGENT_PRODUCT_NAME_SUFFIX'] = ""

return env

Expand Down Expand Up @@ -272,13 +273,15 @@ def _build_msi(ctx, env, outdir, name, allowlist):

def _msi_output_name(env):
if _is_fips_mode(env):
return f"datadog-fips-agent-{env['PACKAGE_VERSION']}-1-x86_64"
return f"datadog-fips-agent-{env['AGENT_PRODUCT_NAME_SUFFIX']}{env['PACKAGE_VERSION']}-1-x86_64"
else:
return f"datadog-agent-{env['PACKAGE_VERSION']}-1-x86_64"
return f"datadog-agent-{env['AGENT_PRODUCT_NAME_SUFFIX']}{env['PACKAGE_VERSION']}-1-x86_64"


@task
def build(ctx, vstudio_root=None, arch="x64", major_version='7', release_version='nightly', debug=False):
def build(
ctx, vstudio_root=None, arch="x64", major_version='7', release_version='nightly', debug=False, build_upgrade=False
):
"""
Build the MSI installer for the agent
"""
Expand Down Expand Up @@ -320,12 +323,25 @@ def build(ctx, vstudio_root=None, arch="x64", major_version='7', release_version
# And copy it to the final output path as a build artifact
shutil.copy2(os.path.join(build_outdir, msi_name + '.msi'), OUTPUT_PATH)

# if the optional upgrade test helper exists then build that too
optional_name = "datadog-agent-7.43.0~rc.3+git.485.14b9337-1-x86_64"
if os.path.exists(os.path.join(build_outdir, optional_name + ".wxs")):
# Build the optional upgrade test helper
if build_upgrade:
print("Building optional upgrade test helper")
upgrade_env = env.copy()
version = _create_version_from_match(VERSION_RE.search(env['PACKAGE_VERSION']))
next_version = version.next_version(bump_patch=True)
upgrade_env['PACKAGE_VERSION'] = upgrade_env['PACKAGE_VERSION'].replace(str(version), str(next_version))
upgrade_env['AGENT_PRODUCT_NAME_SUFFIX'] = "upgrade-test-"
_build_wxs(
ctx,
upgrade_env,
build_outdir,
'AgentCustomActions.CA.dll',
)
msi_name = _msi_output_name(upgrade_env)
print(os.path.join(build_outdir, msi_name + ".wxs"))
with timed("Building optional MSI"):
_build_msi(ctx, env, build_outdir, optional_name, DATADOG_AGENT_MSI_ALLOW_LIST)
shutil.copy2(os.path.join(build_outdir, optional_name + '.msi'), OUTPUT_PATH)
_build_msi(ctx, env, build_outdir, msi_name, DATADOG_AGENT_MSI_ALLOW_LIST)
shutil.copy2(os.path.join(build_outdir, msi_name + '.msi'), OUTPUT_PATH)


@task
Expand Down
3 changes: 2 additions & 1 deletion tasks/winbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def agent_package(
flavor=AgentFlavor.base.name,
release_version="nightly-a7",
skip_deps=False,
build_upgrade=False,
):
# Build agent
omnibus_build(
Expand All @@ -31,7 +32,7 @@ def agent_package(
)

# Package Agent into MSI
build_agent_msi(ctx, release_version=release_version)
build_agent_msi(ctx, release_version=release_version, build_upgrade=build_upgrade)

# Package MSI into OCI
if AgentFlavor[flavor] == AgentFlavor.base:
Expand Down
12 changes: 11 additions & 1 deletion tasks/winbuildscripts/Build-AgentPackages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ Specifies the release version of the build. Default is the value of the environm
.PARAMETER Flavor
Specifies the flavor of the agent. Default is the value of the environment variable AGENT_FLAVOR.

.PARAMETER BuildUpgrade
Specifies whether to build the upgrade package. Default is false.

Use this options to build an aditional MSI for testing upgrading the MSI.

.PARAMETER BuildOutOfSource
Specifies whether to build out of source. Default is $false.

Expand Down Expand Up @@ -38,7 +43,8 @@ param(
[nullable[bool]] $CheckGoVersion,
[bool] $InstallDeps = $true,
[string] $ReleaseVersion = $env:RELEASE_VERSION,
[string] $Flavor = $env:AGENT_FLAVOR
[string] $Flavor = $env:AGENT_FLAVOR,
[bool] $BuildUpgrade = $false
)

. "$PSScriptRoot\common.ps1"
Expand All @@ -63,6 +69,10 @@ Invoke-BuildScript `
$env:AGENT_FLAVOR=$Flavor
}

if ($BuildUpgrade) {
$inv_args += "--build-upgrade"
}

Write-Host "inv -e winbuild.agent-package $inv_args"
inv -e winbuild.agent-package @inv_args
if ($LASTEXITCODE -ne 0) {
Expand Down
8 changes: 7 additions & 1 deletion test/new-e2e/tests/windows/common/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import (
"testing"
"time"

infraCommon "github.com/DataDog/test-infra-definitions/common"

"github.com/DataDog/datadog-agent/pkg/version"
"github.com/DataDog/datadog-agent/test/new-e2e/pkg/components"
"github.com/DataDog/datadog-agent/test/new-e2e/pkg/runner"
"github.com/DataDog/datadog-agent/test/new-e2e/pkg/runner/parameters"
windowsCommon "github.com/DataDog/datadog-agent/test/new-e2e/tests/windows/common"
infraCommon "github.com/DataDog/test-infra-definitions/common"

"github.com/cenkalti/backoff/v4"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -55,6 +56,11 @@ func GetDatadogAgentProductCode(host *components.RemoteHost) (string, error) {
return windowsCommon.GetProductCodeByName(host, "Datadog Agent")
}

// GetDatadogProductVersion returns the product version for the Datadog Agent
func GetDatadogProductVersion(host *components.RemoteHost) (string, error) {
return windowsCommon.GetProductVersionByName(host, "Datadog Agent")
}

// InstallAgent installs the agent and returns the remote MSI path and any errors
func InstallAgent(host *components.RemoteHost, options ...InstallAgentOption) (string, error) {
p, err := infraCommon.ApplyOption(&InstallAgentParams{}, options)
Expand Down
49 changes: 47 additions & 2 deletions test/new-e2e/tests/windows/common/agent/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,12 @@ func GetLatestMSIURL(majorVersion string, arch string, flavor string) (string, e
// majorVersion: 6, 7
// arch: x86_64
// flavor: base, fips
func GetPipelineMSIURL(pipelineID string, majorVersion string, arch string, flavor string) (string, error) {
func GetPipelineMSIURL(pipelineID string, majorVersion string, arch string, flavor string, nameSuffix string) (string, error) {
productName, err := GetFlavorProductName(flavor)
if err != nil {
return "", err
}
productName = fmt.Sprintf("%s%s", productName, nameSuffix)
// Manual URL example: https://s3.amazonaws.com/dd-agent-mstesting?prefix=pipelines/A7/25309493
fmt.Printf("Looking for agent MSI for pipeline majorVersion %v %v\n", majorVersion, pipelineID)
artifactURL, err := pipeline.GetPipelineArtifact(pipelineID, pipeline.AgentS3BucketTesting, majorVersion, func(artifact string) bool {
Expand Down Expand Up @@ -337,7 +338,7 @@ func GetPackageFromEnv() (*Package, error) {

// check if we should use the URL from a specific CI pipeline
if pipelineIDFound {
url, err := GetPipelineMSIURL(pipelineID, majorVersion, arch, flavor)
url, err := GetPipelineMSIURL(pipelineID, majorVersion, arch, flavor, "")
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -431,3 +432,47 @@ func GetLastStablePackageFromEnv() (*Package, error) {
Flavor: flavor,
}, nil
}

// GetUpgradeTestPackageFromEnv returns the upgrade test package to use in upgrade test
//
// UPGRADABLE_WINDOWS_AGENT_MSI_URL: manually provided URL (all other parameters are informational only)
func GetUpgradeTestPackageFromEnv() (*Package, error) {
// Collect env opts
// version string will be same as main pipeline agent as the build does not change the emebeded versions
version, _ := LookupVersionFromEnv()
arch, _ := LookupArchFromEnv()
flavor, _ := LookupFlavorFromEnv()
pipelineID, pipelineIDFound := os.LookupEnv("E2E_PIPELINE_ID")

majorVersion := strings.Split(version, ".")[0]

// if UPGRADABLE_WINDOWS_AGENT_MSI_URL provided use it
url := os.Getenv("UPGRADABLE_WINDOWS_AGENT_MSI_URL")
if url != "" {
return &Package{
Channel: stableChannel,
Version: version,
Arch: arch,
URL: url,
Flavor: flavor,
}, nil
}

// check if we should use the URL from a specific CI pipeline
if pipelineIDFound {
url, err := GetPipelineMSIURL(pipelineID, majorVersion, arch, flavor, "-upgrade-test")
if err != nil {
return nil, err
}
return &Package{
PipelineID: pipelineID,
Version: version,
Arch: arch,
URL: url,
Flavor: flavor,
}, nil
}

// if not in pipeline or provided in env, then fail
return nil, fmt.Errorf("no upgradable package found")
}
21 changes: 21 additions & 0 deletions test/new-e2e/tests/windows/common/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,24 @@ func GetProductCodeByName(host *components.RemoteHost, name string) (string, err
}
return val, nil
}

// GetProductVersionByName returns the product version for the given product name
// Pulls version from MSI registry infomration
func GetProductVersionByName(host *components.RemoteHost, name string) (string, error) {
// get GUID
guid, err := GetProductCodeByName(host, name)
if err != nil {
return "", err
}
// get verion string
cmd := fmt.Sprintf(`(Get-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\%s").DisplayVersion`, guid)
val, err := host.Execute(cmd)
if err != nil {
return "", err
}
val = strings.TrimSpace(val)
if val == "" {
return "", fmt.Errorf("display version not found")
}
return val, nil
}
65 changes: 65 additions & 0 deletions test/new-e2e/tests/windows/install-test/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,71 @@ func (s *testUpgradeSuite) TestUpgrade() {
s.uninstallAgentAndRunUninstallTests(t)
}

// TestUpgrade tests upgrading the agent from WINDOWS_AGENT_VERSION to UPGRADE_TEST_VERSION
func TestUpgradeFromLatest(t *testing.T) {
s := &testUpgradeFromLatestSuite{}
upgradeAgentPackge, err := windowsAgent.GetUpgradeTestPackageFromEnv()
require.NoError(t, err, "should get last stable agent package from env")
s.upgradeAgentPackge = upgradeAgentPackge
run(t, s)
}

type testUpgradeFromLatestSuite struct {
baseAgentMSISuite
upgradeAgentPackge *windowsAgent.Package
}

func (s *testUpgradeFromLatestSuite) TestUpgradeFromLatest() {
vm := s.Env().RemoteHost

// install current version
if !s.Run(fmt.Sprintf("install %s", s.AgentPackage.AgentVersion()), func() {
_, err := s.InstallAgent(vm,
windowsAgent.WithPackage(s.AgentPackage),
windowsAgent.WithInstallLogFile(filepath.Join(s.SessionOutputDir(), "install.log")),
windowsAgent.WithValidAPIKey(),
)
s.Require().NoError(err, "Agent should be %s", s.AgentPackage.AgentVersion())
}) {
s.T().FailNow()
}

productVersionPre, err := windowsAgent.GetDatadogProductVersion(vm)
s.Require().NoError(err, "should get product version")

// upgrade to test agent
if !s.Run(fmt.Sprintf("upgrade to %s", s.upgradeAgentPackge.AgentVersion()), func() {
_, err := s.InstallAgent(vm,
windowsAgent.WithPackage(s.upgradeAgentPackge),
windowsAgent.WithInstallLogFile(filepath.Join(s.SessionOutputDir(), "upgrade.log")),
windowsAgent.WithValidAPIKey(),
)
s.Require().NoError(err, "should upgrade to agent %s", s.upgradeAgentPackge.AgentVersion())
}) {
s.T().FailNow()
}

// run tests
testerOptions := []TesterOption{
WithAgentPackage(s.upgradeAgentPackge),
}
t, err := NewTester(s, vm, testerOptions...)
s.Require().NoError(err, "should create tester")
if !t.TestInstallExpectations(s.T()) {
s.T().FailNow()
}

// Get Display Version
productVersionPost, err := windowsAgent.GetDatadogProductVersion(vm)
s.Require().NoError(err, "should get product version")

// check that version is different post upgrade
assert.NotEqual(s.T(), productVersionPre, productVersionPost, "product version should be different after upgrade")

s.uninstallAgentAndRunUninstallTests(t)

}

func TestUpgradeRollback(t *testing.T) {
s := &testUpgradeRollbackSuite{}
run(t, s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,34 @@ internal interface IAgentFlavor
internal class FIPSAgent : IAgentFlavor
{
private readonly AgentVersion _agentVersion;
private readonly string _agentNameSuffix;

public FIPSAgent(AgentVersion agentVersion)
{
_agentVersion = agentVersion;
_agentNameSuffix = Environment.GetEnvironmentVariable("AGENT_PRODUCT_NAME_SUFFIX");
}

public string ProductFullName => "Datadog FIPS Agent";
public Guid UpgradeCode => new("de421174-9615-4fe9-b8a8-2b3f123bdc4f");
public string ProductDescription => $"Datadog FIPS Agent {_agentVersion.PackageVersion}";
public string PackageOutFileName => $"datadog-fips-agent-{_agentVersion.PackageVersion}-1-x86_64";
public string PackageOutFileName => $"datadog-fips-agent-{_agentNameSuffix}{_agentVersion.PackageVersion}-1-x86_64";
}

internal class BaseAgent : IAgentFlavor
{
private readonly AgentVersion _agentVersion;
private readonly string _agentNameSuffix;

public BaseAgent(AgentVersion agentVersion)
{
_agentVersion = agentVersion;
_agentNameSuffix = Environment.GetEnvironmentVariable("AGENT_PRODUCT_NAME_SUFFIX");
}

public string ProductFullName => "Datadog Agent";
public Guid UpgradeCode => new("0c50421b-aefb-4f15-a809-7af256d608a5");
public string ProductDescription => $"Datadog Agent {_agentVersion.PackageVersion}";
public string PackageOutFileName => $"datadog-agent-{_agentVersion.PackageVersion}-1-x86_64";
public string PackageOutFileName => $"datadog-agent-{_agentNameSuffix}{_agentVersion.PackageVersion}-1-x86_64";
}
}
Loading