1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Merge pull request #34198 from AdrianVovk/updatectl-bugfixes

updatectl: Bugfixes
This commit is contained in:
Yu Watanabe 2024-08-31 15:20:15 +09:00 committed by GitHub
commit 6434d0bbf7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 72 additions and 34 deletions

View File

@ -45,7 +45,7 @@ static const char* arg_format = NULL;
static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
static ImageClass arg_image_class = _IMAGE_CLASS_INVALID;
#define PROGRESS_PREFIX "Total: "
#define PROGRESS_PREFIX "Total:"
static int settle_image_class(void) {

View File

@ -153,5 +153,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_REBALANCE_NOT_NEEDED, EALREADY),
SD_BUS_ERROR_MAP(BUS_ERROR_HOME_NOT_REFERENCED, EBADR),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_UPDATE_CANDIDATE, EALREADY),
SD_BUS_ERROR_MAP_END
};

View File

@ -158,4 +158,6 @@
#define BUS_ERROR_REBALANCE_NOT_NEEDED "org.freedesktop.home1.RebalanceNotNeeded"
#define BUS_ERROR_HOME_NOT_REFERENCED "org.freedesktop.home1.HomeNotReferenced"
#define BUS_ERROR_NO_UPDATE_CANDIDATE "org.freedesktop.sysupdate1.NoCandidate"
BUS_ERROR_MAP_ELF_USE(bus_common_errors);

View File

@ -4553,7 +4553,7 @@ static int progress_bytes(uint64_t n_bytes, void *userdata) {
p->copy_blocks_done += n_bytes;
if (asprintf(&s, "%s %s %s %s/%s ",
if (asprintf(&s, "%s %s %s %s/%s",
strna(p->copy_blocks_path),
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
strna(p->definition_path),

View File

@ -460,21 +460,16 @@ bool shall_tint_background(void) {
return cache != 0;
}
void draw_progress_bar(const char *prefix, double percentage) {
/* We are going output a bunch of small strings that shall appear as a single line to STDERR which is
* unbuffered by default. Let's temporarily turn on full buffering, so that this is passed to the tty
* as a single buffer, to make things more efficient. */
char buffer[LONG_LINE_MAX];
setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
void draw_progress_bar_unbuffered(const char *prefix, double percentage) {
fputc('\r', stderr);
if (prefix)
if (prefix) {
fputs(prefix, stderr);
fputc(' ', stderr);
}
if (!terminal_is_dumb()) {
size_t cols = columns();
size_t prefix_width = utf8_console_width(prefix);
size_t prefix_width = utf8_console_width(prefix) + 1 /* space */;
size_t length = cols > prefix_width + 6 ? cols - prefix_width - 6 : 0;
if (length > 5 && percentage >= 0.0 && percentage <= 100.0) {
@ -518,6 +513,33 @@ void draw_progress_bar(const char *prefix, double percentage) {
fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
}
void clear_progress_bar_unbuffered(const char *prefix) {
fputc('\r', stderr);
if (terminal_is_dumb())
fputs(strrepa(" ",
prefix ? utf8_console_width(prefix) + 5 : /* %3.0f%% (4 chars) + space */
LESS_BY(columns(), 1U)),
stderr);
else
fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
}
void draw_progress_bar(const char *prefix, double percentage) {
/* We are going output a bunch of small strings that shall appear as a single line to STDERR which is
* unbuffered by default. Let's temporarily turn on full buffering, so that this is passed to the tty
* as a single buffer, to make things more efficient. */
char buffer[LONG_LINE_MAX];
setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
draw_progress_bar_unbuffered(prefix, percentage);
fflush(stderr);
/* Disable buffering again */
@ -525,23 +547,12 @@ void draw_progress_bar(const char *prefix, double percentage) {
}
void clear_progress_bar(const char *prefix) {
char buffer[LONG_LINE_MAX];
setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
fputc('\r', stderr);
clear_progress_bar_unbuffered(prefix);
if (terminal_is_dumb())
fputs(strrepa(" ",
prefix ? utf8_console_width(prefix) + 4 :
LESS_BY(columns(), 1U)), /* 4: %3.0f%% */
stderr);
else
fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
fflush(stderr);
/* Disable buffering again */
setvbuf(stderr, NULL, _IONBF, 0);
}

View File

@ -55,3 +55,5 @@ bool shall_tint_background(void);
void draw_progress_bar(const char *prefix, double percentage);
void clear_progress_bar(const char *prefix);
void draw_progress_bar_unbuffered(const char *prefix, double percentage);
void clear_progress_bar_unbuffered(const char *prefix);

View File

@ -4,6 +4,7 @@
#include "sd-json.h"
#include "build-path.h"
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-get-properties.h"
#include "bus-label.h"
@ -1044,8 +1045,8 @@ static int target_method_update_finished_early(
/* Called when job finishes w/ a successful exit code, but before any work begins.
* This happens when there is no candidate (i.e. we're already up-to-date), or
* specified update is already installed. */
return sd_bus_error_setf(error, "org.freedesktop.sysupdate1.NoCandidate",
"Job exited successfully with no work to do, assume already updated");
return sd_bus_error_setf(error, BUS_ERROR_NO_UPDATE_CANDIDATE,
"Job exited successfully with no work to do, assume already updated");
}
static int target_method_update_detach(sd_bus_message *msg, const Job *j) {

View File

@ -13,6 +13,7 @@
#include "bus-map-properties.h"
#include "bus-util.h"
#include "errno-list.h"
#include "fileio.h"
#include "format-table.h"
#include "json-util.h"
#include "main-func.h"
@ -775,6 +776,7 @@ static int verb_check(int argc, char **argv, void *userdata) {
}
#define UPDATE_PROGRESS_FAILED INT_MIN
#define UPDATE_PROGRESS_DONE INT_MAX
/* Make sure it doesn't overlap w/ errno values */
assert_cc(UPDATE_PROGRESS_FAILED < -ERRNO_MAX);
@ -794,6 +796,11 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
if (n == 0)
return 0;
/* We're outputting lots of small strings to STDERR, which is unbuffered by default. So let's turn
* on full buffering, so we pass this all to the TTY in one go, to make things more efficient */
char buffer[LONG_LINE_MAX];
setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
if (!terminal_is_dumb()) {
for (size_t i = 0; i <= n; i++)
fputs("\n", stderr); /* Possibly scroll the terminal to make room (including total)*/
@ -808,24 +815,36 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
int progress = PTR_TO_INT(p);
if (progress == UPDATE_PROGRESS_FAILED) {
fprintf(stderr, "%s %s\n", RED_CROSS_MARK(), target);
clear_progress_bar_unbuffered(target);
fprintf(stderr, "%s: %s Unknown failure\n", target, RED_CROSS_MARK());
total += 100;
} else if (progress == -EALREADY) {
fprintf(stderr, "%s %s (Already up-to-date)\n", GREEN_CHECK_MARK(), target);
clear_progress_bar_unbuffered(target);
fprintf(stderr, "%s: %s Already up-to-date\n", target, GREEN_CHECK_MARK());
n--; /* Don't consider this target in the total */
} else if (progress < 0) {
fprintf(stderr, "%s %s (%s)\n", RED_CROSS_MARK(), target, STRERROR(progress));
clear_progress_bar_unbuffered(target);
fprintf(stderr, "%s: %s %s\n", target, RED_CROSS_MARK(), STRERROR(progress));
total += 100;
} else if (progress == UPDATE_PROGRESS_DONE) {
clear_progress_bar_unbuffered(target);
fprintf(stderr, "%s: %s Done\n", target, GREEN_CHECK_MARK());
total += 100;
} else {
draw_progress_bar(target, progress);
draw_progress_bar_unbuffered(target, progress);
fputs("\n", stderr);
total += progress;
}
}
if (n > 1) {
draw_progress_bar("TOTAL", (double) total / n);
fputs("\n", stderr);
if (exiting)
clear_progress_bar_unbuffered(target);
else {
draw_progress_bar_unbuffered("Total", (double) total / n);
if (terminal_is_dumb())
fputs("\n", stderr);
}
}
if (!terminal_is_dumb()) {
@ -837,6 +856,7 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
fputs("------\n", stderr);
fflush(stderr);
setvbuf(stderr, NULL, _IONBF, 0); /* Disable buffering again */
return 0;
}
@ -895,7 +915,7 @@ static int update_finished(sd_bus_message *m, void *userdata, sd_bus_error *erro
}
if (status == 0) /* success */
status = 100;
status = UPDATE_PROGRESS_DONE;
else if (status > 0) /* exit status without errno */
status = UPDATE_PROGRESS_FAILED; /* i.e. EXIT_FAILURE */
/* else errno */

View File

@ -4,7 +4,7 @@
#include "random-util.h"
#include "tests.h"
#define PROGRESS_PREFIX "test: "
#define PROGRESS_PREFIX "test:"
TEST(progress_bar) {