|
69 | 69 | from mig.shared.url import urlparse
|
70 | 70 |
|
71 | 71 |
|
| 72 | +def determine_timezone(_environ=os.environ, _path_exists=os.path.exists, _print=print): |
| 73 | + """Attempt to detect the timezone in various known portable ways.""" |
| 74 | + |
| 75 | + sys_timezone = None |
| 76 | + |
| 77 | + timezone_link = '/etc/localtime' |
| 78 | + timezone_cmd = ["/usr/bin/timedatectl", "status"] |
| 79 | + |
| 80 | + env_timezone = _environ.get('TZ', None) |
| 81 | + if env_timezone: |
| 82 | + # Use TZ env value directly if set |
| 83 | + return env_timezone |
| 84 | + |
| 85 | + if _path_exists(timezone_link): |
| 86 | + zoneinfo_absolute = os.path.realpath(timezone_link) |
| 87 | + # Convert /etc/localtime link to e.g. /.../zoneinfo/Europe/Rome |
| 88 | + # then remove leading directories leaving TZ e.g. Europe/Rome |
| 89 | + zoneinfo_path_parts = zoneinfo_absolute.split('/') |
| 90 | + try: |
| 91 | + zoneinfo_index = zoneinfo_path_parts.index('zoneinfo') |
| 92 | + # the last path parts are at least .../zoneinfo/ which |
| 93 | + # is good enough for us here - treat them as the timezone |
| 94 | + localtime_timezone = '/'.join( |
| 95 | + zoneinfo_path_parts[zoneinfo_index + 1:]) |
| 96 | + return localtime_timezone |
| 97 | + except IndexError: |
| 98 | + pass |
| 99 | + |
| 100 | + _print("WARNING: ignoring non-standard /etc/localtime") |
| 101 | + |
| 102 | + if _path_exists(timezone_cmd[0]): |
| 103 | + # Parse Time zone: LOCATION (ALIAS, OFFSET) output of timedatectl |
| 104 | + # into just LOCATION |
| 105 | + try: |
| 106 | + timezone_proc = subprocess_popen( |
| 107 | + timezone_cmd, stdout=subprocess_pipe) |
| 108 | + for line in timezone_proc.stdout.readlines(): |
| 109 | + line = ensure_native_string(line.strip()) |
| 110 | + if not line.startswith("Time zone: "): |
| 111 | + continue |
| 112 | + timedatectl_parts = line.replace( |
| 113 | + "Time zone: ", "").split(" ", 1) |
| 114 | + return timedatectl_parts[0] |
| 115 | + except IndexError: |
| 116 | + pass |
| 117 | + except OSError as exc: |
| 118 | + # warn about any issues executing the command but continue |
| 119 | + _print("WARNING: failed to extract time zone with %s : %s" % |
| 120 | + (' '.join(timezone_cmd), exc)) |
| 121 | + |
| 122 | + # none of the standard extraction methods succeeded by this point |
| 123 | + _print("WARNING: failed to extract system time zone; defaulting to UTC") |
| 124 | + return 'UTC' |
| 125 | + |
| 126 | + |
72 | 127 | def fill_template(template_file, output_file, settings, eat_trailing_space=[],
|
73 | 128 | additional=None):
|
74 | 129 | """Fill a configuration template using provided settings dictionary"""
|
@@ -944,25 +999,7 @@ def generate_confs(
|
944 | 999 | user_dict['__DUPLICATI_PROTOCOLS__'] = ' '.join(prio_duplicati_protocols)
|
945 | 1000 |
|
946 | 1001 | if timezone == keyword_auto:
|
947 |
| - # attempt to detect the timezone |
948 |
| - sys_timezone = None |
949 |
| - try: |
950 |
| - timezone_cmd = ["/usr/bin/timedatectl", "status"] |
951 |
| - timezone_proc = subprocess_popen( |
952 |
| - timezone_cmd, stdout=subprocess_pipe) |
953 |
| - for line in timezone_proc.stdout.readlines(): |
954 |
| - line = ensure_native_string(line.strip()) |
955 |
| - if not line.startswith("Time zone: "): |
956 |
| - continue |
957 |
| - sys_timezone = line.replace("Time zone: ", "").split(" ", 1)[0] |
958 |
| - except OSError as exc: |
959 |
| - # warn about any issues executing the command but continue |
960 |
| - pass |
961 |
| - if sys_timezone is None: |
962 |
| - print("WARNING: failed to extract system time zone; defaulting to UTC") |
963 |
| - sys_timezone = 'UTC' |
964 |
| - |
965 |
| - timezone = sys_timezone |
| 1002 | + timezone = determine_timezone() |
966 | 1003 |
|
967 | 1004 | user_dict['__SEAFILE_TIMEZONE__'] = timezone
|
968 | 1005 |
|
|
0 commit comments