Skip to content

Client, Manager, API, docker_wrapper: support network access from apps - #7084

Merged
AenBleidd merged 28 commits into
masterfrom
dpa_app_network
May 22, 2026
Merged

Client, Manager, API, docker_wrapper: support network access from apps#7084
AenBleidd merged 28 commits into
masterfrom
dpa_app_network

Conversation

@davidpanderson

@davidpanderson davidpanderson commented May 20, 2026

Copy link
Copy Markdown
Contributor

The goal of this PR is to allow apps that do network communication
to work properly in the presence of network outages and suspension.
With these changes:

  • If a job that needs network (such as a docker job) runs while
    the network is disconnected, it figures this out, tells the client,
    and the user is shown a notice suggesting that they reconnect.

  • If such a job needs network and network access is suspended by the user
    (via time-of-day prefs or the 'suspend network' command)
    it sees this, tells the client that it needs to communicate,
    and the user is shown a notice suggesting that they unsuspend.

This requires some logic in apps; this PR adds this to docker_wrapper.

This is described here:
https://github.com/BOINC/boinc/wiki/Apps-that-do-network-communication

Note: in ~2004 there was an unsuccessful effort to run Folding@home
as a BOINC app, and we added logic where the client is responsible
for knowing whether a connection exists, and it notifies the app.
This PR removes this logic; in the new design it's up to the app
to detect the absence of a connection.

Remove an API where the app tells the client how much data it transferred.
This info isn't used, and in the case of Docker the app doesn't know
how much data was transferred.


Summary by cubic

Apps can now tell the client when they’re waiting for Internet, and the UI shows clear notices and a “Waiting for network” task state. docker_wrapper detects outages, retries image builds until connectivity returns, and surfaces better errors.

  • New Features

    • API: added boinc_waiting_for_network(bool); app status always includes <want_network>; removed boinc_need_network(), boinc_network_poll(), boinc_network_done(), boinc_network_usage().
    • Client/Manager: shows notices when tasks need Internet or network is suspended; tracks connection vs. suspension notices separately and clears them on reconnection or when no tasks want network; GUI shows “Waiting for network”; GUI RPC exposes want_network; don’t strip tags in notices; removed unused bytes sent/received tracking.
    • docker_wrapper: waits for a heartbeat before checking suspend state; detects disconnect/suspension, sets want_network, and retries image builds until network returns; checks connectivity via ping to berkeley.edu; honors exit/abort while waiting; prints network-related logs only with verbose flags; shows command output on errors; uses --retry 0 for Podman builds; on Windows, copies the command string before CreateProcess.
    • Work fetch: piggyback requests no longer skip higher‑priority projects that previously returned no jobs.
    • Lib: run_command() returns non‑zero on command failures and (on Windows) still returns command output; added network_connected().
  • Migration

    • Replace removed APIs with boinc_waiting_for_network(bool).
    • Apps should detect connectivity and call boinc_waiting_for_network(true/false); include <want_network> in status updates.

Written for commit cbe058e. Summary will update on new commits. Review in cubic

This goal of this PR is to allow apps that do network communication
to work properly in the presence of network outage and suspension.

- If a job that needs network (such as a docker job) runs while
the network is disconnected, it figures this out, tells the client,
and the user is shown a notice suggesting that they reconnect.

- If such a job needs network and network access is suspended by the user
(via time-of-day prefs or the 'suspend network' command)
it sees this, tells the client that it needs to communicate,
and the user is shown a notice suggesting that they unsuspend.

This requires some logic in apps; this PR adds this to docker_wrapper.

This is described here:
https://github.com/BOINC/boinc/wiki/Apps-that-do-network-communication

Note: in ~2004 there was an unsuccessful effort to run Folding@home
as a BOINC app, and we added logic where the client is responsible
for knowing whether a connection exists, and it notifies the app.
This PR removes this logic; in the new design it's up to the app
to detect the absence of a connection.

Remove an API where the app tells the client how much data it transferred.
This info isn't used, and in the case of Docker the app doesn't know
how much data was transferred.
…ed. WTF?

So let's try running ping as a separate command instead
- the ping you get from cmd (or program) is different from the one in powershell
- the -c option (to do only 1 ping) gives a permissions error
- the output is completely different from Unix ping
Copilot AI review requested due to automatic review settings May 20, 2026 07:31

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 25 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread samples/docker_wrapper/docker_wrapper.cpp Outdated
Comment thread lib/network.cpp Outdated
Comment thread client/app_control.cpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the BOINC client/app interface and UI to support applications that require network access during execution, particularly handling (1) physical disconnection and (2) user-suspended network access. It also removes legacy app→client network-usage accounting and the older client→app “network available” signaling design.

Changes:

  • Add an app-driven “waiting for network” signal (boinc_waiting_for_network() / <want_network>) and expose it via GUI RPC/Manager UI (“Waiting for network”).
  • Update client network-status logic and notices to reflect tasks needing network, and remove legacy network-availability signaling and byte accounting.
  • Extend docker_wrapper to detect network unavailability/suspension during image build and to report “waiting for network”.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
samples/example_app/uc2.cpp Removes the sample’s deprecated boinc_network_usage() option.
samples/docker_wrapper/docker_wrapper.cpp Adds “waiting for network” handling during image build; refactors output parsing helpers.
samples/docker_wrapper/checkpoint_notes Moves checkpoint/restart notes out of the C++ source.
lib/util.h Updates run_command() signature to accept const char*.
lib/util.cpp Updates run_command() signature definition accordingly.
lib/network.h Adds network_connected() declaration and centralizes addr_len() helper.
lib/network.cpp Implements network_connected() using ping.
lib/gui_rpc_client.h Adds RESULT::want_network field for GUI RPC consumers.
lib/gui_rpc_client.cpp Removes duplicate addr_len() helper (now in lib/network.h).
lib/gui_rpc_client_ops.cpp Parses/clears want_network in GUI RPC result parsing.
clientgui/MainDocument.cpp Shows “Waiting for network” in task status text.
client/result.h Removes stored per-task final bytes sent/received fields.
client/result.cpp Removes read/write of per-task final bytes sent/received in state output.
client/net_stats.h Replaces show_ref_message with network_notice_active gating.
client/net_stats.cpp Uses new some_task_wants_network() and adjusts notice clearing paths.
client/gui_http.h Clarifies GUI_HTTP responsibilities in comments.
client/cs_notice.cpp Removes additional network-related notices when clearing network messages.
client/client_state.h Updates/expands network-related notice strings.
client/client_msgs.cpp Adjusts msg_printf() to mark messages as non-HTML.
client/app.h Removes legacy network byte accounting; redefines want_network semantics; renames task-set query.
client/app.cpp Removes active-task network byte output; adds <want_network/> to GUI output; renames task-set query impl.
client/app_start.cpp Removes resetting of removed per-episode byte counters.
client/app_control.cpp Removes parsing of byte counters; adds notice logic for <want_network>.
api/boinc_api.h Replaces legacy network APIs with boinc_waiting_for_network(bool).
api/boinc_api.cpp Implements boinc_waiting_for_network() and includes <want_network> in app-status messages.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread client/app_control.cpp Outdated
Comment on lines +1366 to +1445
@@ -1420,23 +1408,7 @@ bool ACTIVE_TASK::get_app_status_msg() {
parse_double(msg_buf, "<fpops_cumulative>", result->fpops_cumulative);
parse_double(msg_buf, "<intops_per_cpu_sec>", result->intops_per_cpu_sec);
parse_double(msg_buf, "<intops_cumulative>", result->intops_cumulative);
if (parse_double(msg_buf, "<bytes_sent>", dtemp)) {
if (dtemp > bytes_sent_episode) {
double nbytes = dtemp - bytes_sent_episode;
daily_xfer_history.add(nbytes, true);
bytes_sent += nbytes;
}
bytes_sent_episode = dtemp;
}
if (parse_double(msg_buf, "<bytes_received>", dtemp)) {
if (dtemp > bytes_received_episode) {
double nbytes = dtemp - bytes_received_episode;
daily_xfer_history.add(nbytes, false);
bytes_received += nbytes;
}
bytes_received_episode = dtemp;
}
parse_int(msg_buf, "<want_network>", want_network);
parse_int(msg_buf, "<want_network>", new_want_network);
if (parse_int(msg_buf, "<other_pid>", other_pid)) {
// for now, we handle only one of these
other_pids.clear();
@@ -1445,6 +1417,32 @@ bool ACTIVE_TASK::get_app_status_msg() {
if (parse_int(msg_buf, "<sporadic_ac>", i)) {
sporadic_ac_state = (SPORADIC_AC_STATE)i;
}

switch (new_want_network) {
case 0:
if (want_network) {
// app was waiting for network, now isn't.
if (net_status.network_notice_active) {
notices.remove_notices(NULL, REMOVE_NETWORK_MSG);
net_status.network_notice_active = false;
}
want_network = 0;
}
break;
case 1:
if (!want_network) {
if (!net_status.network_notice_active) {
if (gstate.network_suspended) {
msg_printf(0, MSG_USER_ALERT, APP_NETWORK_SUSPENDED_MSG);
} else {
msg_printf(0, MSG_USER_ALERT, APP_NEED_NETWORK_MSG);
}
net_status.network_notice_active = true;
}
want_network = 1;
}
break;
}
Comment thread lib/network.cpp Outdated
fprintf(stderr, "%s failed: %d\n", cmd, retval);
}
// ping exits nonzero on failure
return 0;
vector<string> out;
snprintf(cmd, sizeof(cmd), "build \"%s\" -t %s -f %s %s",
int retval;
snprintf(cmd, sizeof(cmd), "build \"%s\" --retry 0 -t %s -f %s %s",
Copilot AI review requested due to automatic review settings May 20, 2026 18:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

client/app_control.cpp:1370

  • new_want_network is initialized to -1 and want_network is no longer reset to 0 before parsing. Because the API only emits <want_network> when true, the tag will be absent when the app clears the condition, leaving new_want_network == -1 and preventing want_network from ever being cleared. Treat a missing <want_network> tag as 0 (e.g., initialize to 0 / restore reset-to-0 behavior) or have the API always send an explicit 0/1 value.
    int new_want_network = -1;
    current_cpu_time = checkpoint_cpu_time = 0.0;
    if (parse_double(msg_buf, "<fraction_done>", fd)) {
        // fraction_done will be reported as zero
        // until the app's first call to boinc_fraction_done().

Comment thread lib/network.cpp Outdated
fprintf(stderr, "%s failed: %d\n", cmd, retval);
}
// ping exits nonzero on failure
return 0;
Comment thread lib/network.cpp Outdated
//
int network_connected() {
#ifdef _WIN32
const char* cmd = "ping google.com -n 1";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidpanderson, can we have reference site configurable via cc_config.xml?
I personally don't care but some might not want to send any statistics to any corporate website (even via ping request).
It's ok to fallback to google.com if there is no site configured, but it would be nice to give users a choice.
See this ticket for reference.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this (using the test_network_url that we already have in nvc_config.xml)

Comment thread lib/network.cpp Outdated
fprintf(stderr, "%s failed: %d\n", cmd, retval);
}
// ping exits nonzero on failure
return 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidpanderson, please validate this logic. I believe you should return retval here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Cubic caught that too.

Copilot AI review requested due to automatic review settings May 20, 2026 19:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

lib/util.cpp:318

  • Changing run_command() to take const char* is unsafe on Windows: CreateProcess() requires a writable command-line buffer (it may modify it), but the implementation casts away const ((LPTSTR)cmd). Callers can now legally pass string literals (e.g. network_connected() does), which can lead to undefined behavior/crashes. Either keep the parameter as char* (enforcing mutability) or make an internal writable copy before calling CreateProcess().
int run_command(const char *cmd, vector<string> &out) {
    out.clear();
#ifdef _WIN32
    HANDLE pipe_read, pipe_write;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    memset(&si, 0, sizeof(si));
    memset(&pi, 0, sizeof(pi));
    memset(&sa, 0, sizeof(sa));

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&pipe_read, &pipe_write, &sa, 0)) return -1;
    SetHandleInformation(pipe_read, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_FORCEOFFFEEDBACK | STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = pipe_write;
    si.hStdError = pipe_write;
    si.hStdInput = NULL;

    if (!CreateProcess(
        NULL,
        (LPTSTR)cmd,
        NULL,

lib/util.cpp:376

  • network_connected() relies on run_command() returning nonzero when ping fails, but on Unix run_command() ignores the command’s exit status (it calls pclose(fp) but doesn’t check its return value). As a result, network_connected() will almost always report “connected” on Unix even when ping fails. Consider checking the pclose() status (e.g. WEXITSTATUS) and returning an error when the command exits nonzero.
int run_command(const char *cmd, vector<string> &out) {
    out.clear();
#ifdef _WIN32
    HANDLE pipe_read, pipe_write;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    memset(&si, 0, sizeof(si));
    memset(&pi, 0, sizeof(pi));
    memset(&sa, 0, sizeof(sa));

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&pipe_read, &pipe_write, &sa, 0)) return -1;
    SetHandleInformation(pipe_read, HANDLE_FLAG_INHERIT, 0);

    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_FORCEOFFFEEDBACK | STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = pipe_write;
    si.hStdError = pipe_write;
    si.hStdInput = NULL;

    if (!CreateProcess(
        NULL,
        (LPTSTR)cmd,
        NULL,
        NULL,
        TRUE,   // inherit handles
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &si,
        &pi
    )) {
        return -1;
    }

    // wait for command to finish
    //
    WaitForSingleObject(pi.hProcess, INFINITE);

    unsigned long exit_code;
    GetExitCodeProcess(pi.hProcess, &exit_code);
    if (exit_code) return -1;

    DWORD count, nread;
    PeekNamedPipe(pipe_read, NULL, NULL, NULL, &count, NULL);
    if (count == 0) {
        return 0;
    }
    char* buf = (char*)malloc(count+1);
    if (!ReadFile(pipe_read, buf, count, &nread, NULL)) {
        free(buf);
        return -1;
    }
    buf[nread] = 0;
    char* p = buf;
    while (*p) {
        char* q = strchr(p, '\n');
        if (!q) break;
        out.push_back(string(p, q-p+1));    // include \n
        p = q + 1;
    }
    free(buf);
#else
#ifndef _USING_FCGI_
    char buf[256];
    errno = 0;
    FILE* fp = popen(cmd, "r");
    if (!fp) {
        fprintf(stderr, "popen() failed: %s\n", cmd);
        return ERR_FOPEN;
    }
    while (fgets(buf, 256, fp)) {
        out.push_back(buf);
    }
    pclose(fp);
    if (errno) {
        fprintf(stderr, "popen() failed errno %d: %s\n", errno, cmd);
        return -1;
    }
#endif
#endif
    return 0;

Comment on lines +434 to +467
// if google was previously unreachable, see if that's changed
if (google_unreachable) {
retval = network_connected();
if (retval) {
if (verbose_all()) {
fprintf(stderr,
"google still unreachable (%d); sleeping 10\n", retval
);
}
boinc_sleep(10);
continue;
}
}
retval = docker_conn.command(cmd, out, verbose_std());
if (retval) {
fprintf(stderr, "build command failed: %d\n", retval);
return retval;
}
if (output_has_str(out, "retrying")) {
if (verbose_std()) {
fprintf(stderr, "build cmd output has 'retrying'\n");
}
retval = network_connected();
if (retval == 0) {
// network connection exists but the create operation
// couldn't reach a needed server; error out
if (verbose_std()) {
fprintf(stderr, "... but google is reachable; quitting\n");
}
return -1;
}
if (verbose_std()) {
fprintf(stderr, "google is unreachable (%d); sleeping\n", retval);
}
Comment thread client/app_control.cpp Outdated
Comment on lines +1366 to +1451
@@ -1420,23 +1408,7 @@ bool ACTIVE_TASK::get_app_status_msg() {
parse_double(msg_buf, "<fpops_cumulative>", result->fpops_cumulative);
parse_double(msg_buf, "<intops_per_cpu_sec>", result->intops_per_cpu_sec);
parse_double(msg_buf, "<intops_cumulative>", result->intops_cumulative);
if (parse_double(msg_buf, "<bytes_sent>", dtemp)) {
if (dtemp > bytes_sent_episode) {
double nbytes = dtemp - bytes_sent_episode;
daily_xfer_history.add(nbytes, true);
bytes_sent += nbytes;
}
bytes_sent_episode = dtemp;
}
if (parse_double(msg_buf, "<bytes_received>", dtemp)) {
if (dtemp > bytes_received_episode) {
double nbytes = dtemp - bytes_received_episode;
daily_xfer_history.add(nbytes, false);
bytes_received += nbytes;
}
bytes_received_episode = dtemp;
}
parse_int(msg_buf, "<want_network>", want_network);
parse_int(msg_buf, "<want_network>", new_want_network);
if (parse_int(msg_buf, "<other_pid>", other_pid)) {
// for now, we handle only one of these
other_pids.clear();
@@ -1445,6 +1417,38 @@ bool ACTIVE_TASK::get_app_status_msg() {
if (parse_int(msg_buf, "<sporadic_ac>", i)) {
sporadic_ac_state = (SPORADIC_AC_STATE)i;
}

switch (new_want_network) {
case 0:
// if want_network goes true to false,
// and no tasks now want network, remove notice
//
if (want_network) {
want_network = 0;
if (net_status.network_notice_active) {
if (!gstate.active_tasks.some_task_wants_network()) {
notices.remove_notices(NULL, REMOVE_NETWORK_MSG);
net_status.network_notice_active = false;
}
}
}
break;
case 1:
// if want_network goes from false to true, show notice
//
if (!want_network) {
if (!net_status.network_notice_active) {
if (gstate.network_suspended) {
msg_printf(0, MSG_USER_ALERT, APP_NETWORK_SUSPENDED_MSG);
} else {
msg_printf(0, MSG_USER_ALERT, APP_NEED_NETWORK_MSG);
}
net_status.network_notice_active = true;
}
want_network = 1;
}
break;
}
- nvc_config.xml has an optional 'network test URL'.
    If this is present, pass it to apps via the app_init.xml file
- network_connected() now takes a hostname arg
- docker_wrapper: look for network test URL in APP_INIT_DATA.
    If found convert it to a hostname;
    else use "www.google.com".
    Pass this to network_connected();

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 8 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread samples/docker_wrapper/docker_wrapper.cpp Outdated
Comment thread lib/network.cpp Outdated
Comment thread client/current_version.h Outdated
Copilot AI review requested due to automatic review settings May 20, 2026 21:39
Copilot AI review requested due to automatic review settings May 21, 2026 08:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 6 comments.

Comment thread lib/network.cpp
Comment thread lib/network.cpp Outdated
Comment on lines +362 to +366
// (used w/ google.com to check for network connection)
//
// We used to do this directly, by gethostbyname() and connect().
// But on Windows, gethostbyname() caches negative results,
// so once 'google.com' fails (due to network disconnection)
Comment thread lib/util.cpp
Comment on lines +297 to +301
char cmd2[1024];

// CreateProcess() can modify its cmd arg (WTF???)
// So copy it to a temp buffer
safe_strcpy(cmd2, cmd);
Comment on lines +447 to +451
retval = docker_conn.command(cmd, out, verbose_std());
if (retval) {
fprintf(stderr, "build command failed: %d\n", retval);
return retval;
}
Comment thread client/app_control.cpp
Comment on lines +1424 to +1433
// and no tasks now want network, remove notice
//
if (want_network) {
want_network = 0;
if (net_status.network_notice_active) {
if (!gstate.active_tasks.some_task_wants_network()) {
notices.remove_notices(NULL, REMOVE_NETWORK_MSG);
net_status.network_notice_active = false;
}
}
Comment thread client/net_stats.cpp
Comment on lines 222 to 228
int LOOKUP_WEBSITE_OP::do_rpc(string& url) {
int retval;

if (net_status.show_ref_message) {
msg_printf(0, MSG_INFO,
"Project communication failed: attempting access to reference site"
);
}
msg_printf(0, MSG_INFO,
"Project communication failed: attempting access to reference site"
);
retval = gui_http->do_rpc(this, url.c_str(), LOOKUP_WEBSITE_FILENAME, true);
Copilot AI review requested due to automatic review settings May 21, 2026 21:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 5 comments.

Comment thread lib/network.cpp
Comment on lines +373 to +387
bool network_connected() {
char cmd[256];
snprintf(cmd, sizeof(cmd), "ping %s berkeley.edu",
#ifdef _WIN32
"-n 1"
#else
"-c 1"
#endif
);
vector<string> out;
int retval = run_command(cmd, out);
// ping exits nonzero on failure
if (retval) {
return false;
}
Comment thread lib/util.cpp
Comment on lines +297 to +301
char cmd2[1024];

// CreateProcess() can modify its cmd arg (WTF???)
// So copy it to a temp buffer
safe_strcpy(cmd2, cmd);
Comment on lines 405 to 415
int build_image() {
char cmd[256];
vector<string> out;
snprintf(cmd, sizeof(cmd), "build \"%s\" -t %s -f %s %s",
escaped_cwd, image_name, dockerfile, config.build_args.c_str()
int retval;

snprintf(cmd, sizeof(cmd),
"build \"%s\" %s -t %s -f %s %s",
escaped_cwd,
docker_type == PODMAN?"--retry 0":"",
image_name, dockerfile, config.build_args.c_str()
);
Comment thread client/work_fetch.cpp
Comment on lines +610 to +617
if (p2->sched_req_no_work[i]) {
if (log_flags.work_fetch_debug) {
msg_printf(p, MSG_INFO,
"piggyback: %s doesn't have jobs", p2->project_name
);
}
continue;
}
Comment thread client/app_control.cpp
Comment on lines +1421 to +1451
switch (new_want_network) {
case 0:
// if want_network goes true to false,
// and no tasks now want network, remove notice
//
if (want_network) {
want_network = 0;
if (net_status.network_notice_active) {
if (!gstate.active_tasks.some_task_wants_network()) {
notices.remove_notices(NULL, REMOVE_NETWORK_MSG);
net_status.network_notice_active = false;
}
}
}
break;
case 1:
// if want_network goes from false to true, show notice
//
if (!want_network) {
if (!net_status.network_notice_active) {
if (gstate.network_suspended) {
msg_printf(0, MSG_USER_ALERT, APP_NETWORK_SUSPENDED_MSG);
} else {
msg_printf(0, MSG_USER_ALERT, APP_NEED_NETWORK_MSG);
}
net_status.network_notice_active = true;
}
want_network = 1;
}
break;
}
Copilot AI review requested due to automatic review settings May 21, 2026 22:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 8 comments.

Comment thread lib/network.cpp
Comment on lines +373 to +389
bool network_connected() {
char cmd[256];
snprintf(cmd, sizeof(cmd), "ping %s berkeley.edu",
#ifdef _WIN32
"-n 1"
#else
"-c 1"
#endif
);
vector<string> out;
int retval = run_command(cmd, out);
// ping exits nonzero on failure
if (retval) {
return false;
}
return true;
}
Comment thread client/app_control.cpp Outdated
Comment on lines +1439 to +1446
if (!want_network) {
if (!net_status.network_notice_active) {
if (gstate.network_suspended) {
msg_printf(0, MSG_USER_ALERT, APP_NETWORK_SUSPENDED_MSG);
} else {
msg_printf(0, MSG_USER_ALERT, APP_NEED_NETWORK_MSG);
}
net_status.network_notice_active = true;
Comment thread client/net_stats.cpp
Comment on lines 225 to 257
@@ -253,11 +251,9 @@ void LOOKUP_WEBSITE_OP::handle_reply(int http_op_retval) {
net_status.last_comm_time = 0;
show_fail_msg();
} else {
if (net_status.show_ref_message) {
msg_printf(0, MSG_INFO,
"Internet access OK - project servers may be temporarily down."
);
}
msg_printf(0, MSG_INFO,
"Internet access OK - project servers may be temporarily down."
);
}
Comment thread client/work_fetch.cpp
Comment on lines +610 to +617
if (p2->sched_req_no_work[i]) {
if (log_flags.work_fetch_debug) {
msg_printf(p, MSG_INFO,
"piggyback: %s doesn't have jobs", p2->project_name
);
}
continue;
}
Comment thread client/client_state.h
Comment on lines +720 to +722
#define NEED_NETWORK_MSG _("BOINC can't access Internet - check network connection")
#define APP_NEED_NETWORK_MSG _("Tasks can't access Internet - check network connection")
#define APP_NETWORK_SUSPENDED_MSG _("Tasks need Internet access - consider unsuspending network")
Comment thread api/boinc_api.cpp Outdated
Comment on lines 192 to 194
static int want_network = 0;
static int have_network = 1;
static double bytes_sent = 0;
static double bytes_received = 0;
Comment thread lib/util.cpp
Comment on lines +297 to 302
char cmd2[1024];

// CreateProcess() can modify its cmd arg (WTF???)
// So copy it to a temp buffer
safe_strcpy(cmd2, cmd);

Comment thread lib/util.cpp
Comment on lines 321 to 326
if (!CreateProcess(
NULL,
(LPTSTR)cmd,
(LPTSTR)cmd2,
NULL,
NULL,
TRUE, // inherit handles
client: keep track of suspend/connection notices separately
run_command() Win: return output even if command fails
@github-project-automation github-project-automation Bot moved this to In progress in Client/Manager May 22, 2026
@AenBleidd AenBleidd added this to the Client/Manager 8.2.14 milestone May 22, 2026
@AenBleidd
AenBleidd merged commit 4cceee3 into master May 22, 2026
275 of 276 checks passed
@AenBleidd
AenBleidd deleted the dpa_app_network branch May 22, 2026 06:39
@github-project-automation github-project-automation Bot moved this from In progress to Merged in Client/Manager May 22, 2026
@AenBleidd AenBleidd linked an issue Jun 11, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

If can't build Docker image because disconnected, handle correctly

3 participants