|
|
|
@ -413,96 +413,96 @@ def main() -> None: |
|
|
|
|
cloudlog.warning("updates are disabled by the DisableUpdates param") |
|
|
|
|
exit(0) |
|
|
|
|
|
|
|
|
|
ov_lock_fd = open(LOCK_FILE, 'w') |
|
|
|
|
try: |
|
|
|
|
fcntl.flock(ov_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) |
|
|
|
|
except OSError as e: |
|
|
|
|
raise RuntimeError("couldn't get overlay lock; is another instance running?") from e |
|
|
|
|
with open(LOCK_FILE, 'w') as ov_lock_fd: |
|
|
|
|
try: |
|
|
|
|
fcntl.flock(ov_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) |
|
|
|
|
except OSError as e: |
|
|
|
|
raise RuntimeError("couldn't get overlay lock; is another instance running?") from e |
|
|
|
|
|
|
|
|
|
# Set low io priority |
|
|
|
|
proc = psutil.Process() |
|
|
|
|
if psutil.LINUX: |
|
|
|
|
proc.ionice(psutil.IOPRIO_CLASS_BE, value=7) |
|
|
|
|
# Set low io priority |
|
|
|
|
proc = psutil.Process() |
|
|
|
|
if psutil.LINUX: |
|
|
|
|
proc.ionice(psutil.IOPRIO_CLASS_BE, value=7) |
|
|
|
|
|
|
|
|
|
# Check if we just performed an update |
|
|
|
|
if Path(os.path.join(STAGING_ROOT, "old_openpilot")).is_dir(): |
|
|
|
|
cloudlog.event("update installed") |
|
|
|
|
# Check if we just performed an update |
|
|
|
|
if Path(os.path.join(STAGING_ROOT, "old_openpilot")).is_dir(): |
|
|
|
|
cloudlog.event("update installed") |
|
|
|
|
|
|
|
|
|
if not params.get("InstallDate"): |
|
|
|
|
t = datetime.datetime.utcnow().isoformat() |
|
|
|
|
params.put("InstallDate", t.encode('utf8')) |
|
|
|
|
if not params.get("InstallDate"): |
|
|
|
|
t = datetime.datetime.utcnow().isoformat() |
|
|
|
|
params.put("InstallDate", t.encode('utf8')) |
|
|
|
|
|
|
|
|
|
updater = Updater() |
|
|
|
|
update_failed_count = 0 # TODO: Load from param? |
|
|
|
|
wait_helper = WaitTimeHelper() |
|
|
|
|
updater = Updater() |
|
|
|
|
update_failed_count = 0 # TODO: Load from param? |
|
|
|
|
wait_helper = WaitTimeHelper() |
|
|
|
|
|
|
|
|
|
# invalidate old finalized update |
|
|
|
|
set_consistent_flag(False) |
|
|
|
|
# invalidate old finalized update |
|
|
|
|
set_consistent_flag(False) |
|
|
|
|
|
|
|
|
|
# set initial state |
|
|
|
|
params.put("UpdaterState", "idle") |
|
|
|
|
# set initial state |
|
|
|
|
params.put("UpdaterState", "idle") |
|
|
|
|
|
|
|
|
|
# Run the update loop |
|
|
|
|
first_run = True |
|
|
|
|
while True: |
|
|
|
|
wait_helper.ready_event.clear() |
|
|
|
|
# Run the update loop |
|
|
|
|
first_run = True |
|
|
|
|
while True: |
|
|
|
|
wait_helper.ready_event.clear() |
|
|
|
|
|
|
|
|
|
# Attempt an update |
|
|
|
|
exception = None |
|
|
|
|
try: |
|
|
|
|
# TODO: reuse overlay from previous updated instance if it looks clean |
|
|
|
|
init_overlay() |
|
|
|
|
|
|
|
|
|
# ensure we have some params written soon after startup |
|
|
|
|
updater.set_params(False, update_failed_count, exception) |
|
|
|
|
|
|
|
|
|
if not system_time_valid() or first_run: |
|
|
|
|
first_run = False |
|
|
|
|
wait_helper.sleep(60) |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
update_failed_count += 1 |
|
|
|
|
|
|
|
|
|
# check for update |
|
|
|
|
params.put("UpdaterState", "checking...") |
|
|
|
|
updater.check_for_update() |
|
|
|
|
|
|
|
|
|
# download update |
|
|
|
|
last_fetch = read_time_from_param(params, "UpdaterLastFetchTime") |
|
|
|
|
timed_out = last_fetch is None or (datetime.datetime.utcnow() - last_fetch > datetime.timedelta(days=3)) |
|
|
|
|
user_requested_fetch = wait_helper.user_request == UserRequest.FETCH |
|
|
|
|
if params.get_bool("NetworkMetered") and not timed_out and not user_requested_fetch: |
|
|
|
|
cloudlog.info("skipping fetch, connection metered") |
|
|
|
|
elif wait_helper.user_request == UserRequest.CHECK: |
|
|
|
|
cloudlog.info("skipping fetch, only checking") |
|
|
|
|
else: |
|
|
|
|
updater.fetch_update() |
|
|
|
|
write_time_to_param(params, "UpdaterLastFetchTime") |
|
|
|
|
update_failed_count = 0 |
|
|
|
|
except subprocess.CalledProcessError as e: |
|
|
|
|
cloudlog.event( |
|
|
|
|
"update process failed", |
|
|
|
|
cmd=e.cmd, |
|
|
|
|
output=e.output, |
|
|
|
|
returncode=e.returncode |
|
|
|
|
) |
|
|
|
|
exception = f"command failed: {e.cmd}\n{e.output}" |
|
|
|
|
OVERLAY_INIT.unlink(missing_ok=True) |
|
|
|
|
except Exception as e: |
|
|
|
|
cloudlog.exception("uncaught updated exception, shouldn't happen") |
|
|
|
|
exception = str(e) |
|
|
|
|
OVERLAY_INIT.unlink(missing_ok=True) |
|
|
|
|
# Attempt an update |
|
|
|
|
exception = None |
|
|
|
|
try: |
|
|
|
|
# TODO: reuse overlay from previous updated instance if it looks clean |
|
|
|
|
init_overlay() |
|
|
|
|
|
|
|
|
|
# ensure we have some params written soon after startup |
|
|
|
|
updater.set_params(False, update_failed_count, exception) |
|
|
|
|
|
|
|
|
|
if not system_time_valid() or first_run: |
|
|
|
|
first_run = False |
|
|
|
|
wait_helper.sleep(60) |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
update_failed_count += 1 |
|
|
|
|
|
|
|
|
|
# check for update |
|
|
|
|
params.put("UpdaterState", "checking...") |
|
|
|
|
updater.check_for_update() |
|
|
|
|
|
|
|
|
|
# download update |
|
|
|
|
last_fetch = read_time_from_param(params, "UpdaterLastFetchTime") |
|
|
|
|
timed_out = last_fetch is None or (datetime.datetime.utcnow() - last_fetch > datetime.timedelta(days=3)) |
|
|
|
|
user_requested_fetch = wait_helper.user_request == UserRequest.FETCH |
|
|
|
|
if params.get_bool("NetworkMetered") and not timed_out and not user_requested_fetch: |
|
|
|
|
cloudlog.info("skipping fetch, connection metered") |
|
|
|
|
elif wait_helper.user_request == UserRequest.CHECK: |
|
|
|
|
cloudlog.info("skipping fetch, only checking") |
|
|
|
|
else: |
|
|
|
|
updater.fetch_update() |
|
|
|
|
write_time_to_param(params, "UpdaterLastFetchTime") |
|
|
|
|
update_failed_count = 0 |
|
|
|
|
except subprocess.CalledProcessError as e: |
|
|
|
|
cloudlog.event( |
|
|
|
|
"update process failed", |
|
|
|
|
cmd=e.cmd, |
|
|
|
|
output=e.output, |
|
|
|
|
returncode=e.returncode |
|
|
|
|
) |
|
|
|
|
exception = f"command failed: {e.cmd}\n{e.output}" |
|
|
|
|
OVERLAY_INIT.unlink(missing_ok=True) |
|
|
|
|
except Exception as e: |
|
|
|
|
cloudlog.exception("uncaught updated exception, shouldn't happen") |
|
|
|
|
exception = str(e) |
|
|
|
|
OVERLAY_INIT.unlink(missing_ok=True) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
params.put("UpdaterState", "idle") |
|
|
|
|
update_successful = (update_failed_count == 0) |
|
|
|
|
updater.set_params(update_successful, update_failed_count, exception) |
|
|
|
|
except Exception: |
|
|
|
|
cloudlog.exception("uncaught updated exception while setting params, shouldn't happen") |
|
|
|
|
try: |
|
|
|
|
params.put("UpdaterState", "idle") |
|
|
|
|
update_successful = (update_failed_count == 0) |
|
|
|
|
updater.set_params(update_successful, update_failed_count, exception) |
|
|
|
|
except Exception: |
|
|
|
|
cloudlog.exception("uncaught updated exception while setting params, shouldn't happen") |
|
|
|
|
|
|
|
|
|
# infrequent attempts if we successfully updated recently |
|
|
|
|
wait_helper.user_request = UserRequest.NONE |
|
|
|
|
wait_helper.sleep(5*60 if update_failed_count > 0 else 1.5*60*60) |
|
|
|
|
# infrequent attempts if we successfully updated recently |
|
|
|
|
wait_helper.user_request = UserRequest.NONE |
|
|
|
|
wait_helper.sleep(5*60 if update_failed_count > 0 else 1.5*60*60) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|