Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package google-osconfig-agent for
openSUSE:Factory checked in at 2026-11-13 18:32:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/google-osconfig-agent (Old)
and /work/SRC/openSUSE:Factory/.google-osconfig-agent.new.1251 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "google-osconfig-agent"
Fri Nov 13 18:32:13 2026 rev:70 rq:1397094 version:20261105.03
Changes:
--------
---
/work/SRC/openSUSE:Factory/google-osconfig-agent/google-osconfig-agent.changes
2026-11-10 16:30:02.823855961 +0100
+++
/work/SRC/openSUSE:Factory/.google-osconfig-agent.new.1251/google-osconfig-agent.changes
2026-11-13 18:36:19.498823900 +0100
@@ -1,0 +2,11 @@
+Thu Nov 12 08:05:13 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 20261105.03 (bsc#1289973, bsc#1290117)
+ * E2E tests v2 redesign: migrate PackageResource Googet tests (#1073)
+- from version 20261105.01
+ * Fix race between osconfig reboot and Windows TrustedInstaller
+ reboot (#1082)
+- from version 20261105.00
+ * E2E tests v2 redesign: migrate PackageResource Msi tests (#1074)
+
+-------------------------------------------------------------------
Old:
----
osconfig-20261103.02.tar.gz
New:
----
osconfig-20261105.03.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ google-osconfig-agent.spec ++++++
--- /var/tmp/diff_new_pack.vqUvpl/_old 2026-11-13 18:36:22.520951850 +0100
+++ /var/tmp/diff_new_pack.vqUvpl/_new 2026-11-13 18:36:22.522951935 +0100
@@ -19,7 +19,7 @@
%define shortname osconfig
Name: google-osconfig-agent
-Version: 20261103.02
+Version: 20261105.03
Release: 0
Summary: Google Cloud Guest Agent
License: Apache-2.0
++++++ _service ++++++
--- /var/tmp/diff_new_pack.vqUvpl/_old 2026-11-13 18:36:22.570953967 +0100
+++ /var/tmp/diff_new_pack.vqUvpl/_new 2026-11-13 18:36:22.574954137 +0100
@@ -3,8 +3,8 @@
<param name="url">https://github.com/GoogleCloudPlatform/osconfig</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="versionformat">20261103.02</param>
- <param name="revision">20261103.02</param>
+ <param name="versionformat">20261105.03</param>
+ <param name="revision">20261105.03</param>
<param name="changesgenerate">enable</param>
</service>
<service name="recompress" mode="disabled">
@@ -15,7 +15,7 @@
<param name="basename">osconfig</param>
</service>
<service name="go_modules" mode="disabled">
- <param name="archive">osconfig-20261103.02.tar.gz</param>
+ <param name="archive">osconfig-20261105.03.tar.gz</param>
<param
name="replace">github.com/containerd/containerd=github.com/containerd/[email protected]</param>
<param
name="replace">github.com/go-jose/go-jose/v4=github.com/go-jose/go-jose/[email protected]</param>
<param
name="replace">github.com/klauspost/compress=github.com/klauspost/[email protected]</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.vqUvpl/_old 2026-11-13 18:36:22.600955238 +0100
+++ /var/tmp/diff_new_pack.vqUvpl/_new 2026-11-13 18:36:22.603955365 +0100
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/GoogleCloudPlatform/osconfig</param>
- <param
name="changesrevision">edd1aa80c72c57959515158882591548e6eed61c</param></service></servicedata>
+ <param
name="changesrevision">b68b9ac88e9756c74749dd01895f53e77565b9e3</param></service></servicedata>
(No newline at EOF)
++++++ osconfig-20261103.02.tar.gz -> osconfig-20261105.03.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osconfig-20261103.02/agentendpoint/patch_task.go
new/osconfig-20261105.03/agentendpoint/patch_task.go
--- old/osconfig-20261103.02/agentendpoint/patch_task.go 2026-11-03
21:12:42.000000000 +0100
+++ new/osconfig-20261105.03/agentendpoint/patch_task.go 2026-11-05
13:20:03.000000000 +0100
@@ -217,7 +217,7 @@
clog.Warningf(ctx, "Failed to report REBOOTING state: %v", err)
}
- if err := rebootSystem(); err != nil {
+ if err := rebootSystem(ctx); err != nil {
return fmt.Errorf("failed to reboot system: %v", err)
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osconfig-20261103.02/agentendpoint/reboot_linux.go
new/osconfig-20261105.03/agentendpoint/reboot_linux.go
--- old/osconfig-20261103.02/agentendpoint/reboot_linux.go 2026-11-03
21:12:42.000000000 +0100
+++ new/osconfig-20261105.03/agentendpoint/reboot_linux.go 2026-11-05
13:20:03.000000000 +0100
@@ -15,6 +15,7 @@
package agentendpoint
import (
+ "context"
"os/exec"
"syscall"
@@ -27,16 +28,17 @@
shutdown = "/bin/shutdown"
)
-func rebootSystem() error {
+func rebootSystem(ctx context.Context) error {
+ ctx = context.WithoutCancel(ctx)
// Start with systemctl and work down a list of reboot methods.
if e := util.Exists(systemctl); e {
- return exec.Command(systemctl, "reboot").Start()
+ return exec.CommandContext(ctx, systemctl, "reboot").Start()
}
if e := util.Exists(reboot); e {
- return exec.Command(reboot).Run()
+ return exec.CommandContext(ctx, reboot).Run()
}
if e := util.Exists(shutdown); e {
- return exec.Command(shutdown, "-r", "-t", "0").Run()
+ return exec.CommandContext(ctx, shutdown, "-r", "-t", "0").Run()
}
// Fall back to reboot(2) system call
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osconfig-20261103.02/agentendpoint/reboot_windows.go
new/osconfig-20261105.03/agentendpoint/reboot_windows.go
--- old/osconfig-20261103.02/agentendpoint/reboot_windows.go 2026-11-03
21:12:42.000000000 +0100
+++ new/osconfig-20261105.03/agentendpoint/reboot_windows.go 2026-11-05
13:20:03.000000000 +0100
@@ -18,15 +18,57 @@
package agentendpoint
import (
+ "context"
+ "errors"
"os"
"os/exec"
"path/filepath"
+
+ "github.com/GoogleCloudPlatform/osconfig/clog"
+ "golang.org/x/sys/windows"
)
-func rebootSystem() error {
+var runShutdownCmd = func(ctx context.Context, root string) (int, bool, error)
{
+ err := exec.CommandContext(ctx, filepath.Join(root,
`System32\shutdown.exe`), "/r", "/t", "00", "/f", "/d", "p:2:3").Run()
+ var exitErr *exec.ExitError
+ if errors.As(err, &exitErr) {
+ return exitErr.ExitCode(), true, err
+ }
+ return 0, false, err
+}
+
+// isShutdownAlreadyInProgress reports whether a shutdown.exe exit code
+// indicates that a system shutdown or reboot is already scheduled or underway:
+// - ERROR_SHUTDOWN_IN_PROGRESS (1115): A system shutdown is in progress.
+// - ERROR_SHUTDOWN_IS_SCHEDULED (1190): A system shutdown has already been
scheduled.
+// - RPC_S_UNKNOWN_IF (1717): wininit.exe has already unregistered the
InitShutdown
+// RPC interface during an active system shutdown/preshutdown sequence.
+// - STATUS_DLL_INIT_FAILED_LOGOFF (0xC000026B): shutdown.exe failed to
initialize
+// DLLs because the window station is already shutting down.
+func isShutdownAlreadyInProgress(code int) bool {
+ switch uint32(code) {
+ case uint32(windows.ERROR_SHUTDOWN_IN_PROGRESS),
+ uint32(windows.ERROR_SHUTDOWN_IS_SCHEDULED),
+ uint32(windows.RPC_S_UNKNOWN_IF),
+ uint32(windows.STATUS_DLL_INIT_FAILED_LOGOFF):
+ return true
+ default:
+ return false
+ }
+}
+
+func rebootSystem(ctx context.Context) error {
+ ctx = context.WithoutCancel(ctx)
root := os.Getenv("SystemRoot")
if root == "" {
root = `C:\Windows`
}
- return exec.Command(filepath.Join(root, `System32\shutdown.exe`), "/r",
"/t", "00", "/f", "/d", "p:2:3").Run()
+ if code, hasCode, err := runShutdownCmd(ctx, root); err != nil {
+ if hasCode && isShutdownAlreadyInProgress(code) {
+ clog.Warningf(ctx, "System reboot/shutdown is already
in progress (shutdown.exe exit status %d): %v", code, err)
+ return nil
+ }
+ return err
+ }
+ return nil
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/osconfig-20261103.02/agentendpoint/reboot_windows_test.go
new/osconfig-20261105.03/agentendpoint/reboot_windows_test.go
--- old/osconfig-20261103.02/agentendpoint/reboot_windows_test.go
1970-01-01 01:00:00.000000000 +0100
+++ new/osconfig-20261105.03/agentendpoint/reboot_windows_test.go
2026-11-05 13:20:03.000000000 +0100
@@ -0,0 +1,104 @@
+// Copyright 2026 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build windows
+// +build windows
+
+package agentendpoint
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "testing"
+
+ "github.com/GoogleCloudPlatform/osconfig/util/utiltest"
+ "golang.org/x/sys/windows"
+)
+
+func TestRebootSystemWindows(t *testing.T) {
+ ctx := t.Context()
+ dllInitFailedLogoff := uint32(windows.STATUS_DLL_INIT_FAILED_LOGOFF)
+
+ tests := []struct {
+ name string
+ code int
+ hasCode bool
+ cmdErr error
+ wantErr error
+ }{
+ {
+ name: "shutdown succeeds",
+ code: 0,
+ hasCode: false,
+ cmdErr: nil,
+ wantErr: nil,
+ },
+ {
+ name: "ERROR_SHUTDOWN_IN_PROGRESS (1115) treated as
non-fatal",
+ code: int(windows.ERROR_SHUTDOWN_IN_PROGRESS),
+ hasCode: true,
+ cmdErr: fmt.Errorf("exit status %d",
windows.ERROR_SHUTDOWN_IN_PROGRESS),
+ wantErr: nil,
+ },
+ {
+ name: "ERROR_SHUTDOWN_IS_SCHEDULED (1190) treated as
non-fatal",
+ code: int(windows.ERROR_SHUTDOWN_IS_SCHEDULED),
+ hasCode: true,
+ cmdErr: fmt.Errorf("exit status %d",
windows.ERROR_SHUTDOWN_IS_SCHEDULED),
+ wantErr: nil,
+ },
+ {
+ name: "RPC_S_UNKNOWN_IF (1717) treated as non-fatal",
+ code: int(windows.RPC_S_UNKNOWN_IF),
+ hasCode: true,
+ cmdErr: fmt.Errorf("exit status %d",
windows.RPC_S_UNKNOWN_IF),
+ wantErr: nil,
+ },
+ {
+ name: "STATUS_DLL_INIT_FAILED_LOGOFF (0xC000026B)
treated as non-fatal",
+ code: int(dllInitFailedLogoff),
+ hasCode: true,
+ cmdErr: fmt.Errorf("exit status %d",
dllInitFailedLogoff),
+ wantErr: nil,
+ },
+ {
+ name: "unexpected exit code returns error",
+ code: int(windows.ERROR_ACCESS_DENIED),
+ hasCode: true,
+ cmdErr: errors.New("exit status 5"),
+ wantErr: errors.New("exit status 5"),
+ },
+ {
+ name: "command launch error without exit code
returns error",
+ code: 0,
+ hasCode: false,
+ cmdErr: errors.New("executable file not found"),
+ wantErr: errors.New("executable file not found"),
+ },
+ }
+
+ origRunShutdownCmd := runShutdownCmd
+ t.Cleanup(func() { runShutdownCmd = origRunShutdownCmd })
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ runShutdownCmd = func(_ context.Context, _ string)
(int, bool, error) {
+ return tt.code, tt.hasCode, tt.cmdErr
+ }
+ err := rebootSystem(ctx)
+ utiltest.AssertErrorMatch(t, err, tt.wantErr)
+ })
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/osconfig-20261103.02/e2e_tests_v2/ospolicies_package_googet_test.go
new/osconfig-20261105.03/e2e_tests_v2/ospolicies_package_googet_test.go
--- old/osconfig-20261103.02/e2e_tests_v2/ospolicies_package_googet_test.go
1970-01-01 01:00:00.000000000 +0100
+++ new/osconfig-20261105.03/e2e_tests_v2/ospolicies_package_googet_test.go
2026-11-05 13:20:03.000000000 +0100
@@ -0,0 +1,158 @@
+//go:build e2e
+
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package e2etests_test
+
+import (
+ "context"
+ "testing"
+ "time"
+
+ "github.com/GoogleCloudPlatform/osconfig/e2e_tests_v2/internal/gcp"
+ "github.com/GoogleCloudPlatform/osconfig/e2e_tests_v2/internal/testenv"
+ "google.golang.org/api/osconfig/v1"
+)
+
+const ensureGooGetTestStateScript = `$svc = Get-Service google_osconfig_agent
-ErrorAction SilentlyContinue
+if ($svc -and $svc.Status -eq 'Running') {
+ Stop-Service google_osconfig_agent -Force -ErrorAction SilentlyContinue
+}
+
+googet -noconfirm install certgen
+googet -noconfirm remove google-compute-engine-ssh`
+
+type ospoliciesPackageGooGetTestCase struct {
+ name string
+ image string
+ machineType string
+ timeout time.Duration
+}
+
+// osPolicyPackageGooGetTestCases returns the list of test cases for GooGet
package policy tests.
+func osPolicyPackageGooGetTestCases() []ospoliciesPackageGooGetTestCase {
+ return []ospoliciesPackageGooGetTestCase{
+ // Windows Server
+ {
+ name: "windows-2016",
+ image:
"projects/windows-cloud/global/images/family/windows-2016",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ {
+ name: "windows-2019",
+ image:
"projects/windows-cloud/global/images/family/windows-2019",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ {
+ name: "windows-2022",
+ image:
"projects/windows-cloud/global/images/family/windows-2022",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ }
+}
+
+// buildGooGetPackageOSPolicyAssignment constructs the OSPolicyAssignment for
testing GooGet packages.
+// It enforces that "google-compute-engine-ssh" is INSTALLED and "certgen" is
REMOVED on the target VM.
+func buildGooGetPackageOSPolicyAssignment(vmName string)
*osconfig.OSPolicyAssignment {
+ return &osconfig.OSPolicyAssignment{
+ InstanceFilter: &osconfig.OSPolicyAssignmentInstanceFilter{
+ InclusionLabels: []*osconfig.OSPolicyAssignmentLabelSet{
+ {
+ Labels: map[string]string{"name":
vmName},
+ },
+ },
+ },
+ Rollout: &osconfig.OSPolicyAssignmentRollout{
+ DisruptionBudget: &osconfig.FixedOrPercent{Percent:
100},
+ MinWaitDuration: "0s",
+ },
+ OsPolicies: []*osconfig.OSPolicy{
+ {
+ Id: "packageresourcegooget",
+ Mode: "ENFORCEMENT",
+ ResourceGroups:
[]*osconfig.OSPolicyResourceGroup{
+ {
+ Resources:
[]*osconfig.OSPolicyResource{
+ {
+ Id:
"install-package",
+ Pkg:
&osconfig.OSPolicyResourcePackageResource{
+
DesiredState: "INSTALLED",
+ Googet:
&osconfig.OSPolicyResourcePackageResourceGooGet{
+
Name: "google-compute-engine-ssh",
+ },
+ },
+ },
+ {
+ Id:
"remove-package",
+ Pkg:
&osconfig.OSPolicyResourcePackageResource{
+
DesiredState: "REMOVED",
+ Googet:
&osconfig.OSPolicyResourcePackageResourceGooGet{
+
Name: "certgen",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+// TestOSPolicyPackageResourceGooGet verifies that the OS Config agent
enforces GooGet package policies:
+// installing a missing package ("google-compute-engine-ssh") and removing an
installed package ("certgen").
+func TestOSPolicyPackageResourceGooGet(t *testing.T) {
+ const wantCompliances = 1
+ tests := osPolicyPackageGooGetTestCases()
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+
+ test := testenv.New(t, tt.timeout)
+
+ var vm *gcp.VM
+ test.Step("create VM", func(ctx context.Context) error {
+ scriptKey, scriptContent :=
gcp.StartupScript(tt.image, ensureGooGetTestStateScript, "")
+ customMetadata := map[string]string{
+ "osconfig-disabled-features":
"guestpolicies",
+ scriptKey:
scriptContent,
+ }
+ var err error
+ vm, err = test.CreateVM(tt.image,
tt.machineType, customMetadata)
+ return err
+ })
+
+ test.Step("wait for initial package state in
inventory", func(ctx context.Context) error {
+ return test.WaitForPackages(vm,
[]string{"certgen"}, []string{"google-compute-engine-ssh"})
+ })
+
+ test.Step("create os policy assignment", func(ctx
context.Context) error {
+ return test.CreateOSPolicyAssignment(vm,
buildGooGetPackageOSPolicyAssignment(vm.Name))
+ })
+
+ test.Step("wait for os policy compliance report",
func(ctx context.Context) error {
+ return test.WaitForOSPolicyCompliance(vm,
wantCompliances)
+ })
+
+ test.Step("verify packages via inventory", func(ctx
context.Context) error {
+ return test.WaitForPackages(vm,
[]string{"google-compute-engine-ssh"}, []string{"certgen"})
+ })
+ })
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/osconfig-20261103.02/e2e_tests_v2/ospolicies_package_msi_test.go
new/osconfig-20261105.03/e2e_tests_v2/ospolicies_package_msi_test.go
--- old/osconfig-20261103.02/e2e_tests_v2/ospolicies_package_msi_test.go
1970-01-01 01:00:00.000000000 +0100
+++ new/osconfig-20261105.03/e2e_tests_v2/ospolicies_package_msi_test.go
2026-11-05 13:20:03.000000000 +0100
@@ -0,0 +1,168 @@
+//go:build e2e
+
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package e2etests_test
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/GoogleCloudPlatform/osconfig/e2e_tests_v2/internal/gcp"
+ "github.com/GoogleCloudPlatform/osconfig/e2e_tests_v2/internal/testenv"
+ "google.golang.org/api/osconfig/v1"
+)
+
+type ospoliciesPackageMsiTestCase struct {
+ name string
+ image string
+ machineType string
+ timeout time.Duration
+}
+
+// osPolicyPackageMsiTestCases returns the list of test cases for Msi package
policy tests.
+func osPolicyPackageMsiTestCases() []ospoliciesPackageMsiTestCase {
+ return []ospoliciesPackageMsiTestCase{
+ // Windows Server
+ {
+ name: "windows-2016",
+ image:
"projects/windows-cloud/global/images/family/windows-2016",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ {
+ name: "windows-2019",
+ image:
"projects/windows-cloud/global/images/family/windows-2019",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ {
+ name: "windows-2022",
+ image:
"projects/windows-cloud/global/images/family/windows-2022",
+ machineType: "e2-standard-4",
+ timeout: 25 * time.Minute,
+ },
+ }
+}
+
+// buildMsiPackageOSPolicyAssignment constructs the OSPolicyAssignment for
testing MSI packages.
+// It installs Chrome Enterprise MSI from GCS on the target VM.
+func buildMsiPackageOSPolicyAssignment(vmName string)
*osconfig.OSPolicyAssignment {
+ return &osconfig.OSPolicyAssignment{
+ InstanceFilter: &osconfig.OSPolicyAssignmentInstanceFilter{
+ InclusionLabels: []*osconfig.OSPolicyAssignmentLabelSet{
+ {
+ Labels: map[string]string{"name":
vmName},
+ },
+ },
+ },
+ Rollout: &osconfig.OSPolicyAssignmentRollout{
+ DisruptionBudget: &osconfig.FixedOrPercent{Percent:
100},
+ MinWaitDuration: "0s",
+ },
+ OsPolicies: []*osconfig.OSPolicy{
+ {
+ Id: "packageresourcemsi",
+ Mode: "ENFORCEMENT",
+ ResourceGroups:
[]*osconfig.OSPolicyResourceGroup{
+ {
+ Resources:
[]*osconfig.OSPolicyResource{
+ {
+ Id:
"install-package",
+ Pkg:
&osconfig.OSPolicyResourcePackageResource{
+
DesiredState: "INSTALLED",
+ Msi:
&osconfig.OSPolicyResourcePackageResourceMSI{
+
Source: &osconfig.OSPolicyResourceFile{
+
Gcs: &osconfig.OSPolicyResourceFileGcs{
+
Bucket: "osconfig-agent-end2end-test-resources",
+
Object: "OSPolicies/googlechromestandaloneenterprise64.msi",
+
Generation: 1720172515592258,
+
},
+
},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func waitForWindowsApplication(ctx context.Context, test *testenv.Test, vm
*gcp.VM, appName string) error {
+ return gcp.PollUntil(ctx, test.Suite.Config.PollInterval,
fmt.Sprintf("windows application %s on %s", appName, vm.Name), func(ctx
context.Context) (string, bool, error) {
+ inv, err := test.Suite.Compute.GetInventory(ctx, vm.Project,
vm.Zone, vm.Name, "FULL")
+ if err != nil {
+ if gcp.IsNotFound(err) ||
gcp.IsTransientComputeError(err) {
+ return fmt.Sprintf("inventory not yet published
(%v)", err), false, nil
+ }
+ return "", false, fmt.Errorf("failed to read inventory:
%w", err)
+ }
+ for _, item := range inv.Items {
+ if item.InstalledPackage != nil &&
item.InstalledPackage.WindowsApplication != nil {
+ if
strings.Contains(strings.ToLower(item.InstalledPackage.WindowsApplication.DisplayName),
strings.ToLower(appName)) {
+ return fmt.Sprintf("found application
%q", item.InstalledPackage.WindowsApplication.DisplayName), true, nil
+ }
+ }
+ }
+ return fmt.Sprintf("waiting for application %q in inventory",
appName), false, nil
+ })
+}
+
+// TestOSPolicyPackageResourceMsi verifies that the OS Config agent installs
an MSI package
+// (Chrome Enterprise MSI from GCS) on Windows VM instances.
+func TestOSPolicyPackageResourceMsi(t *testing.T) {
+ const wantCompliances = 1
+ tests := osPolicyPackageMsiTestCases()
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+
+ test := testenv.New(t, tt.timeout)
+
+ var vm *gcp.VM
+ test.Step("create VM", func(ctx context.Context) error {
+ customMetadata := map[string]string{
+ "osconfig-disabled-features":
"guestpolicies",
+ }
+ var err error
+ vm, err = test.CreateVM(tt.image,
tt.machineType, customMetadata)
+ return err
+ })
+
+ test.Step("wait for agent inventory", func(ctx
context.Context) error {
+ _, err := test.WaitForInventory(vm)
+ return err
+ })
+
+ test.Step("create os policy assignment", func(ctx
context.Context) error {
+ return test.CreateOSPolicyAssignment(vm,
buildMsiPackageOSPolicyAssignment(vm.Name))
+ })
+
+ test.Step("wait for os policy compliance report",
func(ctx context.Context) error {
+ return test.WaitForOSPolicyCompliance(vm,
wantCompliances)
+ })
+
+ test.Step("verify package installed via inventory",
func(ctx context.Context) error {
+ return waitForWindowsApplication(ctx, test, vm,
"Google Chrome")
+ })
+ })
+ }
+}
++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/google-osconfig-agent/vendor.tar.gz
/work/SRC/openSUSE:Factory/.google-osconfig-agent.new.1251/vendor.tar.gz
differ: char 14, line 1