Further build-many-glibcs.py fixes for utcnow() deprecation

Message ID b45d632-e1d6-c360-5de7-d879624f135@redhat.com
State Committed
Commit b86cb494f9a27a106c96c025c6d834334d85b80a
Headers
Series Further build-many-glibcs.py fixes for utcnow() deprecation |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed

Commit Message

Joseph Myers Jan. 13, 2024, 2:04 a.m. UTC
  It turns out that the replacement of datetime.datetime.utcnow(), for a
warning produced early in running build-many-glibcs.py with Python
3.12, (a) wasn't complete (there were other uses elsewhere in the
script also needing updating) and (b) broke reading of build-time from
build-state.json, because an aware datetime was written out including
+00:00 for the timezone, which was not expected by the strptime call.

Fix the first by making the change to
datetime.datetime.now(datetime.timezone.utc) for all the remaining
utcnow() calls.  Fix the second by using strftime with an explicit
format instead of just str() when formatting build times for
build-state.json and and email subjects, and then setting the timezone
explicitly when reading from build-state.json.  (Other uses, in
particular messages output by the bot, continue to use str() as the
precise format should not matter in those cases; it shouldn't actually
matter for email subjects either but it seems a good idea to keep
those short.)

Tested with a bot-cycle run and checking the format of times in
build-state.json afterwards.
  

Comments

Joseph Myers Jan. 18, 2024, 9:36 p.m. UTC | #1
Ping.  This patch 
<https://sourceware.org/pipermail/libc-alpha/2024-January/154034.html> is 
pending review.
  
H.J. Lu Jan. 18, 2024, 10:22 p.m. UTC | #2
On Fri, Jan 12, 2024 at 6:05 PM Joseph Myers <josmyers@redhat.com> wrote:
>
> It turns out that the replacement of datetime.datetime.utcnow(), for a
> warning produced early in running build-many-glibcs.py with Python
> 3.12, (a) wasn't complete (there were other uses elsewhere in the
> script also needing updating) and (b) broke reading of build-time from
> build-state.json, because an aware datetime was written out including
> +00:00 for the timezone, which was not expected by the strptime call.
>
> Fix the first by making the change to
> datetime.datetime.now(datetime.timezone.utc) for all the remaining
> utcnow() calls.  Fix the second by using strftime with an explicit
> format instead of just str() when formatting build times for
> build-state.json and and email subjects, and then setting the timezone
> explicitly when reading from build-state.json.  (Other uses, in
> particular messages output by the bot, continue to use str() as the
> precise format should not matter in those cases; it shouldn't actually
> matter for email subjects either but it seems a good idea to keep
> those short.)
>
> Tested with a bot-cycle run and checking the format of times in
> build-state.json afterwards.
>
> diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
> index ec2ded6e56..20601ed853 100755
> --- a/scripts/build-many-glibcs.py
> +++ b/scripts/build-many-glibcs.py
> @@ -1057,7 +1057,8 @@ class Context(object):
>      def update_build_state(self, action, build_time, build_versions):
>          """Update the build state after a build."""
>          build_time = build_time.replace(microsecond=0)
> -        self.build_state[action]['build-time'] = str(build_time)
> +        self.build_state[action]['build-time'] = build_time.strftime(
> +            '%Y-%m-%d %H:%M:%S')
>          self.build_state[action]['build-versions'] = build_versions
>          build_results = {}
>          for log in self.status_log_list:
> @@ -1103,15 +1104,17 @@ class Context(object):
>          old_time_str = self.build_state[action]['build-time']
>          if not old_time_str:
>              return True
> -        old_time = datetime.datetime.strptime(old_time_str,
> -                                              '%Y-%m-%d %H:%M:%S')
> -        new_time = datetime.datetime.utcnow()
> +        old_time = datetime.datetime.strptime(
> +            old_time_str, '%Y-%m-%d %H:%M:%S').replace(
> +                tzinfo=datetime.timezone.utc)
> +        new_time = datetime.datetime.now(datetime.timezone.utc)
>          delta = new_time - old_time
>          return delta.total_seconds() >= delay
>
>      def bot_cycle(self):
>          """Run a single round of checkout and builds."""
> -        print('Bot cycle starting %s.' % str(datetime.datetime.utcnow()))
> +        print('Bot cycle starting %s.'
> +              % str(datetime.datetime.now(datetime.timezone.utc)))
>          self.load_bot_config_json()
>          actions = ('host-libraries', 'compilers', 'glibcs')
>          self.bot_run_self(['--replace-sources'], 'checkout')
> @@ -1163,12 +1166,13 @@ class Context(object):
>              shutil.copytree(self.logsdir, self.logsdir_old)
>          for a in actions:
>              if must_build[a]:
> -                build_time = datetime.datetime.utcnow()
> +                build_time = datetime.datetime.now(datetime.timezone.utc)
>                  print('Rebuilding %s at %s.' % (a, str(build_time)))
>                  self.bot_run_self([], a)
>                  self.load_build_state_json()
>                  self.bot_build_mail(a, build_time)
> -        print('Bot cycle done at %s.' % str(datetime.datetime.utcnow()))
> +        print('Bot cycle done at %s.'
> +              % str(datetime.datetime.now(datetime.timezone.utc)))
>
>      def bot_build_mail(self, action, build_time):
>          """Send email with the results of a build."""
> @@ -1184,7 +1188,7 @@ class Context(object):
>          build_time = build_time.replace(microsecond=0)
>          subject = (self.bot_config['email-subject'] %
>                     {'action': action,
> -                    'build-time': str(build_time)})
> +                    'build-time': build_time.strftime('%Y-%m-%d %H:%M:%S')})
>          results = self.build_state[action]['build-results']
>          changes = self.build_state[action]['result-changes']
>          ever_passed = set(self.build_state[action]['ever-passed'])
> @@ -1233,7 +1237,8 @@ class Context(object):
>          msg['From'] = self.bot_config['email-from']
>          msg['To'] = self.bot_config['email-to']
>          msg['Message-ID'] = email.utils.make_msgid()
> -        msg['Date'] = email.utils.format_datetime(datetime.datetime.utcnow())
> +        msg['Date'] = email.utils.format_datetime(
> +            datetime.datetime.now(datetime.timezone.utc))
>          with smtplib.SMTP(self.bot_config['email-server']) as s:
>              s.send_message(msg)
>
>
> --
> Joseph S. Myers
> josmyers@redhat.com
>

LGTM.

Thanks.
  

Patch

diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
index ec2ded6e56..20601ed853 100755
--- a/scripts/build-many-glibcs.py
+++ b/scripts/build-many-glibcs.py
@@ -1057,7 +1057,8 @@  class Context(object):
     def update_build_state(self, action, build_time, build_versions):
         """Update the build state after a build."""
         build_time = build_time.replace(microsecond=0)
-        self.build_state[action]['build-time'] = str(build_time)
+        self.build_state[action]['build-time'] = build_time.strftime(
+            '%Y-%m-%d %H:%M:%S')
         self.build_state[action]['build-versions'] = build_versions
         build_results = {}
         for log in self.status_log_list:
@@ -1103,15 +1104,17 @@  class Context(object):
         old_time_str = self.build_state[action]['build-time']
         if not old_time_str:
             return True
-        old_time = datetime.datetime.strptime(old_time_str,
-                                              '%Y-%m-%d %H:%M:%S')
-        new_time = datetime.datetime.utcnow()
+        old_time = datetime.datetime.strptime(
+            old_time_str, '%Y-%m-%d %H:%M:%S').replace(
+                tzinfo=datetime.timezone.utc)
+        new_time = datetime.datetime.now(datetime.timezone.utc)
         delta = new_time - old_time
         return delta.total_seconds() >= delay
 
     def bot_cycle(self):
         """Run a single round of checkout and builds."""
-        print('Bot cycle starting %s.' % str(datetime.datetime.utcnow()))
+        print('Bot cycle starting %s.'
+              % str(datetime.datetime.now(datetime.timezone.utc)))
         self.load_bot_config_json()
         actions = ('host-libraries', 'compilers', 'glibcs')
         self.bot_run_self(['--replace-sources'], 'checkout')
@@ -1163,12 +1166,13 @@  class Context(object):
             shutil.copytree(self.logsdir, self.logsdir_old)
         for a in actions:
             if must_build[a]:
-                build_time = datetime.datetime.utcnow()
+                build_time = datetime.datetime.now(datetime.timezone.utc)
                 print('Rebuilding %s at %s.' % (a, str(build_time)))
                 self.bot_run_self([], a)
                 self.load_build_state_json()
                 self.bot_build_mail(a, build_time)
-        print('Bot cycle done at %s.' % str(datetime.datetime.utcnow()))
+        print('Bot cycle done at %s.'
+              % str(datetime.datetime.now(datetime.timezone.utc)))
 
     def bot_build_mail(self, action, build_time):
         """Send email with the results of a build."""
@@ -1184,7 +1188,7 @@  class Context(object):
         build_time = build_time.replace(microsecond=0)
         subject = (self.bot_config['email-subject'] %
                    {'action': action,
-                    'build-time': str(build_time)})
+                    'build-time': build_time.strftime('%Y-%m-%d %H:%M:%S')})
         results = self.build_state[action]['build-results']
         changes = self.build_state[action]['result-changes']
         ever_passed = set(self.build_state[action]['ever-passed'])
@@ -1233,7 +1237,8 @@  class Context(object):
         msg['From'] = self.bot_config['email-from']
         msg['To'] = self.bot_config['email-to']
         msg['Message-ID'] = email.utils.make_msgid()
-        msg['Date'] = email.utils.format_datetime(datetime.datetime.utcnow())
+        msg['Date'] = email.utils.format_datetime(
+            datetime.datetime.now(datetime.timezone.utc))
         with smtplib.SMTP(self.bot_config['email-server']) as s:
             s.send_message(msg)