Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package suseconnect-ng for openSUSE:Factory 
checked in at 2022-08-23 14:25:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/suseconnect-ng (Old)
 and      /work/SRC/openSUSE:Factory/.suseconnect-ng.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "suseconnect-ng"

Tue Aug 23 14:25:55 2022 rev:10 rq:993339 version:0.0.9~git5.75890b6

Changes:
--------
--- /work/SRC/openSUSE:Factory/suseconnect-ng/suseconnect-ng.changes    
2022-04-20 16:54:35.122469221 +0200
+++ /work/SRC/openSUSE:Factory/.suseconnect-ng.new.2083/suseconnect-ng.changes  
2022-08-23 14:26:35.415218665 +0200
@@ -1,0 +2,19 @@
+Fri Aug 05 13:33:05 UTC 2022 - jan.s...@zerebecki.de
+
+- Update to version 0.0.9~git5.75890b6:
+  * Don't run keepalive on reboot
+  * Use system-wide proxy settings (bsc#1200994)
+  * Add customer information about keepalive calls
+  * Add timer for SUSEConnect --keepalive (bsc#1196076)
+  * Add --keepalive to manpage
+  * Added support for the System-Token header
+  * Add Keepalive command line option
+  * Print nested zypper errors (bsc#1200803)
+  * Fix migration json error with SMT (bsc#1198625)
+  * Add option to run local scc tests
+  * Switch to jenkins-hosted credentials
+  * Fix "VCS stamping" problem
+  * Add missing import
+  * Remove redundant code + add comment
+
+-------------------------------------------------------------------

Old:
----
  connect-ng-0.0.8~git2.368ea44.tar.xz

New:
----
  connect-ng-0.0.9~git5.75890b6.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ suseconnect-ng.spec ++++++
--- /var/tmp/diff_new_pack.T8x4Yi/_old  2022-08-23 14:26:36.679221447 +0200
+++ /var/tmp/diff_new_pack.T8x4Yi/_new  2022-08-23 14:26:36.683221455 +0200
@@ -23,7 +23,7 @@
 %global test_hwinfo 0
 
 Name:           suseconnect-ng
-Version:        0.0.8~git2.368ea44
+Version:        0.0.9~git5.75890b6
 Release:        0
 URL:            https://github.com/SUSE/connect-ng
 License:        LGPL-2.1-or-later
@@ -31,7 +31,6 @@
 Group:          System/Management
 Source:         connect-ng-%{version}.tar.xz
 Source1:        %name-rpmlintrc
-BuildRequires:  git
 BuildRequires:  go >= 1.16
 BuildRequires:  golang-packaging
 BuildRequires:  ruby-devel
@@ -106,6 +105,8 @@
 
 %prep
 %setup -q -n connect-ng-%{version}
+# keep git metadata but don't use it for "VCS stamping"
+mv .git .git.bak
 
 %build
 find %_builddir/..
@@ -133,10 +134,62 @@
 install -D -m 644 %_builddir/go/src/%import_path/man/zypper-migration.8 
%buildroot/%_mandir/man8/zypper-migration.8
 install -D -m 644 %_builddir/go/src/%import_path/man/zypper-search-packages.8 
%buildroot/%_mandir/man8/zypper-search-packages.8
 
+# Install the SUSEConnect --keepalive timer and service.
+install -D -m 644 %_builddir/go/src/%import_path/suseconnect-keepalive.timer 
%buildroot/%_unitdir/suseconnect-keepalive.timer
+install -D -m 644 %_builddir/go/src/%import_path/suseconnect-keepalive.service 
%buildroot/%_unitdir/suseconnect-keepalive.service
+ln -sf service %buildroot/%_sbindir/rcsuseconnect-keepalive
+
 find %_builddir/..
 # we currently do not ship the source for any go module
 rm -rf %buildroot/usr/share/go
 
+%pre
+%service_add_pre suseconnect-keepalive.service suseconnect-keepalive.timer
+
+# in pre blocks the old version is still installed. This way we can detect
+# if --keepalive was already present before
+kainfo=0
+helptext=$(SUSEConnect --help)
+if [ $? -eq 0 ]; then
+    echo "$helptext" | grep -q keepalive
+    kainfo=$?
+fi
+
+if [ $kainfo -ne 0 ]; then
+  cat << EOF
+Empowering you with enriched system visibility in the SUSE Customer Center
+
+SUSE is committed to helping provide better insights into the consumption of
+SUSE subscriptions regardless of where they are running; physical or virtual,
+on-prem or in the cloud.
+
+SUSE has been working on several improvements to the SUSE Customer Center 
(SCC),
+RMT, and SUSE Manager to provide a clearer picture of your system landscape:
+
+- SUSE Manager v4.1+ now sends system information to SCC.
+- SCC now captures which products are activated on systems that sit behind RMT
+  or SMT.
+- This update will enable your system to "ping" SCC/RMT daily to
+  confirm the system's active status. This will help you identify or filter out
+  systems in SCC that are no longer running or decommissioned. As always, the
+  choice is yours, you can disable the daily ping by disabling the
+  suseconnect-keepalive systemd timer.
+
+We will continue improving our products to make it easier for you to view and
+manage your subscription consumption. As always, we'd love to hear your 
feedback
+about these improvements and any ideas you might have.
+EOF
+fi
+
+%post
+%service_add_post suseconnect-keepalive.service suseconnect-keepalive.timer
+
+%preun
+%service_del_preun suseconnect-keepalive.service suseconnect-keepalive.timer
+
+%postun
+%service_del_postun suseconnect-keepalive.service suseconnect-keepalive.timer
+
 %check
 %gotest -v %import_path/internal/connect %{?test_hwinfo_args}
 %gotest -v %import_path/suseconnect
@@ -148,9 +201,12 @@
 %_bindir/suseconnect
 %_bindir/SUSEConnect
 %_sbindir/SUSEConnect
+%_sbindir/rcsuseconnect-keepalive
 /usr/lib/zypper/commands
 %_mandir/man8/*
 %_mandir/man5/*
+%_unitdir/suseconnect-keepalive.service
+%_unitdir/suseconnect-keepalive.timer
 
 %files -n libsuseconnect
 %license LICENSE LICENSE.LGPL

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.T8x4Yi/_old  2022-08-23 14:26:36.731221561 +0200
+++ /var/tmp/diff_new_pack.T8x4Yi/_new  2022-08-23 14:26:36.735221570 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/SUSE/connect-ng.git</param>
-              <param 
name="changesrevision">7497adf2078f1d8f9eb51ef90ec61f7bfb46c848</param></service></servicedata>
+              <param 
name="changesrevision">75890b6d6cb41ce623cec1fd77f3c899e2625f88</param></service></servicedata>
 (No newline at EOF)
 

++++++ connect-ng-0.0.8~git2.368ea44.tar.xz -> 
connect-ng-0.0.9~git5.75890b6.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.git/FETCH_HEAD 
new/connect-ng-0.0.9~git5.75890b6/.git/FETCH_HEAD
--- old/connect-ng-0.0.8~git2.368ea44/.git/FETCH_HEAD   2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/FETCH_HEAD   2022-08-03 
09:54:35.000000000 +0200
@@ -1 +1 @@
-368ea44344a170c3bdaf4dba6e69a3ec44de1be1               branch 'main' of 
https://github.com/SUSE/connect-ng
+75890b6d6cb41ce623cec1fd77f3c899e2625f88               branch 'main' of 
https://github.com/SUSE/connect-ng
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.git/ORIG_HEAD 
new/connect-ng-0.0.9~git5.75890b6/.git/ORIG_HEAD
--- old/connect-ng-0.0.8~git2.368ea44/.git/ORIG_HEAD    2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/ORIG_HEAD    2022-08-03 
09:54:35.000000000 +0200
@@ -1 +1 @@
-368ea44344a170c3bdaf4dba6e69a3ec44de1be1
+75890b6d6cb41ce623cec1fd77f3c899e2625f88
Binary files old/connect-ng-0.0.8~git2.368ea44/.git/index and 
new/connect-ng-0.0.9~git5.75890b6/.git/index differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.git/logs/HEAD 
new/connect-ng-0.0.9~git5.75890b6/.git/logs/HEAD
--- old/connect-ng-0.0.8~git2.368ea44/.git/logs/HEAD    2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/logs/HEAD    2022-08-03 
09:54:35.000000000 +0200
@@ -22,3 +22,5 @@
 16545bf627186d6c3e0754ecdcf8aa5e080877fd 
16545bf627186d6c3e0754ecdcf8aa5e080877fd jan_osc <jan_osc@localhost.(none)> 
1649854761 +0200  reset: moving to main
 16545bf627186d6c3e0754ecdcf8aa5e080877fd 
368ea44344a170c3bdaf4dba6e69a3ec44de1be1 jan_osc <jan_osc@localhost.(none)> 
1650442680 +0200  merge origin/main: Fast-forward
 368ea44344a170c3bdaf4dba6e69a3ec44de1be1 
368ea44344a170c3bdaf4dba6e69a3ec44de1be1 jan_osc <jan_osc@localhost.(none)> 
1650442681 +0200  reset: moving to main
+368ea44344a170c3bdaf4dba6e69a3ec44de1be1 
75890b6d6cb41ce623cec1fd77f3c899e2625f88 jan_osc <jan_osc@localhost.(none)> 
1659706384 +0200  merge origin/main: Fast-forward
+75890b6d6cb41ce623cec1fd77f3c899e2625f88 
75890b6d6cb41ce623cec1fd77f3c899e2625f88 jan_osc <jan_osc@localhost.(none)> 
1659706384 +0200  reset: moving to main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/.git/logs/refs/heads/main 
new/connect-ng-0.0.9~git5.75890b6/.git/logs/refs/heads/main
--- old/connect-ng-0.0.8~git2.368ea44/.git/logs/refs/heads/main 2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/logs/refs/heads/main 2022-08-03 
09:54:35.000000000 +0200
@@ -13,3 +13,4 @@
 33e58472fd2f39bc963859cbe5892fb47fd6b9b6 
3ef988ed2feed23430e8f0d3f58d2a45301932a7 jan_osc <jan_osc@localhost.(none)> 
1648123790 +0100  merge origin/main: Fast-forward
 3ef988ed2feed23430e8f0d3f58d2a45301932a7 
16545bf627186d6c3e0754ecdcf8aa5e080877fd jan_osc <jan_osc@localhost.(none)> 
1649854761 +0200  merge origin/main: Fast-forward
 16545bf627186d6c3e0754ecdcf8aa5e080877fd 
368ea44344a170c3bdaf4dba6e69a3ec44de1be1 jan_osc <jan_osc@localhost.(none)> 
1650442680 +0200  merge origin/main: Fast-forward
+368ea44344a170c3bdaf4dba6e69a3ec44de1be1 
75890b6d6cb41ce623cec1fd77f3c899e2625f88 jan_osc <jan_osc@localhost.(none)> 
1659706384 +0200  merge origin/main: Fast-forward
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/.git/logs/refs/remotes/origin/main 
new/connect-ng-0.0.9~git5.75890b6/.git/logs/refs/remotes/origin/main
--- old/connect-ng-0.0.8~git2.368ea44/.git/logs/refs/remotes/origin/main        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/logs/refs/remotes/origin/main        
2022-08-03 09:54:35.000000000 +0200
@@ -12,3 +12,4 @@
 33e58472fd2f39bc963859cbe5892fb47fd6b9b6 
3ef988ed2feed23430e8f0d3f58d2a45301932a7 jan_osc <jan_osc@localhost.(none)> 
1648123789 +0100  fetch --tags: fast-forward
 3ef988ed2feed23430e8f0d3f58d2a45301932a7 
16545bf627186d6c3e0754ecdcf8aa5e080877fd jan_osc <jan_osc@localhost.(none)> 
1649854760 +0200  fetch --tags: fast-forward
 16545bf627186d6c3e0754ecdcf8aa5e080877fd 
368ea44344a170c3bdaf4dba6e69a3ec44de1be1 jan_osc <jan_osc@localhost.(none)> 
1650442680 +0200  fetch --tags: fast-forward
+368ea44344a170c3bdaf4dba6e69a3ec44de1be1 
75890b6d6cb41ce623cec1fd77f3c899e2625f88 jan_osc <jan_osc@localhost.(none)> 
1659706384 +0200  fetch --tags: fast-forward
Binary files 
old/connect-ng-0.0.8~git2.368ea44/.git/objects/pack/pack-8df2cb00d9ea6c83d0c9f29bcf2330ec25f66fcd.idx
 and 
new/connect-ng-0.0.9~git5.75890b6/.git/objects/pack/pack-8df2cb00d9ea6c83d0c9f29bcf2330ec25f66fcd.idx
 differ
Binary files 
old/connect-ng-0.0.8~git2.368ea44/.git/objects/pack/pack-8df2cb00d9ea6c83d0c9f29bcf2330ec25f66fcd.pack
 and 
new/connect-ng-0.0.9~git5.75890b6/.git/objects/pack/pack-8df2cb00d9ea6c83d0c9f29bcf2330ec25f66fcd.pack
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.git/refs/heads/main 
new/connect-ng-0.0.9~git5.75890b6/.git/refs/heads/main
--- old/connect-ng-0.0.8~git2.368ea44/.git/refs/heads/main      2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/refs/heads/main      2022-08-03 
09:54:35.000000000 +0200
@@ -1 +1 @@
-368ea44344a170c3bdaf4dba6e69a3ec44de1be1
+75890b6d6cb41ce623cec1fd77f3c899e2625f88
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/.git/refs/remotes/origin/main 
new/connect-ng-0.0.9~git5.75890b6/.git/refs/remotes/origin/main
--- old/connect-ng-0.0.8~git2.368ea44/.git/refs/remotes/origin/main     
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.git/refs/remotes/origin/main     
2022-08-03 09:54:35.000000000 +0200
@@ -1 +1 @@
-368ea44344a170c3bdaf4dba6e69a3ec44de1be1
+75890b6d6cb41ce623cec1fd77f3c899e2625f88
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.git/refs/tags/v0.0.9 
new/connect-ng-0.0.9~git5.75890b6/.git/refs/tags/v0.0.9
--- old/connect-ng-0.0.8~git2.368ea44/.git/refs/tags/v0.0.9     1970-01-01 
01:00:00.000000000 +0100
+++ new/connect-ng-0.0.9~git5.75890b6/.git/refs/tags/v0.0.9     2022-08-03 
09:54:35.000000000 +0200
@@ -0,0 +1 @@
+b360d2479a596ab48d5614ee7457efd8dcf6d67b
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/.gitignore 
new/connect-ng-0.0.9~git5.75890b6/.gitignore
--- old/connect-ng-0.0.8~git2.368ea44/.gitignore        2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/.gitignore        2022-08-03 
09:54:35.000000000 +0200
@@ -1,2 +1,3 @@
 out
 internal/connect/version.txt
+connect-ruby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/Makefile 
new/connect-ng-0.0.9~git5.75890b6/Makefile
--- old/connect-ng-0.0.8~git2.368ea44/Makefile  2022-04-20 10:16:43.000000000 
+0200
+++ new/connect-ng-0.0.9~git5.75890b6/Makefile  2022-08-03 09:54:35.000000000 
+0200
@@ -20,6 +20,13 @@
 test-yast: build-so
        docker build -t go-connect-test-yast -f Dockerfile.yast . && docker run 
-t go-connect-test-yast
 
+test-scc: connect-ruby
+       docker build -t connect.ng-sle15sp3 -f 
integration/Dockerfile.ng-sle15sp3 .
+       docker run --privileged --rm -t connect.ng-sle15sp3 ./integration/run.sh
+
+connect-ruby:
+       git clone https://github.com/SUSE/connect connect-ruby
+
 gofmt:
        @if [ ! -z "$$(gofmt -l ./)" ]; then echo "Formatting errors..."; gofmt 
-d ./; exit 1; fi
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/integration/Dockerfile.ng-sle15sp3 
new/connect-ng-0.0.9~git5.75890b6/integration/Dockerfile.ng-sle15sp3
--- old/connect-ng-0.0.8~git2.368ea44/integration/Dockerfile.ng-sle15sp3        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/integration/Dockerfile.ng-sle15sp3        
2022-08-03 09:54:35.000000000 +0200
@@ -3,8 +3,6 @@
 ENV PRODUCT SLE_15_SP3
 ENV BUILT_AT "Tue Jul 13 15:32 CET 2021"
 
-RUN useradd --no-log-init --create-home scc
-
 # Remember to drop docker caches if any of these change
 RUN zypper ar 
http://download.suse.de/ibs/SUSE/Products/SLE-Module-Basesystem/15-SP3/x86_64/product
 base &&\
     zypper ar 
http://download.suse.de/ibs/SUSE/Updates/SLE-Module-Basesystem/15-SP3/x86_64/update
 base-updates &&\
@@ -20,8 +18,8 @@
       vim osc hwinfo libx86emu3 zypper-migration-plugin sudo awk curl \
       obs-service-tar_scm obs-service-recompress obs-service-extract_file 
obs-service-set_version obs-service-format_spec_file
 
-RUN wget http://username:passw...@gaffer.suse.de:9999/files/.regcode -O 
~/.regcode
-RUN wget http://username:passw...@gaffer.suse.de:9999/files/.oscrc -O ~/.oscrc
+RUN wget --no-check-certificate 
https://ci.suse.de/job/scc-connect-ng-config/lastBuild/artifact/.regcodes -O 
~/.regcodes
+RUN wget --no-check-certificate 
https://ci.suse.de/job/scc-connect-ng-config/lastBuild/artifact/.oscrc -O 
~/.oscrc
 
 RUN echo 'gem: --no-ri --no-rdoc' > /etc/gemrc && \
     gem install bundler --no-document
@@ -35,10 +33,8 @@
 RUN bundle config jobs $(nproc) && \
     bundle install
 ADD connect-ruby/. /tmp/connect
-RUN chown -R scc /tmp/connect
 
 
 RUN mkdir /tmp/connect-ng
 WORKDIR /tmp/connect-ng
 ADD . /tmp/connect-ng
-RUN chown -R scc /tmp/connect-ng
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/integration/run.sh 
new/connect-ng-0.0.9~git5.75890b6/integration/run.sh
--- old/connect-ng-0.0.8~git2.368ea44/integration/run.sh        2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/integration/run.sh        2022-08-03 
09:54:35.000000000 +0200
@@ -13,7 +13,7 @@
 head=$(git rev-list -n1 HEAD)
 mkdir osc-package
 cd osc-package
-osc co -o . 'systemsmanagement:SCC/suseconnect-ng'
+osc -A https://api.opensuse.org co -o . 'systemsmanagement:SCC/suseconnect-ng'
 cp ../_service ./
 sed -i "s|https://github.com/SUSE/connect-ng.git|file://$remote|g" _service
 sed -i "s|main|$head|g" _service
@@ -37,4 +37,8 @@
 rm bin/SUSEConnect
 # the tests match the exact version defined in the ruby code, replace it with 
ours
 sed -i "s|VERSION = '[^']*'|VERSION = '$shortversion'|g" 
lib/suse/connect/version.rb
+# load test regcodes into env vars
+set -a
+. ~/.regcodes
+set +a
 cucumber
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/api.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/api.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/api.go   2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/api.go   2022-08-03 
09:54:35.000000000 +0200
@@ -14,13 +14,13 @@
                return "", "", err
        }
        var creds struct {
-               Login     string `json:"login"`
-               Passoword string `json:"password"`
+               Login    string `json:"login"`
+               Password string `json:"password"`
        }
        if err = json.Unmarshal(resp, &creds); err != nil {
                return "", "", JSONError{err}
        }
-       return creds.Login, creds.Passoword, nil
+       return creds.Login, creds.Password, nil
 }
 
 func upToDate() bool {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/api_test.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/api_test.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/api_test.go      
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/api_test.go      
2022-08-03 09:54:35.000000000 +0200
@@ -8,8 +8,11 @@
 )
 
 func TestAnnounceSystem(t *testing.T) {
+       createTestCredentials("", "", t)
+
        ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r 
*http.Request) {
                w.Header().Set("Content-Type", "application/json")
+               w.Header().Set("System-Token", "token")
                io.WriteString(w, 
`{"login":"test-user","password":"test-password"}`)
        }))
        defer ts.Close()
@@ -25,6 +28,15 @@
        if password != "test-password" {
                t.Errorf("Expected password: \"test-password\", got: \"%s\"", 
password)
        }
+
+       // System token should have been updated.
+       creds, err := getCredentials()
+       if err != nil {
+               t.Fatalf("Unexpected error: %s", err)
+       }
+       if creds.SystemToken != "token" {
+               t.Fatalf("Unexpected token '%v', should have been 'token'", 
creds.SystemToken)
+       }
 }
 
 func TestGetActivations(t *testing.T) {
@@ -267,3 +279,25 @@
                t.Fatalf("len(migrations) == %d, expected 2", len(migrations))
        }
 }
+
+func TestProductMigrationsSMT(t *testing.T) {
+       createTestCredentials("", "", t)
+       ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r 
*http.Request) {
+               w.Write(readTestFile("migrations-smt.json", t))
+       }))
+       defer ts.Close()
+       CFG.BaseURL = ts.URL
+
+       migrations, err := productMigrations(nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(migrations) != 1 {
+               t.Fatalf("len(migrations) == %d, expected 1", len(migrations))
+       }
+       gotID := migrations[0][0].ID
+       expectedID := 101361
+       if gotID != expectedID {
+               t.Fatalf("Got ID: %d, expected: %d", gotID, expectedID)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/client.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/client.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/client.go        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/client.go        
2022-08-03 09:54:35.000000000 +0200
@@ -200,6 +200,18 @@
        return updateSystem(sysInfoBody)
 }
 
+// SendKeepAlivePing updates the system information on the server
+func SendKeepAlivePing() error {
+       if !IsRegistered() {
+               return ErrPingFromUnregistered
+       }
+       err := UpdateSystem("", "")
+       if err == nil {
+               Info.Print(bold(greenText("\nSuccessfully updated system")))
+       }
+       return err
+}
+
 // announceOrUpdate Announces the system to the server, receiving and storing 
its
 // credentials. When already announced, sends the current hardware details to 
the server
 func announceOrUpdate() error {
@@ -215,7 +227,7 @@
        if err != nil {
                return err
        }
-       return writeSystemCredentials(login, password)
+       return writeSystemCredentials(login, password, "")
 }
 
 // IsRegistered returns true if there is a valid credentials file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/connection.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/connection.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/connection.go    
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/connection.go    
2022-08-03 09:54:35.000000000 +0200
@@ -8,6 +8,7 @@
        "net/http"
        "net/http/httputil"
        "net/url"
+       "strings"
        "time"
 )
 
@@ -52,6 +53,14 @@
        }
        // REVISIT "Accept-Encoding" - disable gzip commpression on debug?
        req.Header.Add("User-Agent", appName+"/"+GetShortenedVersion())
+
+       // Pass the current system token.
+       creds, err := getCredentials()
+       token := ""
+       if err == nil {
+               token = creds.SystemToken
+       }
+       req.Header.Add("System-Token", token)
 }
 
 func addAuthHeader(req *http.Request, auth authType) error {
@@ -97,13 +106,6 @@
 
 func callHTTP(verb, path string, body []byte, query map[string]string, auth 
authType) ([]byte, error) {
        setupHTTPClient()
-       if httpclient == nil {
-               // use defaults from DefaultTransport
-               tr := http.DefaultTransport.(*http.Transport).Clone()
-               tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: 
CFG.Insecure}
-               tr.Proxy = proxyWithAuth
-               httpclient = &http.Client{Transport: tr, Timeout: 60 * 
time.Second}
-       }
        req, err := http.NewRequest(verb, CFG.BaseURL, bytes.NewReader(body))
        if err != nil {
                return nil, err
@@ -132,6 +134,13 @@
        }
        defer resp.Body.Close()
 
+       // For each request SCC might update the System token for a given 
system.
+       // This will be given through the `System-Token` header, so we have to 
grab
+       // this here and store it for the next request.
+       if err := handleSystemToken(resp.Header.Get("System-Token")); err != 
nil {
+               Debug.Printf("system-token: %s\n", err)
+       }
+
        if isLoggerEnabled(Debug) {
                respBlob, _ := httputil.DumpResponse(resp, true)
                Debug.Printf("%s\n", respBlob)
@@ -148,6 +157,24 @@
        return resBody, nil
 }
 
+// handleSystemToken stores the given token into the system credentials file
+// unless it's blank.
+func handleSystemToken(token string) error {
+       token = strings.TrimSpace(token)
+       if token == "" {
+               return nil
+       }
+
+       creds, err := getCredentials()
+       if err != nil {
+               return err
+       }
+
+       creds.SystemToken = token
+       return creds.write()
+}
+
+// ReloadCertPool triggers reload of internals CA cert pool
 func ReloadCertPool() error {
        // TODO: update when https://github.com/golang/go/issues/41888 is fixed
        httpclient = nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/credentials.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/credentials.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/credentials.go   
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/credentials.go   
2022-08-03 09:54:35.000000000 +0200
@@ -17,21 +17,23 @@
 )
 
 var (
-       userMatch   = regexp.MustCompile(`(?m)^\s*username\s*=\s*(\S+)\s*$`)
-       passMatch   = regexp.MustCompile(`(?m)^\s*password\s*=\s*(\S+)\s*$`)
-       curlrcMatch = regexp.MustCompile(`^\s*-*proxy-user[ =]*"(.+):(.+)"\s*$`)
+       userMatch        = 
regexp.MustCompile(`(?m)^\s*username\s*=\s*(\S+)\s*$`)
+       passMatch        = 
regexp.MustCompile(`(?m)^\s*password\s*=\s*(\S+)\s*$`)
+       systemTokenMatch = 
regexp.MustCompile(`(?m)^\s*system_token\s*=\s*(\S+)\s*$`)
+       curlrcMatch      = regexp.MustCompile(`^\s*-*proxy-user[ 
=]*"(.+):(.+)"\s*$`)
 )
 
 // Credentials stores the SCC or service credentials
 type Credentials struct {
-       Filename string `json:"file"`
-       Username string `json:"username"`
-       Password string `json:"password"`
+       Filename    string `json:"file"`
+       Username    string `json:"username"`
+       Password    string `json:"password"`
+       SystemToken string `json:"system_token"`
 }
 
 func (c Credentials) String() string {
-       return fmt.Sprintf("file: %s, username: %s, password: REDACTED",
-               c.Filename, c.Username)
+       return fmt.Sprintf("file: %s, username: %s, password: REDACTED, 
system_token: %s",
+               c.Filename, c.Username, c.SystemToken)
 }
 
 func systemCredentialsFile() string {
@@ -83,10 +85,16 @@
        }
        uMatch := userMatch.FindStringSubmatch(string(content))
        pMatch := passMatch.FindStringSubmatch(string(content))
+       tMatch := systemTokenMatch.FindStringSubmatch(string(content))
        if len(uMatch) != 2 || len(pMatch) != 2 {
                return Credentials{}, ErrMalformedSccCredFile
        }
-       return Credentials{Username: uMatch[1], Password: pMatch[1]}, nil
+       token := ""
+       if len(tMatch) == 2 {
+               token = tMatch[1]
+       }
+
+       return Credentials{Username: uMatch[1], Password: pMatch[1], 
SystemToken: token}, nil
 }
 
 func (c Credentials) write() error {
@@ -103,23 +111,24 @@
                }
        }
        buf := bytes.Buffer{}
-       fmt.Fprintf(&buf, "username=%s\npassword=%s\n", c.Username, c.Password)
+       fmt.Fprintf(&buf, "username=%s\npassword=%s\nsystem_token=%s\n", 
c.Username, c.Password, c.SystemToken)
        return os.WriteFile(path, buf.Bytes(), 0600)
 }
 
 // CreateCredentials writes credentials to path
-func CreateCredentials(login, password, path string) error {
+func CreateCredentials(login, password, systemToken, path string) error {
        c := Credentials{
-               Filename: path,
-               Username: login,
-               Password: password,
+               Filename:    path,
+               Username:    login,
+               Password:    password,
+               SystemToken: systemToken,
        }
        return c.write()
 }
 
-func writeSystemCredentials(login, password string) error {
+func writeSystemCredentials(login, password, systemToken string) error {
        path := systemCredentialsFile()
-       return CreateCredentials(login, password, path)
+       return CreateCredentials(login, password, systemToken, path)
 }
 
 func writeServiceCredentials(serviceName string) error {
@@ -128,7 +137,7 @@
                return err
        }
        path := serviceCredentialsFile(serviceName)
-       return CreateCredentials(c.Username, c.Password, path)
+       return CreateCredentials(c.Username, c.Password, c.SystemToken, path)
 }
 
 func removeSystemCredentials() error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/credentials_test.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/credentials_test.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/credentials_test.go      
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/credentials_test.go      
2022-08-03 09:54:35.000000000 +0200
@@ -12,9 +12,9 @@
                expectCreds Credentials
                expectErr   error
        }{
-               {"username=user1\npassword=pass1", Credentials{"", "user1", 
"pass1"}, nil},
-               {" \n username = user1 \n password = pass1 \n", Credentials{"", 
"user1", "pass1"}, nil},
-               {"username = user1 \n junk \n password = pass1 \n", 
Credentials{"", "user1", "pass1"}, nil},
+               {"username=user1\npassword=pass1", Credentials{"", "user1", 
"pass1", ""}, nil},
+               {" \n username = user1 \n password = pass1 \nsystem_token=\n", 
Credentials{"", "user1", "pass1", ""}, nil},
+               {"username = user1 \n junk \n password = pass1 
\nsystem_token=1234", Credentials{"", "user1", "pass1", "1234"}, nil},
                {"USERNAME = user1 \n passed = pass1", Credentials{}, 
ErrMalformedSccCredFile},
                {"username= \n password = \n", Credentials{}, 
ErrMalformedSccCredFile},
        }
@@ -33,14 +33,14 @@
        if err != ErrMissingCredentialsFile {
                t.Fatalf("Expected [%s], got [%s]", ErrMissingCredentialsFile, 
err)
        }
-       if err := writeSystemCredentials("user1", "pass1"); err != nil {
+       if err := writeSystemCredentials("user1", "pass1", "1234"); err != nil {
                t.Fatalf("Unexpected error: %s", err)
        }
        c, err := getCredentials()
        if err != nil {
                t.Fatalf("Unexpected error: %s", err)
        }
-       if c.Username != "user1" || c.Password != "pass1" {
+       if c.Username != "user1" || c.Password != "pass1" || c.SystemToken != 
"1234" {
                t.Errorf("Unexpected user1 and pass1. Got: %s and %s",
                        c.Username, c.Password)
        }
@@ -55,10 +55,10 @@
 
 func TestWriteCredentials(t *testing.T) {
        CFG.FsRoot = t.TempDir()
-       if err := writeSystemCredentials("user1", "pass1"); err != nil {
+       if err := writeSystemCredentials("user1", "pass1", "1234"); err != nil {
                t.Fatalf("Unexpected error: %s", err)
        }
-       expected := "username=user1\npassword=pass1\n"
+       expected := "username=user1\npassword=pass1\nsystem_token=1234\n"
        contents, _ := os.ReadFile(systemCredentialsFile())
        got := string(contents)
        if got != expected {
@@ -68,7 +68,7 @@
 
 func TestWriteReadDeleteService(t *testing.T) {
        CFG.FsRoot = t.TempDir()
-       if err := writeSystemCredentials("user1", "pass1"); err != nil {
+       if err := writeSystemCredentials("user1", "pass1", "1234"); err != nil {
                t.Fatalf("Unexpected error: %s", err)
        }
        if err := writeServiceCredentials("service1"); err != nil {
@@ -79,7 +79,7 @@
        if err != nil {
                t.Fatalf("Unexpected error: %s", err)
        }
-       if rc.Username != "user1" || rc.Password != "pass1" {
+       if rc.Username != "user1" || rc.Password != "pass1" || rc.SystemToken 
!= "1234" {
                t.Errorf("Got: %s and %s, expected user1 and pass1", 
rc.Username, rc.Password)
        }
        if err := removeServiceCredentials("service1"); err != nil {
@@ -96,10 +96,10 @@
                expectCreds Credentials
                expectErr   error
        }{
-               {"--proxy-user \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%"}, nil},
-               {"--proxy-user = \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%"}, nil},
-               {"proxy-user = \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%"}, nil},
-               {"proxy-user=\"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%"}, nil},
+               {"--proxy-user \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%", ""}, nil},
+               {"--proxy-user = \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%", ""}, nil},
+               {"proxy-user = \"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%", ""}, nil},
+               {"proxy-user=\"meuser1$:mepassord2%\"", Credentials{"", 
"meuser1$", "mepassord2%", ""}, nil},
                {"", Credentials{}, ErrNoProxyCredentials},
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/errors.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/errors.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/errors.go        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/errors.go        
2022-08-03 09:54:35.000000000 +0200
@@ -11,6 +11,7 @@
        ErrMalformedSccCredFile       = errors.New("Cannot parse credentials 
file")
        ErrMissingCredentialsFile     = errors.New("Credentials file is 
missing")
        ErrSystemNotRegistered        = errors.New("System not registered")
+       ErrPingFromUnregistered       = errors.New("Keepalive ping not allowed 
from unregistered system.")
        ErrBaseProductDeactivation    = errors.New("Unable to deactivate base 
product")
        ErrCannotDetectBaseProduct    = errors.New("Unable to detect base 
product")
        ErrListExtensionsUnregistered = errors.New("System not registered")
@@ -36,11 +37,12 @@
        Commmand []string
        ExitCode int
        Output   []byte
+       Err      error
 }
 
 func (ze ZypperError) Error() string {
-       return fmt.Sprintf("command '%s' failed\nError: zypper returned %d with 
'%s'",
-               strings.Join(ze.Commmand, " "), ze.ExitCode, ze.Output)
+       return fmt.Sprintf("command '%s' failed\nError: zypper returned %d with 
'%s' (%s)",
+               strings.Join(ze.Commmand, " "), ze.ExitCode, ze.Output, ze.Err)
 }
 
 // APIError is returned on failed HTTP requests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/helpers_test.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/helpers_test.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/helpers_test.go  
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/helpers_test.go  
2022-08-03 09:54:35.000000000 +0200
@@ -24,7 +24,7 @@
                password = "test"
        }
        CFG.FsRoot = t.TempDir()
-       err := writeSystemCredentials(username, password)
+       err := writeSystemCredentials(username, password, "")
        if err != nil {
                t.Fatal(err)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/product.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/product.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/product.go       
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/product.go       
2022-08-03 09:54:35.000000000 +0200
@@ -26,7 +26,7 @@
        Extensions []Product `json:"extensions,omitempty"`
 
        // these are used by YaST
-       ID           int    `json:"id"`
+       ID           int    `json:"-"` // handled by custom 
unmarshaller/marshaller
        Description  string `xml:"description" json:"description,omitempty"`
        EULAURL      string `json:"eula_url,omitempty"`
        FormerName   string `json:"former_identifier,omitempty"`
@@ -38,10 +38,11 @@
 }
 
 // UnmarshalJSON custom unmarshaller for Product.
-// Only SMT/RMT send the "available" field in their JSON responses.
-// SCC does not, and the default Unmarshal() sets Available to the
-// boolean zero-value which is false. This sets it to true instead.
+// Special decoding is needed for the Available, IsBase and ID fields.
 func (p *Product) UnmarshalJSON(data []byte) error {
+       // Only SMT/RMT send the "available" field in their JSON responses.
+       // SCC does not, and the default Unmarshal() sets Available to the
+       // boolean zero-value which is false. This sets it to true instead.
        type product Product
        prod := product{
                Available: true,
@@ -49,6 +50,7 @@
        if err := json.Unmarshal(data, &prod); err != nil {
                return err
        }
+
        // migration paths contain is-base information as "base" attribute
        // while we default to "isbase" for YaST integration.
        // the rest of the SCC API uses `product_type="base"` instead.
@@ -59,10 +61,50 @@
                return err
        }
        prod.IsBase = prod.IsBase || mProd.Base || prod.ProductType == "base"
+
+       // SCC and RMT servers send the ID field as an int. But SMT sends it
+       // as a string in the POST migrations call. This helper tries both.
+       prod.ID = findID(data)
+
        *p = Product(prod)
        return nil
 }
 
+// findID decodes the "id" field from data
+func findID(data []byte) int {
+       // Try to decode as an int first. SCC/RMT case.
+       idInt := struct {
+               ID int `json:"id"`
+       }{}
+       if err := json.Unmarshal(data, &idInt); err == nil {
+               return idInt.ID
+       }
+
+       // Decoding id as an int failed. Try to decode as a string. SMT case.
+       idStr := struct {
+               ID int `json:"id,string"`
+       }{}
+       if err := json.Unmarshal(data, &idStr); err == nil {
+               return idStr.ID
+       }
+
+       return 0
+}
+
+// MarshalJSON is a custom JSON marshaller that includes the "id" field.
+// This method is needed because the `json:"id"` tag can not be used
+// on Product.ID because the that field requires a custom unmarshaller.
+func (p *Product) MarshalJSON() ([]byte, error) {
+       type prodAlias Product
+       return json.Marshal(&struct {
+               ID int `json:"id"`
+               *prodAlias
+       }{
+               ID:        p.ID,
+               prodAlias: (*prodAlias)(p),
+       })
+}
+
 // Edition returns VERSION[-RELEASE] for product
 func (p Product) Edition() string {
        if p.Release == "" {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/product_test.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/product_test.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/product_test.go  
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/product_test.go  
2022-08-03 09:54:35.000000000 +0200
@@ -129,3 +129,45 @@
                t.Fatal("Expected error, got nil")
        }
 }
+
+func TestFindIDInt(t *testing.T) {
+       jsn := `{"id": 101361}`
+       var p Product
+       err := json.Unmarshal([]byte(jsn), &p)
+       if err != nil {
+               t.Fatalf("Error: %v", err)
+       }
+       if p.ID != 101361 {
+               t.Errorf("Expected: %d, got: %d", 101361, p.ID)
+       }
+}
+
+func TestFindIDString(t *testing.T) {
+       jsn := `{"id": "101361"}`
+       var p Product
+       err := json.Unmarshal([]byte(jsn), &p)
+       if err != nil {
+               t.Fatalf("Error: %v", err)
+       }
+       if p.ID != 101361 {
+               t.Errorf("Expected: %d, got: %d", 101361, p.ID)
+       }
+}
+
+func TestMarshallProductIntID(t *testing.T) {
+       p1 := Product{ID: 42}
+       jsn, err := json.Marshal(&p1)
+       if err != nil {
+               t.Fatalf("Error: %v", err)
+       }
+
+       p2 := Product{}
+       err = json.Unmarshal([]byte(jsn), &p2)
+       if err != nil {
+               t.Fatalf("Error: %v", err)
+       }
+
+       if p1.ID != p2.ID {
+               t.Errorf("Expected: %d, got: %d", p1.ID, p2.ID)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/internal/connect/zypper.go 
new/connect-ng-0.0.9~git5.75890b6/internal/connect/zypper.go
--- old/connect-ng-0.0.8~git2.368ea44/internal/connect/zypper.go        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/internal/connect/zypper.go        
2022-08-03 09:54:35.000000000 +0200
@@ -47,7 +47,7 @@
        output, err := execute(cmd, validExitCodes)
        if err != nil {
                if ee, ok := err.(ExecuteError); ok {
-                       return nil, ZypperError{Commmand: ee.Commmand, 
ExitCode: ee.ExitCode, Output: ee.Output}
+                       return nil, ZypperError(ee)
                }
        }
        return output, nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/libsuseconnect/libsuseconnect.go 
new/connect-ng-0.0.9~git5.75890b6/libsuseconnect/libsuseconnect.go
--- old/connect-ng-0.0.8~git2.368ea44/libsuseconnect/libsuseconnect.go  
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/libsuseconnect/libsuseconnect.go  
2022-08-03 09:54:35.000000000 +0200
@@ -68,7 +68,7 @@
        var res struct {
                Credentials []string `json:"credentials"`
        }
-       res.Credentials = []string{login, password}
+       res.Credentials = []string{login, password, ""}
        jsn, _ := json.Marshal(&res)
        return C.CString(string(jsn))
 }
@@ -95,9 +95,9 @@
 }
 
 //export create_credentials_file
-func create_credentials_file(login, password, path *C.char) *C.char {
+func create_credentials_file(login, password, token, path *C.char) *C.char {
        err := connect.CreateCredentials(
-               C.GoString(login), C.GoString(password), C.GoString(path))
+               C.GoString(login), C.GoString(password), C.GoString(token), 
C.GoString(path))
        if err != nil {
                return C.CString(errorToJSON(err))
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/man/SUSEConnect.8 
new/connect-ng-0.0.9~git5.75890b6/man/SUSEConnect.8
--- old/connect-ng-0.0.8~git2.368ea44/man/SUSEConnect.8 2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/man/SUSEConnect.8 2022-08-03 
09:54:35.000000000 +0200
@@ -71,6 +71,10 @@
 \f[B]--status-text\f[R]
 Get current system registration status in text format.
 .TP
+\f[B]--keepalive\f[R]
+Send a keepalive call to the registration server, so it can detect which
+systems are still running.
+.TP
 \f[B]--write-config\f[R]
 Write options to config file at /etc/SUSEConnect.
 .TP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/man/SUSEConnect.8.md 
new/connect-ng-0.0.9~git5.75890b6/man/SUSEConnect.8.md
--- old/connect-ng-0.0.8~git2.368ea44/man/SUSEConnect.8.md      2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/man/SUSEConnect.8.md      2022-08-03 
09:54:35.000000000 +0200
@@ -68,6 +68,10 @@
   **--status-text**
   : Get current system registration status in text format.
 
+  **--keepalive**
+  : Send a keepalive call to the registration server, so it can detect which
+    systems are still running.
+
   **--write-config**
   : Write options to config file at /etc/SUSEConnect.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/suseconnect/connectUsage.txt 
new/connect-ng-0.0.9~git5.75890b6/suseconnect/connectUsage.txt
--- old/connect-ng-0.0.8~git2.368ea44/suseconnect/connectUsage.txt      
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/suseconnect/connectUsage.txt      
2022-08-03 09:54:35.000000000 +0200
@@ -35,6 +35,7 @@
                              format.
         --status-text        Get current system registration status in text
                              format.
+        --keepalive          Sends data to SCC to update the system 
information.
     -l, --list-extensions    List all extensions and modules available for
                              installation on this system.
         --write-config       Write options to config file at /etc/SUSEConnect.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/suseconnect/suseconnect.go 
new/connect-ng-0.0.9~git5.75890b6/suseconnect/suseconnect.go
--- old/connect-ng-0.0.8~git2.368ea44/suseconnect/suseconnect.go        
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/suseconnect/suseconnect.go        
2022-08-03 09:54:35.000000000 +0200
@@ -35,6 +35,7 @@
 func connectMain() {
        var (
                status           bool
+               keepAlive        bool
                statusText       bool
                debug            bool
                writeConfig      bool
@@ -60,6 +61,7 @@
        flag.BoolVar(&status, "status", false, "")
        flag.BoolVar(&status, "s", false, "")
        flag.BoolVar(&statusText, "status-text", false, "")
+       flag.BoolVar(&keepAlive, "keepalive", false, "")
        flag.BoolVar(&debug, "debug", false, "")
        flag.BoolVar(&writeConfig, "write-config", false, "")
        flag.BoolVar(&deRegister, "de-register", false, "")
@@ -140,6 +142,9 @@
                output, err := connect.GetProductStatuses("json")
                exitOnError(err)
                fmt.Println(output)
+       } else if keepAlive {
+               err := connect.SendKeepAlivePing()
+               exitOnError(err)
        } else if statusText {
                output, err := connect.GetProductStatuses("text")
                exitOnError(err)
@@ -240,6 +245,10 @@
                fmt.Print("Can not deregister base product. Use SUSEConnect -d 
to deactivate ")
                fmt.Print("the whole system.\n")
                os.Exit(70)
+       case connect.ErrPingFromUnregistered:
+               fmt.Print("Error sending keepalive: ")
+               fmt.Print("System is not registered. Use the --regcode 
parameter to register it.\n")
+               os.Exit(71)
        default:
                fmt.Printf("SUSEConnect error: %s\n", err)
                os.Exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/suseconnect-keepalive.service 
new/connect-ng-0.0.9~git5.75890b6/suseconnect-keepalive.service
--- old/connect-ng-0.0.8~git2.368ea44/suseconnect-keepalive.service     
1970-01-01 01:00:00.000000000 +0100
+++ new/connect-ng-0.0.9~git5.75890b6/suseconnect-keepalive.service     
2022-08-03 09:54:35.000000000 +0200
@@ -0,0 +1,13 @@
+[Unit]
+Description=Run SUSEConnect --keepalive
+Wants=suseconnect-keepalive.timer
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/SUSEConnect --keepalive
+EnvironmentFile=-/etc/sysconfig/proxy
+
+# Filter out this special exit code, since it will be raised by `SUSEConnect
+# --keepalive` whenever a system is not registered, which is a pretty typical
+# scenario.
+SuccessExitStatus=71
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/suseconnect-keepalive.timer 
new/connect-ng-0.0.9~git5.75890b6/suseconnect-keepalive.timer
--- old/connect-ng-0.0.8~git2.368ea44/suseconnect-keepalive.timer       
1970-01-01 01:00:00.000000000 +0100
+++ new/connect-ng-0.0.9~git5.75890b6/suseconnect-keepalive.timer       
2022-08-03 09:54:35.000000000 +0200
@@ -0,0 +1,11 @@
+[Unit]
+Description=Schedule daily SUSEConnect --keepalive calls
+After=network-online.target
+
+[Timer]
+# Run this timer every day at a randomized 24h delay.
+OnCalendar=daily
+RandomizedDelaySec=24h
+
+[Install]
+WantedBy=timers.target
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/connect-ng-0.0.8~git2.368ea44/suseconnect-ng.spec 
new/connect-ng-0.0.9~git5.75890b6/suseconnect-ng.spec
--- old/connect-ng-0.0.8~git2.368ea44/suseconnect-ng.spec       2022-04-20 
10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/suseconnect-ng.spec       2022-08-03 
09:54:35.000000000 +0200
@@ -30,7 +30,6 @@
 Group:          System/Management
 Source:         connect-ng-%{version}.tar.xz
 Source1:        %name-rpmlintrc
-BuildRequires:  git
 BuildRequires:  golang-packaging
 BuildRequires:  go >= 1.16
 BuildRequires:  zypper
@@ -103,6 +102,8 @@
 
 %prep
 %setup -q -n connect-ng-%{version}
+# keep git metadata but don't use it for "VCS stamping"
+mv .git .git.bak
 
 %build
 find %_builddir/..
@@ -130,10 +131,62 @@
 install -D -m 644 %_builddir/go/src/%import_path/man/zypper-migration.8 
%buildroot/%_mandir/man8/zypper-migration.8
 install -D -m 644 %_builddir/go/src/%import_path/man/zypper-search-packages.8 
%buildroot/%_mandir/man8/zypper-search-packages.8
 
+# Install the SUSEConnect --keepalive timer and service.
+install -D -m 644 %_builddir/go/src/%import_path/suseconnect-keepalive.timer 
%buildroot/%_unitdir/suseconnect-keepalive.timer
+install -D -m 644 %_builddir/go/src/%import_path/suseconnect-keepalive.service 
%buildroot/%_unitdir/suseconnect-keepalive.service
+ln -sf service %buildroot/%_sbindir/rcsuseconnect-keepalive
+
 find %_builddir/..
 # we currently do not ship the source for any go module
 rm -rf %buildroot/usr/share/go
 
+%pre
+%service_add_pre suseconnect-keepalive.service suseconnect-keepalive.timer
+
+# in pre blocks the old version is still installed. This way we can detect
+# if --keepalive was already present before
+kainfo=0
+helptext=$(SUSEConnect --help)
+if [ $? -eq 0 ]; then
+    echo "$helptext" | grep -q keepalive
+    kainfo=$?
+fi
+
+if [ $kainfo -ne 0 ]; then
+  cat << EOF
+Empowering you with enriched system visibility in the SUSE Customer Center
+
+SUSE is committed to helping provide better insights into the consumption of
+SUSE subscriptions regardless of where they are running; physical or virtual,
+on-prem or in the cloud.
+
+SUSE has been working on several improvements to the SUSE Customer Center 
(SCC),
+RMT, and SUSE Manager to provide a clearer picture of your system landscape:
+
+- SUSE Manager v4.1+ now sends system information to SCC.
+- SCC now captures which products are activated on systems that sit behind RMT
+  or SMT.
+- This update will enable your system to "ping" SCC/RMT daily to
+  confirm the system's active status. This will help you identify or filter out
+  systems in SCC that are no longer running or decommissioned. As always, the
+  choice is yours, you can disable the daily ping by disabling the
+  suseconnect-keepalive systemd timer.
+
+We will continue improving our products to make it easier for you to view and
+manage your subscription consumption. As always, we'd love to hear your 
feedback
+about these improvements and any ideas you might have.
+EOF
+fi
+
+%post
+%service_add_post suseconnect-keepalive.service suseconnect-keepalive.timer
+
+%preun
+%service_del_preun suseconnect-keepalive.service suseconnect-keepalive.timer
+
+%postun
+%service_del_postun suseconnect-keepalive.service suseconnect-keepalive.timer
+
 %check
 %gotest -v %import_path/internal/connect %{?test_hwinfo_args}
 %gotest -v %import_path/suseconnect
@@ -145,9 +198,12 @@
 %_bindir/suseconnect
 %_bindir/SUSEConnect
 %_sbindir/SUSEConnect
+%_sbindir/rcsuseconnect-keepalive
 /usr/lib/zypper/commands
 %_mandir/man8/*
 %_mandir/man5/*
+%_unitdir/suseconnect-keepalive.service
+%_unitdir/suseconnect-keepalive.timer
 
 %files -n libsuseconnect
 %license LICENSE LICENSE.LGPL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/testdata/migrations-smt.json 
new/connect-ng-0.0.9~git5.75890b6/testdata/migrations-smt.json
--- old/connect-ng-0.0.8~git2.368ea44/testdata/migrations-smt.json      
1970-01-01 01:00:00.000000000 +0100
+++ new/connect-ng-0.0.9~git5.75890b6/testdata/migrations-smt.json      
2022-08-03 09:54:35.000000000 +0200
@@ -0,0 +1,23 @@
+[
+  [
+    {
+      "product_type": "base",
+      "identifier": "suse-microos",
+      "release_stage": "released",
+      "free": true,
+      "productdataid": "2401",
+      "available": true,
+      "friendly_name": "SUSE Linux Enterprise Micro 5.2 x86_64",
+      "product_class": "MICROOS-X86",
+      "base": true,
+      "description": "SUSE Linux Enterprise Micro 5.2",
+      "shortname": "SUSE Linux Enterprise Micro",
+      "id": "101361",
+      "product_orig": "SUSE-MicroOS",
+      "release_type": null,
+      "cpe": "cpe:/o:suse:suse-microos:5.2",
+      "arch": "x86_64",
+      "version": "5.2"
+    }
+  ]
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/connect-ng-0.0.8~git2.368ea44/yast/lib/suse/toolkit/shim_utils.rb 
new/connect-ng-0.0.9~git5.75890b6/yast/lib/suse/toolkit/shim_utils.rb
--- old/connect-ng-0.0.8~git2.368ea44/yast/lib/suse/toolkit/shim_utils.rb       
2022-04-20 10:16:43.000000000 +0200
+++ new/connect-ng-0.0.9~git5.75890b6/yast/lib/suse/toolkit/shim_utils.rb       
2022-08-03 09:54:35.000000000 +0200
@@ -1,3 +1,5 @@
+require 'openssl'
+
 module SUSE
   module Toolkit
     # This module implements common boilerplate for wrapping libsuseconnect

Reply via email to