Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg: Implement message type "before" to display a pre-(install|upgrade) message. #1910

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/pkg-keywords.5
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ Valid information by entry in the array are:
.Bl -tag
.It Cm message Ar string
actual message to be shown to the users.
.It Cm type Op Ar upgrade | Ar remove | Ar install
defines in which contect the message should be shown to the users.
If not set, the message will always be printed
.It Cm type Op Ar upgrade | Ar remove | Ar install | Ar before
defines in which context the message should be shown to the users.
If not set, the message will always be printed, when set to
.Va before ,
message will be printed before install or upgrade and
.Xr pkg 8
will sleep for 10 seconds.
.El
.El
.Sh SEE ALSO
Expand Down
21 changes: 21 additions & 0 deletions libpkg/pkg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,12 @@ pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
msg->type = PKG_MESSAGE_REMOVE;
else if (strcasecmp(ucl_object_tostring(elt), "upgrade") == 0)
msg->type = PKG_MESSAGE_UPGRADE;
else if (strcasecmp(ucl_object_tostring(elt), "pre-install") == 0)
msg->type = PKG_MESSAGE_PREINSTALL;
else if (strcasecmp(ucl_object_tostring(elt), "pre-remove") == 0)
msg->type = PKG_MESSAGE_PREREMOVE;
else if (strcasecmp(ucl_object_tostring(elt), "pre-upgrade") == 0)
msg->type = PKG_MESSAGE_PREUPGRADE;
else
pkg_emit_error("Unknown message type,"
" message will always be printed");
Expand Down Expand Up @@ -1830,6 +1836,21 @@ pkg_message_to_ucl(const struct pkg *pkg)
ucl_object_fromstring("remove"),
"type", 0, false);
break;
case PKG_MESSAGE_PREINSTALL:
ucl_object_insert_key(obj,
ucl_object_fromstring("pre-install"),
"type", 0, false);
break;
case PKG_MESSAGE_PREUPGRADE:
ucl_object_insert_key(obj,
ucl_object_fromstring("pre-upgrade"),
"type", 0, false);
break;
case PKG_MESSAGE_PREREMOVE:
ucl_object_insert_key(obj,
ucl_object_fromstring("pre-remove"),
"type", 0, false);
break;
}
if (msg->maximum_version) {
ucl_object_insert_key(obj,
Expand Down
104 changes: 62 additions & 42 deletions libpkg/pkg_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,65 @@ pkg_rollback_cb(void *data)
pkg_rollback_pkg((struct pkg *)data);
}

static void
pkg_print_message(struct pkg *pkg, struct pkg *local, struct pkg *remote,
pkg_printmessage_t prepost)
{
xstring *message = NULL;
struct pkg_message *msg;
const char *msgstr;

LL_FOREACH(pkg->message, msg) {
msgstr = NULL;
/* Print "always"-type only post-operation */
if ((msg->type == PKG_MESSAGE_ALWAYS) &&
(prepost == PKG_PRINTMESSAGE_POST)) {
msgstr = msg->str;
} else if (local != NULL &&
msg->type == ((prepost == PKG_PRINTMESSAGE_POST) ?
PKG_MESSAGE_UPGRADE : PKG_MESSAGE_PREUPGRADE)) {
if (msg->maximum_version == NULL &&
msg->minimum_version == NULL) {
msgstr = msg->str;
} else if (msg->maximum_version == NULL) {
if (pkg_version_cmp(local->version, msg->minimum_version) == 1) {
msgstr = msg->str;
}
} else if (msg->minimum_version == NULL) {
if (pkg_version_cmp(local->version, msg->maximum_version) == -1) {
msgstr = msg->str;
}
} else if (pkg_version_cmp(local->version, msg->maximum_version) == -1 &&
pkg_version_cmp(local->version, msg->minimum_version) == 1) {
msgstr = msg->str;
}
} else if (local == NULL &&
msg->type == (
(prepost == PKG_PRINTMESSAGE_POST ?
PKG_MESSAGE_INSTALL : PKG_MESSAGE_PREINSTALL))) {
msgstr = msg->str;
}
if (msgstr != NULL) {
if (message == NULL) {
message = xstring_new();
pkg_fprintf(message->fp, "=====\nMessage from "
"%n-%v:\n\n", pkg, pkg);
}
fprintf(message->fp, "--\n%s\n", msgstr);
}
}
if (pkg->message != NULL && message != NULL) {
fflush(message->fp);
if (prepost == PKG_PRINTMESSAGE_POST)
pkg_emit_message(message->buf);
else {
pkg_emit_notice("%s", message->buf);
sleep(10);
}
xstring_free(message);
}
}

static int
pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
struct pkg_manifest_key *keys, const char *reloc, struct pkg *remote,
Expand All @@ -1037,10 +1096,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
struct archive *a;
struct archive_entry *ae;
struct pkg *pkg = NULL;
xstring *message = NULL;
struct pkg_message *msg;
struct pkg_file *f;
const char *msgstr;
bool extract = true;
int retcode = EPKG_OK;
int ret;
Expand Down Expand Up @@ -1130,6 +1186,8 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
if (retcode != EPKG_OK)
goto cleanup;

pkg_print_message(pkg, local, remote, PKG_PRINTMESSAGE_PRE);

/*
* Execute pre-install scripts
*/
Expand Down Expand Up @@ -1204,45 +1262,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
pkg_emit_install_finished(pkg, local);
}

LL_FOREACH(pkg->message, msg) {
msgstr = NULL;
if (msg->type == PKG_MESSAGE_ALWAYS) {
msgstr = msg->str;
} else if (local != NULL &&
msg->type == PKG_MESSAGE_UPGRADE) {
if (msg->maximum_version == NULL &&
msg->minimum_version == NULL) {
msgstr = msg->str;
} else if (msg->maximum_version == NULL) {
if (pkg_version_cmp(local->version, msg->minimum_version) == 1) {
msgstr = msg->str;
}
} else if (msg->minimum_version == NULL) {
if (pkg_version_cmp(local->version, msg->maximum_version) == -1) {
msgstr = msg->str;
}
} else if (pkg_version_cmp(local->version, msg->maximum_version) == -1 &&
pkg_version_cmp(local->version, msg->minimum_version) == 1) {
msgstr = msg->str;
}
} else if (local == NULL &&
msg->type == PKG_MESSAGE_INSTALL) {
msgstr = msg->str;
}
if (msgstr != NULL) {
if (message == NULL) {
message = xstring_new();
pkg_fprintf(message->fp, "=====\nMessage from "
"%n-%v:\n\n", pkg, pkg);
}
fprintf(message->fp, "--\n%s\n", msgstr);
}
}
if (pkg->message != NULL && message != NULL) {
fflush(message->fp);
pkg_emit_message(message->buf);
xstring_free(message);
}
pkg_print_message(pkg, local, remote, PKG_PRINTMESSAGE_POST);

cleanup:
if (a != NULL) {
Expand Down
20 changes: 18 additions & 2 deletions libpkg/pkg_delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
bool handle_rc = false;
const unsigned load_flags = PKG_LOAD_RDEPS|PKG_LOAD_FILES|PKG_LOAD_DIRS|
PKG_LOAD_SCRIPTS|PKG_LOAD_ANNOTATIONS|PKG_LOAD_LUA_SCRIPTS;
bool head = true;

assert(pkg != NULL);
assert(db != NULL);
Expand All @@ -81,6 +80,24 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
return (EPKG_LOCKED);
}

/* Print pre-action message(s), if any */
LL_FOREACH(pkg->message, msg) {
if (msg->type == PKG_MESSAGE_PREREMOVE) {
if (message == NULL) {
message = xstring_new();
pkg_fprintf(message->fp, "Message from "
"%n-%v:\n", pkg, pkg);
}
fprintf(message->fp, "%s\n", msg->str);
}
}
if (pkg->message != NULL && message != NULL) {
fflush(message->fp);
pkg_emit_notice("%s", message->buf);
xstring_free(message);
message = NULL;
}

/*
* stop the different related services if the users do want that
* and that the service is running
Expand Down Expand Up @@ -122,7 +139,6 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
message = xstring_new();
pkg_fprintf(message->fp, "Message from "
"%n-%v:\n", pkg, pkg);
head = false;
}
fprintf(message->fp, "%s\n", msg->str);
}
Expand Down
8 changes: 7 additions & 1 deletion libpkg/pkg_ports.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ keyword_open_schema(void)
" type = object;"
" properties {"
" message = { type = string };"
" type = { enum = [ upgrade, remove, install ] };"
" type = { enum = [ upgrade, remove, install, pre-upgrade, pre-remove, pre-install ] };"
" };"
" required [ message ];"
" };"
Expand Down Expand Up @@ -984,6 +984,12 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
msg->type = PKG_MESSAGE_REMOVE;
else if (strcasecmp(ucl_object_tostring(elt), "upgrade") == 0)
msg->type = PKG_MESSAGE_UPGRADE;
else if (strcasecmp(ucl_object_tostring(elt), "pre-install") == 0)
msg->type = PKG_MESSAGE_PREINSTALL;
else if (strcasecmp(ucl_object_tostring(elt), "pre-remove") == 0)
msg->type = PKG_MESSAGE_PREREMOVE;
else if (strcasecmp(ucl_object_tostring(elt), "pre-upgrade") == 0)
msg->type = PKG_MESSAGE_PREUPGRADE;
}
DL_APPEND(p->pkg->message, msg);
}
Expand Down
9 changes: 9 additions & 0 deletions libpkg/pkg_printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,15 @@ format_message(xstring *buffer, const void *data, struct percent_esc *p)
case PKG_MESSAGE_REMOVE:
fprintf(bufmsg->fp, "On remove:\n");
break;
case PKG_MESSAGE_PREINSTALL:
fprintf(bufmsg->fp, "Before install:\n");
break;
case PKG_MESSAGE_PREREMOVE:
fprintf(bufmsg->fp, "Before remove:\n");
break;
case PKG_MESSAGE_PREUPGRADE:
fprintf(bufmsg->fp, "Before upgrade:\n");
break;
}
fprintf(bufmsg->fp, "%s\n", msg->str);
}
Expand Down
9 changes: 9 additions & 0 deletions libpkg/private/pkg.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,17 @@ typedef enum {
PKG_MESSAGE_INSTALL,
PKG_MESSAGE_REMOVE,
PKG_MESSAGE_UPGRADE,
PKG_MESSAGE_PREINSTALL,
PKG_MESSAGE_PREREMOVE,
PKG_MESSAGE_PREUPGRADE,
} pkg_message_t;

typedef enum {
PKG_PRINTMESSAGE_ALWAYS = 0,
PKG_PRINTMESSAGE_PRE,
PKG_PRINTMESSAGE_POST,
} pkg_printmessage_t;

struct pkg_message {
char *str;
char *minimum_version;
Expand Down
10 changes: 9 additions & 1 deletion tests/frontend/create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,10 @@ cat << EOF > showmsg.ucl
actions: []
messages: [
{ message: "always" },
{ message: "on upgrade";type = "upgrade" },
{ message: "on upgrade"; type = "upgrade" },
{ message: "on install"; type = "install" },
{ message: "before upgrade"; type = "pre-upgrade" },
{ message: "before install"; type = "pre-install" },
]
EOF
cat << EOF > +DISPLAY
Expand All @@ -579,6 +581,12 @@ on upgrade
On install:
on install

Before upgrade:
before upgrade

Before install:
before install

'
atf_check pkg -o PLIST_KEYWORDS_DIR=. create -m . -r ${TMPDIR} -p test.plist
atf_check -o inline:"${OUTPUT}" pkg info -D -F ./test-1.txz
Expand Down
12 changes: 12 additions & 0 deletions tests/frontend/messages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ comment: "need one"
desc: "also need one"
message: [
{ message: "Always print" },
{ message: "Before remove", type: pre-remove },
{ message: "Before install", type: pre-install },
{ message: "Before upgrade", type: pre-upgrade },
{ message: "package being removed", type: remove },
{ message: "package being installed", type: install },
{ message: "package is being upgraded", type: upgrade },
Expand Down Expand Up @@ -97,6 +100,15 @@ OUTPUT='test-5.20_3:
Always:
Always print

Before remove:
Before remove

Before install:
Before install

Before upgrade:
Before upgrade

On remove:
package being removed

Expand Down
8 changes: 8 additions & 0 deletions tests/frontend/register.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ message
{ message: "hey"},
{ message: "install", type = install},
{ message: "remove", type = remove},
{ message: "before install", type = pre-install},
{ message: "before remove", type = pre-remove},
]
EOF
OUTPUT='test2-1:
Expand All @@ -74,6 +76,12 @@ install
On remove:
remove

Before install:
before install

Before remove:
before remove

'
atf_check -o match:"hey" -o match:"install" -o not-match:"remove" pkg register -m .
atf_check -o inline:"${OUTPUT}" pkg info -D test2
Expand Down