diff --git a/cloudinit/analyze/dump.py b/cloudinit/analyze/dump.py index 6e61648f991..60a2fd9b28d 100644 --- a/cloudinit/analyze/dump.py +++ b/cloudinit/analyze/dump.py @@ -4,7 +4,7 @@ import sys from datetime import datetime -from cloudinit import atomic_helper, subp +from cloudinit import atomic_helper, subp, util stage_to_description = { "finished": "finished running cloud-init", @@ -44,14 +44,23 @@ def parse_timestamp(timestampstr): dt = datetime.strptime(timestampstr, CLOUD_INIT_ASCTIME_FMT) timestamp = dt.strftime("%s.%f") else: - # allow date(1) to handle other formats we don't expect + # allow GNU date(1) to handle other formats we don't expect + # This may throw a ValueError if no GNU date can be found timestamp = parse_timestamp_from_date(timestampstr) return float(timestamp) def parse_timestamp_from_date(timestampstr): - out, _ = subp.subp(["date", "+%s.%3N", "-d", timestampstr]) + cmd = "date" + if not util.is_Linux(): + if subp.which("gdate"): + cmd = "gdate" + else: + raise ValueError( + f"Unable to parse timestamp without GNU date: [{timestampstr}]" + ) + out, _ = subp.subp([cmd, "+%s.%3N", "-d", timestampstr]) timestamp = out.strip() return float(timestamp) diff --git a/tests/unittests/analyze/test_dump.py b/tests/unittests/analyze/test_dump.py index 04c896e25c2..3fb0046aa59 100644 --- a/tests/unittests/analyze/test_dump.py +++ b/tests/unittests/analyze/test_dump.py @@ -11,7 +11,7 @@ parse_timestamp, ) from cloudinit.subp import which -from cloudinit.util import write_file +from cloudinit.util import is_Linux, write_file from tests.unittests.helpers import mock, skipIf @@ -44,7 +44,11 @@ def test_parse_timestamp_handles_journalctl_format_adding_year(self): assert float(dt.strftime("%s.%f")) == parse_timestamp(journal_stamp) @skipIf(not which("date"), "'date' command not available.") - @pytest.mark.allow_subp_for("date") + @skipIf( + not is_Linux() and not which("gdate"), + "'GNU date' command not available.", + ) + @pytest.mark.allow_subp_for("date", "gdate") def test_parse_unexpected_timestamp_format_with_date_command(self): """Dump sends unexpected timestamp formats to date for processing.""" new_fmt = "%H:%M %m/%d %Y"