Bug 1452873

Summary: The timezone validity filter in anaconda rejects valid timezones that RHEL6 accepted
Product: Red Hat Enterprise Linux 7 Reporter: Frank Hirtz <fhirtz>
Component: anacondaAssignee: Radek Vykydal <rvykydal>
Status: CLOSED ERRATA QA Contact: Release Test Team <release-test-team-automation>
Severity: medium Docs Contact: Petr Bokoc <pbokoc>
Priority: medium    
Version: 7.3CC: cww, jstodola, pbokoc, pfrankli, pkotvan, rvykydal, sbueno
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: anaconda-21.48.22.123-1 Doc Type: Bug Fix
Doc Text:
Installer now accepts additional time zone definitions in Kickstart files Starting with Red Hat Enterprise Linux 7.0, *Anaconda* switched to a different, more restrictive method of validating time zone selections. This caused some time zone definitions, such as `Japan`, to be no longer valid despite being acceptable in previous versions, and legacy Kickstart files with these definitions had to be updated or they would default to the `Americas/New_York` time zone. The list of valid time zones was previously taken from `pytz.common_timezones` in the `pytz` Python library. This update changes the validation settings for the "timezone" Kickstart command to use `pytz.all_timezones`, which is a superset of the `common_timezones` list and which allows significantly more time zones to be specified. This change ensures that old Kickstart files made for Red Hat Enterprise Linux 6 still specify valid time zones. Note that this change only applies to the "timezone" Kickstart command. The time zone selection in the graphical and text-based interactive interfaces remains unchanged. Existing Kickstart files for Red Hat Enterprise Linux 7 that had valid time zone selections do not require any updates.
Story Points: ---
Clone Of:
: 1525556 2186608 (view as bug list) Environment:
Last Closed: 2018-04-10 08:45:01 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1420851, 1478303, 2186608    

Description Frank Hirtz 2017-05-19 20:00:05 UTC
Description of problem:

We have a client who's starting a migration to RHEL7 and was noticing that their previously valid kickstart timezone specification "Japan", which worked in RHEL6, is getting rejected in RHEL7 and thus they're defaulting to "Americas/New_York".

Having a quick look:

RHEL6:

<snip>
class Timezone(commands.timezone.FC6_Timezone):
    def execute(self, anaconda):
        # check validity
        tab = zonetab.ZoneTab()
        if self.timezone not in (entry.tz.replace(' ','_') for entry in
                                 tab.getEntries()):
            log.warning("Timezone %s set in kickstart is not valid." % (self.timezone,))
</snip>

RHEL7 outsources this:

<snip>
    def execute(self, *args):
        # write out timezone configuration
        if not timezone.is_valid_timezone(self.timezone):
            # this should never happen, but for pity's sake
            log.warning("Timezone %s set in kickstart is not valid, falling "\
                        "back to default (America/New_York).", self.timezone)
            self.timezone = "America/New_York"
<snip>

def is_valid_timezone(timezone):
    """
    Check if a given string is an existing timezone.

    :type timezone: str
    :rtype: bool

    """

    etc_zones = ["Etc/" + zone for zone in ETC_ZONES]

    return timezone in pytz.common_timezones + etc_zones
<snip>
# The following zones are not in pytz.common_timezones and
# Etc category in pytz.all_timezones includes some more,
# however confusing ones (like UCT, GMT+0, GMT-0,...)
ETC_ZONES = ['GMT+1', 'GMT+2', 'GMT+3', 'GMT+4', 'GMT+5', 'GMT+6', 'GMT+7',
             'GMT+8', 'GMT+9', 'GMT+10', 'GMT+11', 'GMT+12',
             'GMT-1', 'GMT-2', 'GMT-3', 'GMT-4', 'GMT-5', 'GMT-6', 'GMT-7',
             'GMT-8', 'GMT-9', 'GMT-10', 'GMT-11', 'GMT-12', 'GMT-13',
             'GMT-14', 'UTC', 'GMT']
<snip>

So, we're using pytz "common_timezones" to assess validity. Having a look at that, we have:

"common_timezones is a list of useful, current timezones. It doesn’t contain deprecated zones or historical zones, except for a few I’ve deemed in common usage, such as US/Eastern (open a bug report if you think other timezones are deserving of being included here). It is also a sequence of strings."

To get the "deprecated" or "historical" zones, we want all_timezones for this:

<snip>
>>> for tz in pytz.common_timezones:
...     if tz == "Japan":
...             print tz
... 
>>> for tz in pytz.all_timezones:
...     if tz == "Japan":
...             print tz
... 
Japan
>>> 
</snip>

Having a look at the corresponding set function in anaconda:
<snip>
def write_timezone_config(timezone, root):
    """
    Write timezone configuration for the system specified by root.

    :param timezone: ksdata.timezone object
    :param root: path to the root
    :raise: TimezoneConfigError

    """

    # we want to create a relative symlink
    tz_file = "/usr/share/zoneinfo/" + timezone.timezone
    rooted_tz_file = os.path.normpath(root + tz_file)
    relative_path = os.path.normpath("../" + tz_file)
    link_path = os.path.normpath(root + "/etc/localtime")

    if not os.access(rooted_tz_file, os.R_OK):
        log.error("Timezone to be linked (%s) doesn't exist", rooted_tz_file)
</snip>

[root@testhost ~]# ls -1 /usr/share/zoneinfo/ | grep Japan
Japan
</snip>

So, as an eyeball sanity check, it looks like this'd work if we relax the filter a bit.

Version-Release number of selected component (if applicable):
RHEL7 anaconda

How reproducible:
Always

Steps to Reproduce:
1. in kickstart specify "timezone Japan"


Actual results:
The set timezone on the system is the default "Americas/New_York"

Expected results:

The timezone is set to Japan.
Additional info:

Comment 2 Frank Hirtz 2017-05-19 20:02:25 UTC
I understand that the behavior is consistent with the current kickstart documentation:

<snip>
 timezone (required)
    Sets the system time zone to timezone. To view a list of available time zones, use the timedatectl list-timezones command. 
</snip>

[root@testhost ~]# timedatectl list-timezones | grep 'Japan\|Asia/Tokyo'
Asia/Tokyo
</snip>

...but it would make carrying forward previous kickstarts simpler and less error-prone if we allow the "historic" timezones to remain as valid options (even if not documented ones).

Comment 6 Radek Vykydal 2017-08-14 13:19:30 UTC
https://github.com/rhinstaller/anaconda/pull/1149

Comment 9 Peter Kotvan 2017-12-05 08:59:32 UTC
I was able to reproduce this issue on RHEL-7.3 and verify it on RHEL-7.5-20171130.0 with anaconda-21.48.22.128-1.el7.

Thanks.

Comment 11 Radek Vykydal 2017-12-18 08:12:46 UTC
Looks good to me, thank you.

Comment 14 errata-xmlrpc 2018-04-10 08:45:01 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:0671