Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package google-guest-agent for
openSUSE:Factory checked in at 2026-10-23 20:31:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/google-guest-agent (Old)
and /work/SRC/openSUSE:Factory/.google-guest-agent.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "google-guest-agent"
Fri Oct 23 20:31:19 2026 rev:72 rq:1392072 version:20261015.00
Changes:
--------
--- /work/SRC/openSUSE:Factory/google-guest-agent/google-guest-agent.changes
2026-09-22 15:50:40.541891619 +0200
+++
/work/SRC/openSUSE:Factory/.google-guest-agent.new.2252680/google-guest-agent.changes
2026-10-23 20:33:23.332372549 +0200
@@ -1,0 +2,13 @@
+Tue Oct 20 12:33:20 UTC 2026 - Robert Schweikert <[email protected]>
+
+- Ship gce-workload-cert-refresh.timer (bsc#1273192)
+
+-------------------------------------------------------------------
+Fri Oct 16 08:55:41 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 20261015.00
+ * Wait for new account to become visible before adding to groups (#635)
+- Update golang.org/x/crypto to v0.58.0
+- Update golang.org/x/net to v0.61.0 (bsc#1285283, CVE-2026-78669)
+
+-------------------------------------------------------------------
@@ -35 +47,0 @@
-- Ship gce-workload-cert-refresh.timer (bsc#1273192)
Old:
----
guest-agent-20260917.00.tar.gz
New:
----
guest-agent-20261015.00.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ google-guest-agent.spec ++++++
--- /var/tmp/diff_new_pack.dyAXVs/_old 2026-10-23 20:33:24.123405649 +0200
+++ /var/tmp/diff_new_pack.dyAXVs/_new 2026-10-23 20:33:24.125405732 +0200
@@ -1,6 +1,7 @@
#
# spec file for package google-guest-agent
#
+# Copyright (c) 2026 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
@@ -19,7 +20,7 @@
%define shortname guest-agent
Name: google-guest-agent
-Version: 20260917.00
+Version: 20261015.00
Release: 0
Summary: Google Cloud Guest Agent
License: Apache-2.0
@@ -66,6 +67,7 @@
install -p -m 0644 google-startup-scripts.service %{buildroot}%{_unitdir}
install -p -m 0644 google-shutdown-scripts.service %{buildroot}%{_unitdir}
install -p -m 0644 gce-workload-cert-refresh.service %{buildroot}%{_unitdir}
+install -p -m 0644 gce-workload-cert-refresh.timer %{buildroot}%{_unitdir}
mkdir -p %{buildroot}%{_sbindir}
for srv_name in %{buildroot}%{_unitdir}/*.service; do rc_name=$(basename -s
'.service' $srv_name); ln -s service %{buildroot}%{_sbindir}/rc$rc_name; done
++++++ _service ++++++
--- /var/tmp/diff_new_pack.dyAXVs/_old 2026-10-23 20:33:24.162407281 +0200
+++ /var/tmp/diff_new_pack.dyAXVs/_new 2026-10-23 20:33:24.165407406 +0200
@@ -3,8 +3,8 @@
<param
name="url">https://github.com/GoogleCloudPlatform/guest-agent/</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="versionformat">20260917.00</param>
- <param name="revision">20260917.00</param>
+ <param name="versionformat">20261015.00</param>
+ <param name="revision">20261015.00</param>
<param name="changesgenerate">enable</param>
</service>
<service name="recompress" mode="disabled">
@@ -15,8 +15,9 @@
<param name="basename">guest-agent</param>
</service>
<service name="go_modules" mode="disabled">
- <param name="archive">guest-agent-20260917.00.tar.gz</param>
- <param
name="replace">golang.org/x/crypto=golang.org/x/[email protected]</param>
+ <param name="archive">guest-agent-20261015.00.tar.gz</param>
+ <param
name="replace">golang.org/x/crypto=golang.org/x/[email protected]</param>
+ <param name="replace">golang.org/x/net=golang.org/x/[email protected]</param>
</service>
</services>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.dyAXVs/_old 2026-10-23 20:33:24.188408369 +0200
+++ /var/tmp/diff_new_pack.dyAXVs/_new 2026-10-23 20:33:24.192408536 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/GoogleCloudPlatform/guest-agent/</param>
- <param
name="changesrevision">9c6ad8833a3ac64f49b735844b29f5ea1f9357c5</param></service></servicedata>
+ <param
name="changesrevision">778f752c2994d5ab69550941cea901bd43f76be7</param></service></servicedata>
(No newline at EOF)
++++++ guest-agent-20260917.00.tar.gz -> guest-agent-20261015.00.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-agent-20260917.00/google_guest_agent/non_windows_accounts.go
new/guest-agent-20261015.00/google_guest_agent/non_windows_accounts.go
--- old/guest-agent-20260917.00/google_guest_agent/non_windows_accounts.go
2026-09-18 01:05:23.000000000 +0200
+++ new/guest-agent-20261015.00/google_guest_agent/non_windows_accounts.go
2026-09-23 16:43:12.000000000 +0200
@@ -28,6 +28,7 @@
"sort"
"strconv"
"strings"
+ "time"
"github.com/GoogleCloudPlatform/guest-agent/google_guest_agent/cfg"
"github.com/GoogleCloudPlatform/guest-agent/google_guest_agent/run"
@@ -356,6 +357,17 @@
if err := createUser(ctx, user, uid, gid); err != nil {
return err
}
+
+ // The account database (e.g. an NSS cache such as nscd) is not always
+ // consistent with the just-run useradd immediately; on a busy or
+ // just-booted system a lookup for the new user can transiently fail,
+ // which in turn makes the gpasswd calls below fail with "user does not
+ // exist" even though useradd succeeded. Wait for the account to
+ // actually resolve before touching group membership.
+ if err := waitForUserVisible(ctx, user); err != nil {
+ return fmt.Errorf("user %s was created but did not become
visible: %v", user, err)
+ }
+
groups := config.Accounts.Groups
for _, group := range strings.Split(groups, ",") {
addUserToGroup(ctx, user, group)
@@ -363,6 +375,47 @@
return addUserToGroup(ctx, user, "google-sudoers")
}
+// userExistsFunc is a seam for testing waitForUserVisible without touching
+// the real user database.
+var userExistsFunc = userExists
+
+// userVisiblePollInterval and userVisiblePollAttempts bound how long
+// waitForUserVisible will wait for a freshly created account to become
+// visible. Five attempts at 200ms cover the nscd-restart window observed in
+// practice while keeping worst case added boot latency small (~1s).
+var (
+ userVisiblePollInterval = 200 * time.Millisecond
+ userVisiblePollAttempts = 5
+)
+
+// waitForUserVisible polls userExistsFunc until it reports the account
+// exists, up to userVisiblePollAttempts times, sleeping
+// userVisiblePollInterval between attempts. It returns nil as soon as the
+// user is visible, or the last error/state seen if it never becomes visible
+// or ctx is done first.
+func waitForUserVisible(ctx context.Context, user string) error {
+ var lastErr error
+ for attempt := 0; attempt < userVisiblePollAttempts; attempt++ {
+ exists, err := userExistsFunc(user)
+ if exists {
+ return nil
+ }
+ lastErr = err
+ if attempt == userVisiblePollAttempts-1 {
+ break
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(userVisiblePollInterval):
+ }
+ }
+ if lastErr == nil {
+ lastErr = fmt.Errorf("user lookup did not succeed")
+ }
+ return lastErr
+}
+
// removeGoogleUser removes Google managed users. If deprovision_remove is
true, the
// user and its home directory are removed. Otherwise, SSH keys and sudoer
// permissions are removed but the user remains on the system. Group membership
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-agent-20260917.00/google_guest_agent/non_windows_accounts_test.go
new/guest-agent-20261015.00/google_guest_agent/non_windows_accounts_test.go
--- old/guest-agent-20260917.00/google_guest_agent/non_windows_accounts_test.go
1970-01-01 01:00:00.000000000 +0100
+++ new/guest-agent-20261015.00/google_guest_agent/non_windows_accounts_test.go
2026-09-23 16:43:12.000000000 +0200
@@ -0,0 +1,123 @@
+// 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
+
+// https://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
+
+package main
+
+import (
+ "context"
+ "errors"
+ "testing"
+ "time"
+)
+
+// withStubUserExists replaces userExistsFunc for the duration of a test and
+// restores it afterwards.
+func withStubUserExists(t *testing.T, stub func(string) (bool, error)) {
+ t.Helper()
+ orig := userExistsFunc
+ userExistsFunc = stub
+ t.Cleanup(func() { userExistsFunc = orig })
+}
+
+// withFastPolling shrinks the poll interval so tests don't have to wait out
+// the real production backoff, and restores the original values afterwards.
+func withFastPolling(t *testing.T, attempts int) {
+ t.Helper()
+ origInterval, origAttempts := userVisiblePollInterval,
userVisiblePollAttempts
+ userVisiblePollInterval = time.Millisecond
+ userVisiblePollAttempts = attempts
+ t.Cleanup(func() {
+ userVisiblePollInterval = origInterval
+ userVisiblePollAttempts = origAttempts
+ })
+}
+
+func TestWaitForUserVisibleImmediateSuccess(t *testing.T) {
+ calls := 0
+ withStubUserExists(t, func(string) (bool, error) {
+ calls++
+ return true, nil
+ })
+ withFastPolling(t, 5)
+
+ if err := waitForUserVisible(context.Background(), "testuser"); err !=
nil {
+ t.Fatalf("waitForUserVisible() = %v, want nil", err)
+ }
+ if calls != 1 {
+ t.Errorf("userExistsFunc called %d times, want 1 (no retry
needed)", calls)
+ }
+}
+
+func TestWaitForUserVisibleEventualSuccess(t *testing.T) {
+ calls := 0
+ withStubUserExists(t, func(string) (bool, error) {
+ calls++
+ if calls < 3 {
+ // Mirrors the observed nscd race: the account was just
+ // created but a lookup transiently reports it missing.
+ return false, errors.New("user: unknown user testuser")
+ }
+ return true, nil
+ })
+ withFastPolling(t, 5)
+
+ if err := waitForUserVisible(context.Background(), "testuser"); err !=
nil {
+ t.Fatalf("waitForUserVisible() = %v, want nil", err)
+ }
+ if calls != 3 {
+ t.Errorf("userExistsFunc called %d times, want 3", calls)
+ }
+}
+
+func TestWaitForUserVisibleNeverVisible(t *testing.T) {
+ calls := 0
+ wantErr := errors.New("user: unknown user testuser")
+ withStubUserExists(t, func(string) (bool, error) {
+ calls++
+ return false, wantErr
+ })
+ withFastPolling(t, 4)
+
+ err := waitForUserVisible(context.Background(), "testuser")
+ if err == nil {
+ t.Fatal("waitForUserVisible() = nil, want error")
+ }
+ if calls != 4 {
+ t.Errorf("userExistsFunc called %d times, want 4
(userVisiblePollAttempts)", calls)
+ }
+}
+
+func TestWaitForUserVisibleContextCancelled(t *testing.T) {
+ withStubUserExists(t, func(string) (bool, error) {
+ return false, errors.New("not yet")
+ })
+ withFastPolling(t, 5)
+ // Use a real (tiny) interval so the context has something to race
+ // against, otherwise the immediate Done() would be indistinguishable
+ // from a slow stub.
+ userVisiblePollInterval = 50 * time.Millisecond
+
+ ctx, cancel := context.WithCancel(context.Background())
+ go func() {
+ time.Sleep(10 * time.Millisecond)
+ cancel()
+ }()
+
+ err := waitForUserVisible(ctx, "testuser")
+ if !errors.Is(err, context.Canceled) {
+ t.Fatalf("waitForUserVisible() = %v, want context.Canceled",
err)
+ }
+}
++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/google-guest-agent/vendor.tar.gz
/work/SRC/openSUSE:Factory/.google-guest-agent.new.2252680/vendor.tar.gz
differ: char 22, line 1