From 368cace952ac822819cd3d3258d77e474642ea8c Mon Sep 17 00:00:00 2001 From: Carlos Abalde Date: Tue, 4 Jun 2024 16:59:57 +0200 Subject: [PATCH] Add 'automated_backups' & 'force_backup' flags to gain more control over when backups are written --- README.rst | 9 ++++-- src/remote.c | 65 +++++++++++++++++++++----------------- src/remote.h | 6 ++-- src/tests/file.backup.vtc | 66 ++++++++++++++++++++++++++++++++++++++- src/vmod_cfg.vcc | 27 ++++++++++++++-- src/vmod_cfg_file.c | 23 +++++++------- src/vmod_cfg_rules.c | 19 +++++------ src/vmod_cfg_script.c | 17 +++++----- 8 files changed, 167 insertions(+), 65 deletions(-) diff --git a/README.rst b/README.rst index 1cbc86b..a888603 100644 --- a/README.rst +++ b/README.rst @@ -38,6 +38,7 @@ import cfg; Object file( STRING location, STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, INT curl_connection_timeout=0, @@ -50,7 +51,7 @@ import cfg; ENUM { ini, json } format="ini", STRING name_delimiter=":", STRING value_delimiter=";") - Method BOOL .reload() + Method BOOL .reload(BOOL force_backup=0) Method STRING .dump(BOOL stream=0, STRING prefix="") Method VOID .inspect() @@ -64,6 +65,7 @@ import cfg; Object rules( STRING location, STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, INT curl_connection_timeout=0, @@ -73,7 +75,7 @@ import cfg; STRING curl_ssl_cafile="", STRING curl_ssl_capath="", STRING curl_proxy="") - Method BOOL .reload() + Method BOOL .reload(BOOL force_backup=0) Method VOID .inspect() Method STRING .get(STRING value, STRING fallback="") @@ -85,6 +87,7 @@ import cfg; Object script( STRING location="", STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, ENUM { lua, javascript } type="lua", @@ -105,7 +108,7 @@ import cfg; STRING curl_ssl_cafile="", STRING curl_ssl_capath="", STRING curl_proxy="") - Method BOOL .reload() + Method BOOL .reload(BOOL force_backup=0) Method VOID .inspect() Method VOID .init(STRING code="") diff --git a/src/remote.c b/src/remote.c index 6908e73..ee3c682 100644 --- a/src/remote.c +++ b/src/remote.c @@ -44,7 +44,8 @@ static char *read_url(VRT_CTX, remote_t *remote); remote_t * new_remote( - const char *location, const char *backup, unsigned period, unsigned curl_connection_timeout, + const char *location, const char *backup, unsigned automated_backups, + unsigned period, unsigned curl_connection_timeout, unsigned curl_transfer_timeout, unsigned curl_ssl_verify_peer, unsigned curl_ssl_verify_host, const char *curl_ssl_cafile, const char *curl_ssl_capath, const char *curl_proxy) @@ -68,6 +69,7 @@ new_remote( } else { result->backup = NULL; } + result->automated_backups = automated_backups; result->period = period; result->curl.connection_timeout = curl_connection_timeout; result->curl.transfer_timeout = curl_transfer_timeout; @@ -109,6 +111,7 @@ free_remote(remote_t *remote) FREE_STRING(location.raw); FREE_STRING(location.parsed); remote->backup = NULL; + remote->automated_backups = 0; remote->period = 0; remote->curl.connection_timeout = 0; remote->curl.transfer_timeout = 0; @@ -171,7 +174,7 @@ check_remote_backup( unsigned check_remote( - VRT_CTX, remote_t *remote, unsigned force, + VRT_CTX, remote_t *remote, unsigned force_load, unsigned force_backup, unsigned (*callback)(VRT_CTX, void *, char *, unsigned), void *ptr) { unsigned result = 0; @@ -179,7 +182,7 @@ check_remote( time_t now = time(NULL); unsigned winner = 0; - if (!force && + if (!force_load && !remote->state.reloading && ((remote->period > 0) && (now - remote->state.tst > remote->period))) { AZ(pthread_mutex_lock(&remote->state.mutex)); @@ -190,7 +193,7 @@ check_remote( AZ(pthread_mutex_unlock(&remote->state.mutex)); } - if (force || winner) { + if (force_load || winner) { char *contents = (*remote->read)(ctx, remote); if (contents != NULL && strlen(contents) > 0) { @@ -206,39 +209,45 @@ check_remote( AZ(pthread_mutex_unlock(&remote->state.mutex)); if (remote->backup != NULL) { - FILE *backup = fopen(remote->backup, "wb"); - if (backup != NULL) { - int rc = fputs(contents, backup); - if (rc < 0) { - // Not possible to use GNU strerror_r() due to Linux Alpine - // issue. See: - // - https://stackoverflow.com/questions/41953104/strerror-r-is-incorrectly-declared-on-alpine-linux - char buffer[256]; + if (remote->automated_backups || force_backup) { + FILE *backup = fopen(remote->backup, "wb"); + if (backup != NULL) { + int rc = fputs(contents, backup); + if (rc < 0) { + // Not possible to use GNU strerror_r() due to Linux Alpine + // issue. See: + // - https://stackoverflow.com/questions/41953104/strerror-r-is-incorrectly-declared-on-alpine-linux + char buffer[256]; #ifdef STRERROR_R_CHAR_P - LOG(ctx, LOG_ERR, - "Failed to write backup file (location=%s, backup=%s, error=%s)", - remote->location.raw, remote->backup, strerror_r(rc, buffer, sizeof(buffer))); -#else - rc = strerror_r(rc, buffer, sizeof(buffer)); - if (rc == 0) { LOG(ctx, LOG_ERR, "Failed to write backup file (location=%s, backup=%s, error=%s)", - remote->location.raw, remote->backup, buffer); + remote->location.raw, remote->backup, strerror_r(rc, buffer, sizeof(buffer))); +#else + rc = strerror_r(rc, buffer, sizeof(buffer)); + if (rc == 0) { + LOG(ctx, LOG_ERR, + "Failed to write backup file (location=%s, backup=%s, error=%s)", + remote->location.raw, remote->backup, buffer); + } else { + LOG(ctx, LOG_ERR, + "Failed to write backup file (location=%s, backup=%s, error=%d)", + remote->location.raw, remote->backup, rc); + } +#endif } else { - LOG(ctx, LOG_ERR, - "Failed to write backup file (location=%s, backup=%s, error=%d)", - remote->location.raw, remote->backup, rc); + LOG(ctx, LOG_INFO, + "Successfully write to backup file (location=%s, backup=%s)", + remote->location.raw, remote->backup); } -#endif + fclose(backup); } else { - LOG(ctx, LOG_INFO, - "Successfully write to backup file (location=%s, backup=%s)", + LOG(ctx, LOG_ERR, + "Failed to open backup file (location=%s, backup=%s)", remote->location.raw, remote->backup); } - fclose(backup); } else { - LOG(ctx, LOG_ERR, - "Failed to open backup file (location=%s, backup=%s)", + LOG(ctx, LOG_INFO, + "Automated backups are disabled (location=%s, backup=%s)", remote->location.raw, remote->backup); } } diff --git a/src/remote.h b/src/remote.h index f3c0018..d21b41b 100644 --- a/src/remote.h +++ b/src/remote.h @@ -10,6 +10,7 @@ typedef struct remote { const char *parsed; } location; const char *backup; + unsigned automated_backups; unsigned period; struct { unsigned connection_timeout; @@ -32,14 +33,15 @@ typedef struct remote { } remote_t; remote_t *new_remote( - const char *location, const char *backup, unsigned period, unsigned curl_connection_timeout, + const char *location, const char *backup, unsigned automated_backups, + unsigned period, unsigned curl_connection_timeout, unsigned curl_transfer_timeout, unsigned curl_ssl_verify_peer, unsigned curl_ssl_verify_host, const char *curl_ssl_cafile, const char *curl_ssl_capath, const char *curl_proxy); void free_remote(remote_t *remote); unsigned check_remote( - VRT_CTX, remote_t *remote, unsigned force, + VRT_CTX, remote_t *remote, unsigned force_load, unsigned force_backup, unsigned (*callback)(VRT_CTX, void *, char *, unsigned), void *ptr); void inspect_remote(VRT_CTX, remote_t *remote); diff --git a/src/tests/file.backup.vtc b/src/tests/file.backup.vtc index b17e522..42d7314 100644 --- a/src/tests/file.backup.vtc +++ b/src/tests/file.backup.vtc @@ -42,6 +42,7 @@ varnish v_no_backup -vcl { new file = cfg.file( "http://${v_origin_no_backup_addr}:${v_origin_no_backup_port}/test.ini", backup="${tmp}/backup.ini", + automated_backups=true, period=0, curl_connection_timeout=2000, curl_transfer_timeout=2000, @@ -101,6 +102,7 @@ varnish v_broken_backup -vcl { new file = cfg.file( "http://${v_origin_broken_backup_addr}:${v_origin_broken_backup_port}/test.ini", backup="${tmp}/backup.ini", + automated_backups=true, period=0, curl_connection_timeout=2000, curl_transfer_timeout=2000, @@ -161,6 +163,7 @@ varnish v_valid_backup -vcl { new file = cfg.file( "http://${v_origin_valid_backup_addr}:${v_origin_valid_backup_port}/test.ini", backup="${tmp}/backup.ini", + automated_backups=true, period=0, curl_connection_timeout=2000, curl_transfer_timeout=2000, @@ -197,6 +200,66 @@ varnish v_valid_backup -expect client_req == 1 varnish v_valid_backup -expect MGT.child_panic == 0 +################################################################################ +## Remote valid, backup doesn't exist and automated backups disabled +################################################################################ + +shell { + rm -f "${tmp}/backup.ini" +} + +server s_origin_no_automated_backups { + rxreq + expect req.url == "/test.ini" + txresp -body "field: foo" +} -repeat 3 -start + +varnish v_origin_no_automated_backups -vcl { + backend default { + .host = "${s_origin_no_automated_backups_addr}"; + .port = "${s_origin_no_automated_backups_port}"; + } + + sub vcl_recv { + return (pass); + } +} -start + +varnish v_no_automated_backups -vcl { + import ${vmod_cfg}; + + backend default { + .host = "${s_origin1_addr}"; + .port = "${s_origin1_port}"; + } + + sub vcl_init { + new file = cfg.file( + "http://${v_origin_no_automated_backups_addr}:${v_origin_no_automated_backups_port}/test.ini", + backup="${tmp}/backup.ini", + automated_backups=false, + period=0, + curl_connection_timeout=2000, + curl_transfer_timeout=2000, + curl_ssl_verify_peer=false, + curl_ssl_verify_host=false, + curl_ssl_cafile="", + curl_ssl_capath="", + curl_proxy="", + format=ini, + name_delimiter=":", + value_delimiter=";"); + + file.reload(force_backup=true); + } +} -start + +logexpect l_no_automated_backups -v v_no_automated_backups -d 1 -g raw { + expect * * VCL_Log {^\[CFG\].* Remote successfully parsed .*\(.*, is_backup=0, .*\)$} + expect * * VCL_Log {^\[CFG\].* Automated backups are disabled .*$} + expect * * VCL_Log {^\[CFG\].* Successfully write to backup file .*$} +} -start -wait + ################################################################################ ## Basic functionalities ################################################################################ @@ -246,6 +309,7 @@ varnish v_basics -vcl { new file = cfg.file( "http://${v_origin_basics_addr}:${v_origin_basics_port}/test.ini", backup="${tmp}/backup.ini", + automated_backups=true, period=0, curl_connection_timeout=2000, curl_transfer_timeout=2000, @@ -261,7 +325,7 @@ varnish v_basics -vcl { sub vcl_deliver { if (req.http.reload == "1") { - set resp.http.reload = file.reload(); + set resp.http.reload = file.reload(force_backup=false); } set resp.http.result = file.get("field", "-"); set resp.http.dump = file.dump(); diff --git a/src/vmod_cfg.vcc b/src/vmod_cfg.vcc index 781f476..4591b1c 100644 --- a/src/vmod_cfg.vcc +++ b/src/vmod_cfg.vcc @@ -60,6 +60,7 @@ Description $Object file( STRING location, STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, INT curl_connection_timeout=0, @@ -81,6 +82,12 @@ Arguments backup: when this option is used, you have to specify where to save the backup file. + automated_backups: if enabled and a backup file has been provided, that + file is updated on every successful load of ``location`` (i.e. during + ``vcl_init``, during periodical updates when ``period`` > 0, etc.). + Otherwise, the file is only updated when explicitly requested to do so (e.g. + calls to ``.reload()`` using the ``force_backup`` flag). + period: how frequently (seconds) contents of the file are reloaded (0 means disabling periodical reloads). @@ -119,8 +126,12 @@ Description on every VCL WARM event received by the VMOD and every ``period`` seconds (if ``period`` > 0). -$Method BOOL .reload() +$Method BOOL .reload(BOOL force_backup=1) +Arguments + force_backup: if enabled and a backup file has been provided, that file + will be updated upon a successful reload, overriding the default behavior + for automated backups. Description Reloads contents of the file. A ``False`` value is returned on failure. @@ -167,6 +178,7 @@ Description $Object rules( STRING location, STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, INT curl_connection_timeout=0, @@ -182,8 +194,12 @@ Description See ``cfg.file()`` for details. -$Method BOOL .reload() +$Method BOOL .reload(BOOL force_backup=1) +Arguments + force_backup: if enabled and a backup file has been provided, that file + will be updated upon a successful reload, overriding the default behavior + for automated backups. Description Reloads contents of the file. A ``False`` value is returned on failure. @@ -206,6 +222,7 @@ Description $Object script( STRING location="", STRING backup="", + BOOL automated_backups=1, INT period=60, BOOL ignore_load_failures=1, ENUM { lua, javascript } type="lua", @@ -268,8 +285,12 @@ Description See ``cfg.file()`` for details about undocumented arguments. -$Method BOOL .reload() +$Method BOOL .reload(BOOL force_backup=1) +Arguments + force_backup: if enabled and a backup file has been provided, that file + will be updated upon a successful reload, overriding the default behavior + for automated backups. Description Reloads contents of the file. A ``False`` value is returned on failure. diff --git a/src/vmod_cfg_file.c b/src/vmod_cfg_file.c index a205b9f..5a33ae4 100644 --- a/src/vmod_cfg_file.c +++ b/src/vmod_cfg_file.c @@ -296,9 +296,9 @@ file_check_callback(VRT_CTX, void *ptr, char *contents, unsigned is_backup) } static unsigned -file_check(VRT_CTX, struct vmod_cfg_file *file, unsigned force) +file_check(VRT_CTX, struct vmod_cfg_file *file, unsigned force_load, unsigned force_backup) { - return check_remote(ctx, file->remote, force, &file_check_callback, file); + return check_remote(ctx, file->remote, force_load, force_backup, &file_check_callback, file); } #define SET_STRING(value, field) \ @@ -310,7 +310,7 @@ file_check(VRT_CTX, struct vmod_cfg_file *file, unsigned force) VCL_VOID vmod_file__init( VRT_CTX, struct vmod_cfg_file **file, const char *vcl_name, - VCL_STRING location, VCL_STRING backup, VCL_INT period, + VCL_STRING location, VCL_STRING backup, VCL_BOOL automated_backups, VCL_INT period, VCL_BOOL ignore_load_failures, VCL_INT curl_connection_timeout, VCL_INT curl_transfer_timeout, VCL_BOOL curl_ssl_verify_peer, VCL_BOOL curl_ssl_verify_host, VCL_STRING curl_ssl_cafile, @@ -335,7 +335,8 @@ vmod_file__init( instance->name = strdup(vcl_name); AN(instance->name); instance->remote = new_remote( - location, backup, period, curl_connection_timeout, curl_transfer_timeout, + location, backup, automated_backups, + period, curl_connection_timeout, curl_transfer_timeout, curl_ssl_verify_peer, curl_ssl_verify_host, curl_ssl_cafile, curl_ssl_capath, curl_proxy); SET_STRING(name_delimiter, name_delimiter); @@ -352,7 +353,7 @@ vmod_file__init( AN(instance->state.variables); VRBT_INIT(instance->state.variables); - if (!file_check(ctx, instance, 1) && !ignore_load_failures) { + if (!file_check(ctx, instance, 1, 0) && !ignore_load_failures) { vmod_file__fini(&instance); } } @@ -397,15 +398,15 @@ vmod_file__fini(struct vmod_cfg_file **file) #undef FREE_STRING VCL_BOOL -vmod_file_reload(VRT_CTX, struct vmod_cfg_file *file) +vmod_file_reload(VRT_CTX, struct vmod_cfg_file *file, VCL_BOOL force_backup) { - return file_check(ctx, file, 1); + return file_check(ctx, file, 1, force_backup); } VCL_STRING vmod_file_dump(VRT_CTX, struct vmod_cfg_file *file, VCL_BOOL stream, VCL_STRING prefix) { - file_check(ctx, file, 0); + file_check(ctx, file, 0, 0); AZ(pthread_rwlock_rdlock(&file->state.rwlock)); const char *result = dump_variables(ctx, file->state.variables, stream, prefix); AZ(pthread_rwlock_unlock(&file->state.rwlock)); @@ -415,14 +416,14 @@ vmod_file_dump(VRT_CTX, struct vmod_cfg_file *file, VCL_BOOL stream, VCL_STRING VCL_VOID vmod_file_inspect(VRT_CTX, struct vmod_cfg_file *file) { - file_check(ctx, file, 0); + file_check(ctx, file, 0, 0); inspect_remote(ctx, file->remote); } VCL_BOOL vmod_file_is_set(VRT_CTX, struct vmod_cfg_file *file, VCL_STRING name) { - file_check(ctx, file, 0); + file_check(ctx, file, 0, 0); AZ(pthread_rwlock_rdlock(&file->state.rwlock)); unsigned result = is_set_variable(ctx, file->state.variables, name); AZ(pthread_rwlock_unlock(&file->state.rwlock)); @@ -432,7 +433,7 @@ vmod_file_is_set(VRT_CTX, struct vmod_cfg_file *file, VCL_STRING name) VCL_STRING vmod_file_get(VRT_CTX, struct vmod_cfg_file *file, VCL_STRING name, VCL_STRING fallback) { - file_check(ctx, file, 0); + file_check(ctx, file, 0, 0); AZ(pthread_rwlock_rdlock(&file->state.rwlock)); const char *result = get_variable(ctx, file->state.variables, name, fallback); AZ(pthread_rwlock_unlock(&file->state.rwlock)); diff --git a/src/vmod_cfg_rules.c b/src/vmod_cfg_rules.c index 42bcd48..10027d2 100644 --- a/src/vmod_cfg_rules.c +++ b/src/vmod_cfg_rules.c @@ -221,15 +221,15 @@ rules_check_callback(VRT_CTX, void *ptr, char *contents, unsigned is_backup) } static unsigned -rules_check(VRT_CTX, struct vmod_cfg_rules *rules, unsigned force) +rules_check(VRT_CTX, struct vmod_cfg_rules *rules, unsigned force_load, unsigned force_backup) { - return check_remote(ctx, rules->remote, force, &rules_check_callback, rules); + return check_remote(ctx, rules->remote, force_load, force_backup, &rules_check_callback, rules); } VCL_VOID vmod_rules__init( VRT_CTX, struct vmod_cfg_rules **rules, const char *vcl_name, - VCL_STRING location, VCL_STRING backup, VCL_INT period, + VCL_STRING location, VCL_STRING backup, VCL_BOOL automated_backups, VCL_INT period, VCL_BOOL ignore_load_failures, VCL_INT curl_connection_timeout, VCL_INT curl_transfer_timeout, VCL_BOOL curl_ssl_verify_peer, VCL_BOOL curl_ssl_verify_host, VCL_STRING curl_ssl_cafile, @@ -251,7 +251,8 @@ vmod_rules__init( instance->name = strdup(vcl_name); AN(instance->name); instance->remote = new_remote( - location, backup, period, curl_connection_timeout, curl_transfer_timeout, + location, backup, automated_backups, + period, curl_connection_timeout, curl_transfer_timeout, curl_ssl_verify_peer, curl_ssl_verify_host, curl_ssl_cafile, curl_ssl_capath, curl_proxy); AZ(pthread_rwlock_init(&instance->state.rwlock, NULL)); @@ -259,7 +260,7 @@ vmod_rules__init( AN(instance->state.rules); VTAILQ_INIT(instance->state.rules); - if (!rules_check(ctx, instance, 1) && !ignore_load_failures) { + if (!rules_check(ctx, instance, 1, 0) && !ignore_load_failures) { vmod_rules__fini(&instance); } } @@ -291,15 +292,15 @@ vmod_rules__fini(struct vmod_cfg_rules **rules) } VCL_BOOL -vmod_rules_reload(VRT_CTX, struct vmod_cfg_rules *rules) +vmod_rules_reload(VRT_CTX, struct vmod_cfg_rules *rules, VCL_BOOL force_backup) { - return rules_check(ctx, rules, 1); + return rules_check(ctx, rules, 1, force_backup); } VCL_VOID vmod_rules_inspect(VRT_CTX, struct vmod_cfg_rules *rules) { - rules_check(ctx, rules, 0); + rules_check(ctx, rules, 0, 0); inspect_remote(ctx, rules->remote); } @@ -309,7 +310,7 @@ vmod_rules_get(VRT_CTX, struct vmod_cfg_rules *rules, VCL_STRING value, VCL_STRI AN(ctx->ws); const char *result = fallback; - rules_check(ctx, rules, 0); + rules_check(ctx, rules, 0, 0); AZ(pthread_rwlock_rdlock(&rules->state.rwlock)); rule_t *irule; diff --git a/src/vmod_cfg_script.c b/src/vmod_cfg_script.c index de08102..fba32ca 100644 --- a/src/vmod_cfg_script.c +++ b/src/vmod_cfg_script.c @@ -57,10 +57,10 @@ script_check_callback(VRT_CTX, void *ptr, char *contents, unsigned is_backup) } static unsigned -script_check(VRT_CTX, struct vmod_cfg_script *script, unsigned force) +script_check(VRT_CTX, struct vmod_cfg_script *script, unsigned force_load, unsigned force_backup) { if (script->remote != NULL) { - return check_remote(ctx, script->remote, force, &script_check_callback, script); + return check_remote(ctx, script->remote, force_load, force_backup, &script_check_callback, script); } else { return 1; } @@ -69,7 +69,7 @@ script_check(VRT_CTX, struct vmod_cfg_script *script, unsigned force) VCL_VOID vmod_script__init( VRT_CTX, struct vmod_cfg_script **script, const char *vcl_name, - VCL_STRING location, VCL_STRING backup, VCL_INT period, + VCL_STRING location, VCL_STRING backup, VCL_BOOL automated_backups, VCL_INT period, VCL_BOOL ignore_load_failures, VCL_ENUM type, VCL_INT max_engines, VCL_INT max_cycles, VCL_INT min_gc_cycles, VCL_BOOL enable_sandboxing, VCL_INT lua_gc_step_size, VCL_BOOL lua_remove_loadfile_function, VCL_BOOL lua_remove_dotfile_function, @@ -99,7 +99,8 @@ vmod_script__init( AN(instance->name); if ((location != NULL) && (strlen(location) > 0)) { instance->remote = new_remote( - location, backup, period, curl_connection_timeout, curl_transfer_timeout, + location, backup, automated_backups, + period, curl_connection_timeout, curl_transfer_timeout, curl_ssl_verify_peer, curl_ssl_verify_host, curl_ssl_cafile, curl_ssl_capath, curl_proxy); } else { @@ -145,7 +146,7 @@ vmod_script__init( VRBT_INIT(&instance->state.variables.list); memset(&instance->state.stats, 0, sizeof(instance->state.stats)); - if (!script_check(ctx, instance, 1) && !ignore_load_failures) { + if (!script_check(ctx, instance, 1, 0) && !ignore_load_failures) { vmod_script__fini(&instance); } } @@ -217,9 +218,9 @@ vmod_script__fini(struct vmod_cfg_script **script) } VCL_BOOL -vmod_script_reload(VRT_CTX, struct vmod_cfg_script *script) +vmod_script_reload(VRT_CTX, struct vmod_cfg_script *script, VCL_BOOL force_backup) { - return script_check(ctx, script, 1); + return script_check(ctx, script, 1, force_backup); } VCL_VOID @@ -236,7 +237,7 @@ vmod_script_inspect( AZ(VSB_cat(vsb, state->execution.code)); } } else if (script->remote != NULL) { - script_check(ctx, script, 0); + script_check(ctx, script, 0, 0); inspect_remote(ctx, script->remote); } }