[Midnightbsd-cvs] src [7313] trunk/lib/libmport: Initial implementation of pre exec/ unexec and post exec/unexec for plists

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Sep 26 13:45:27 EDT 2015


Revision: 7313
          http://svnweb.midnightbsd.org/src/?rev=7313
Author:   laffer1
Date:     2015-09-26 13:45:27 -0400 (Sat, 26 Sep 2015)
Log Message:
-----------
Initial implementation of pre exec/unexec and post exec/unexec for plists

Historically we've run @exec and @unexec inline.  While this is still supported, we're now refactoring to allow steps before
and after package runs.

@preexec and @postexec fire on install and updates

@preunexec and @postunexec fire on deletes. (and updates when removing)

Modified Paths:
--------------
    trunk/lib/libmport/bundle_read_install_pkg.c
    trunk/lib/libmport/delete_primative.c
    trunk/lib/libmport/mport.h
    trunk/lib/libmport/plist.c

Modified: trunk/lib/libmport/bundle_read_install_pkg.c
===================================================================
--- trunk/lib/libmport/bundle_read_install_pkg.c	2015-09-26 16:25:00 UTC (rev 7312)
+++ trunk/lib/libmport/bundle_read_install_pkg.c	2015-09-26 17:45:27 UTC (rev 7313)
@@ -74,6 +74,15 @@
 static int
 do_pre_install(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg)
 {
+    int ret;
+    char cwd[FILENAME_MAX];
+    sqlite3_stmt *assets = NULL, *count, *insert = NULL;
+    sqlite3 *db;
+    mportAssetListEntryType type;
+    const char *data, *checksum;
+
+    db = mport->db;
+
     /* run mtree */
     if (run_mtree(mport, bundle, pkg) != MPORT_OK)
         RETURN_CURRENT_ERROR;
@@ -82,7 +91,70 @@
     if (run_pkg_install(mport, bundle, pkg, "PRE-INSTALL") != MPORT_OK)
         RETURN_CURRENT_ERROR;
 
+    /* Process @preexec steps */
+    if (mport_db_prepare(db, &assets, "SELECT type,data,checksum FROM stub.assets WHERE pkg=%Q", pkg->name) != MPORT_OK)
+        goto ERROR;
+
+    (void) strlcpy(cwd, pkg->prefix, sizeof(cwd));
+
+    if (mport_chdir(mport, cwd) != MPORT_OK)
+        goto ERROR;
+
+    while (1) {
+        ret = sqlite3_step(assets);
+
+        if (ret == SQLITE_DONE)
+            break;
+
+        if (ret != SQLITE_ROW) {
+            SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db));
+            goto ERROR;
+        }
+
+        type = (mportAssetListEntryType) sqlite3_column_int(assets, 0);
+        data = sqlite3_column_text(assets, 1);
+        checksum = sqlite3_column_text(assets, 2);
+
+        switch (type) {
+            case ASSET_CWD:
+                (void) strlcpy(cwd, data == NULL ? pkg->prefix : data, sizeof(cwd));
+                if (mport_chdir(mport, cwd) != MPORT_OK)
+                    goto ERROR;
+
+                break;
+            case ASSET_CHMOD:
+                printf("asset_chmod %s, %s\n", mode, data);
+                if (mode != NULL)
+                    free(mode);
+                /* TODO: should we reset the mode rather than NULL here */
+                if (data == NULL)
+                    mode = NULL;
+                else
+                    mode = strdup(data);
+                break;
+            case ASSET_CHOWN:
+                owner = mport_get_uid(data);
+                break;
+            case ASSET_CHGRP:
+                group = mport_get_gid(data);
+                break;
+            case ASSET_PREEXEC:
+                if (mport_run_asset_exec(mport, data, cwd, file) != MPORT_OK)
+                    goto ERROR;
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+    sqlite3_finalize(assets);
+    mport_pkgmeta_logevent(mport, pkg, "preexec");
+
     return MPORT_OK;
+
+    ERROR:
+        sqlite3_finalize(assets);
+        RETURN_CURRENT_ERROR;
 }
 
 static int
@@ -271,7 +343,7 @@
                 break;
         }
 
-        /* insert this assest into the master database */
+        /* insert this asset into the master database */
         if (sqlite3_bind_int(insert, 1, (int) type) != SQLITE_OK) {
             SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db));
             goto ERROR;
@@ -349,21 +421,100 @@
 static int
 do_post_install(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg)
 {
-  char to[FILENAME_MAX], from[FILENAME_MAX];
+    char to[FILENAME_MAX], from[FILENAME_MAX];
 
-  COPY_METAFILE(MPORT_MTREE_FILE);
-  COPY_METAFILE(MPORT_INSTALL_FILE);
-  COPY_METAFILE(MPORT_DEINSTALL_FILE);
-  COPY_METAFILE(MPORT_MESSAGE_FILE);
+    COPY_METAFILE(MPORT_MTREE_FILE);
+    COPY_METAFILE(MPORT_INSTALL_FILE);
+    COPY_METAFILE(MPORT_DEINSTALL_FILE);
+    COPY_METAFILE(MPORT_MESSAGE_FILE);
 
-  if (display_pkg_msg(mport, bundle, pkg) != MPORT_OK)
+    if (run_postexec(mport, bundle, pkg) != MPORT_OK)
+        RETURN_CURRENT_ERROR;
+
+    if (display_pkg_msg(mport, bundle, pkg) != MPORT_OK)
+        RETURN_CURRENT_ERROR;
+
+    return run_pkg_install(mport, bundle, pkg, "POST-INSTALL");
+}
+
+static int run_postexec(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg)
+{
+    int ret;
+    char cwd[FILENAME_MAX];
+    sqlite3_stmt *assets = NULL, *count, *insert = NULL;
+    sqlite3 *db;
+    mportAssetListEntryType type;
+    const char *data, *checksum;
+
+    db = mport->db;
+
+    /* Process @postexec steps */
+    if (mport_db_prepare(db, &assets, "SELECT type,data,checksum FROM stub.assets WHERE pkg=%Q", pkg->name) != MPORT_OK)
+        goto ERROR;
+
+    (void) strlcpy(cwd, pkg->prefix, sizeof(cwd));
+
+    if (mport_chdir(mport, cwd) != MPORT_OK)
+        goto ERROR;
+
+    while (1) {
+        ret = sqlite3_step(assets);
+
+        if (ret == SQLITE_DONE)
+            break;
+
+        if (ret != SQLITE_ROW) {
+            SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db));
+            goto ERROR;
+        }
+
+        type = (mportAssetListEntryType) sqlite3_column_int(assets, 0);
+        data = sqlite3_column_text(assets, 1);
+        checksum = sqlite3_column_text(assets, 2);
+
+        switch (type) {
+            case ASSET_CWD:
+                (void) strlcpy(cwd, data == NULL ? pkg->prefix : data, sizeof(cwd));
+                if (mport_chdir(mport, cwd) != MPORT_OK)
+                    goto ERROR;
+
+                break;
+            case ASSET_CHMOD:
+                printf("asset_chmod %s, %s\n", mode, data);
+                if (mode != NULL)
+                    free(mode);
+                /* TODO: should we reset the mode rather than NULL here */
+                if (data == NULL)
+                    mode = NULL;
+                else
+                    mode = strdup(data);
+                break;
+            case ASSET_CHOWN:
+                owner = mport_get_uid(data);
+                break;
+            case ASSET_CHGRP:
+                group = mport_get_gid(data);
+                break;
+            case ASSET_POSTEXEC:
+                if (mport_run_asset_exec(mport, data, cwd, file) != MPORT_OK)
+                    goto ERROR;
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+    sqlite3_finalize(assets);
+    mport_pkgmeta_logevent(mport, pkg, "postexec");
+
+    return MPORT_OK;
+
+    ERROR:
+    sqlite3_finalize(assets);
     RETURN_CURRENT_ERROR;
-  
-  return run_pkg_install(mport, bundle, pkg, "POST-INSTALL");
 }
 
 
-
 static int
 run_mtree(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg)
 {

Modified: trunk/lib/libmport/delete_primative.c
===================================================================
--- trunk/lib/libmport/delete_primative.c	2015-09-26 16:25:00 UTC (rev 7312)
+++ trunk/lib/libmport/delete_primative.c	2015-09-26 17:45:27 UTC (rev 7313)
@@ -26,6 +26,7 @@
  */
 
 #include <sys/cdefs.h>
+
 __MBSDID("$MidnightBSD$");
 
 #include <sys/types.h>
@@ -44,13 +45,14 @@
 
 
 static int run_pkg_deinstall(mportInstance *, mportPackageMeta *, const char *);
+
 static int delete_pkg_infra(mportInstance *, mportPackageMeta *);
+
 static int check_for_upwards_depends(mportInstance *, mportPackageMeta *);
 
 
 MPORT_PUBLIC_API int
-mport_delete_primative(mportInstance *mport, mportPackageMeta *pack, int force)
-{
+mport_delete_primative(mportInstance *mport, mportPackageMeta *pack, int force) {
     sqlite3_stmt *stmt;
     int ret, current, total;
     mportAssetListEntryType type;
@@ -114,6 +116,9 @@
     if (mport_db_do(mport->db, "UPDATE packages SET status='dirty' WHERE pkg=%Q", pack->name) != MPORT_OK)
         RETURN_CURRENT_ERROR;
 
+    if (run_unexec(mport, pack, ASSET_PREUNEXEC) != MPORT_OK)
+        RETURN_CURRENT_ERROR;
+
     if (run_pkg_deinstall(mport, pack, "DEINSTALL") != MPORT_OK)
         RETURN_CURRENT_ERROR;
 
@@ -222,6 +227,9 @@
 
     sqlite3_finalize(stmt);
 
+    if (run_unexec(mport, pack, ASSET_POSTUNEXEC) != MPORT_OK)
+        RETURN_CURRENT_ERROR;
+
     if (run_pkg_deinstall(mport, pack, "POST-DEINSTALL") != MPORT_OK)
         RETURN_CURRENT_ERROR;
 
@@ -255,12 +263,56 @@
     syslog(LOG_NOTICE, "%s-%s deinstalled", pack->name, pack->version);
 
     return MPORT_OK;
-} 
-  
+}
 
 static int
-run_pkg_deinstall(mportInstance *mport, mportPackageMeta *pack, const char *mode)
-{
+run_unexec(mportInstance *mport, mportPackageMeta *pkg, mportAssetListEntryType type) {
+    int ret;
+    char cwd[FILENAME_MAX];
+    sqlite3_stmt *assets = NULL;
+    sqlite3 *db;
+    const char *data;
+
+    db = mport->db;
+
+    /* Process @postunexec steps */
+    if (mport_db_prepare(db, &assets, "SELECT data FROM assets WHERE pkg=%Q and type=%Q", pkg->name,
+                         type) != MPORT_OK)
+        goto POSTUN_ERROR;
+
+    (void) strlcpy(cwd, pkg->prefix, sizeof(cwd));
+
+    if (mport_chdir(mport, cwd) != MPORT_OK)
+        goto ERROR;
+
+    while (1) {
+        ret = sqlite3_step(assets);
+
+        if (ret == SQLITE_DONE)
+            break;
+
+        if (ret != SQLITE_ROW) {
+            SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db));
+            goto ERROR;
+        }
+         data = sqlite3_column_text(assets, 0);
+
+        if (mport_run_asset_exec(mport, data, cwd, file) != MPORT_OK)
+            goto POSTUN_ERROR;
+    }
+    sqlite3_finalize(assets);
+    mport_pkgmeta_logevent(mport, pkg, type == ASSET_POSTUNEXEC ? "postunexec" : "preunexec");
+
+    return MPORT_OK;
+
+    POSTUN_ERROR:
+    sqlite3_finalize(assets);
+    RETURN_CURRENT_ERROR;
+}
+
+
+static int
+run_pkg_deinstall(mportInstance *mport, mportPackageMeta *pack, const char *mode) {
     char file[FILENAME_MAX];
     int ret;
 
@@ -281,8 +333,7 @@
 
 /* delete this package's infrastructure dir. */
 static int
-delete_pkg_infra(mportInstance *mport, mportPackageMeta *pack)
-{
+delete_pkg_infra(mportInstance *mport, mportPackageMeta *pack) {
     char dir[FILENAME_MAX];
 
     (void) snprintf(dir, FILENAME_MAX, "%s%s/%s-%s", mport->root, MPORT_INST_INFRA_DIR, pack->name, pack->version);
@@ -296,10 +347,8 @@
 }
 
 
-
 static int
-check_for_upwards_depends(mportInstance *mport, mportPackageMeta *pack)
-{
+check_for_upwards_depends(mportInstance *mport, mportPackageMeta *pack) {
     sqlite3_stmt *stmt;
     const char *depends;
     char *msg;

Modified: trunk/lib/libmport/mport.h
===================================================================
--- trunk/lib/libmport/mport.h	2015-09-26 16:25:00 UTC (rev 7312)
+++ trunk/lib/libmport/mport.h	2015-09-26 17:45:27 UTC (rev 7313)
@@ -73,13 +73,14 @@
 void mport_default_progress_step_cb(int, int, const char *);
 void mport_default_progress_free_cb(void);
 
-enum _AssetListEntryType { 
-  ASSET_INVALID, ASSET_FILE, ASSET_CWD, ASSET_CHMOD, ASSET_CHOWN, ASSET_CHGRP,
-  ASSET_COMMENT, ASSET_IGNORE, ASSET_NAME, ASSET_EXEC, ASSET_UNEXEC,
-  ASSET_SRC, ASSET_DISPLY, ASSET_PKGDEP, ASSET_CONFLICTS, ASSET_MTREE,
-  ASSET_DIRRM, ASSET_DIRRMTRY, ASSET_IGNORE_INST, ASSET_OPTION, ASSET_ORIGIN,
-  ASSET_DEPORIGIN, ASSET_NOINST, ASSET_DISPLAY, ASSET_DIR, ASSET_SAMPLE,
-  ASSET_SHELL
+enum _AssetListEntryType {
+    ASSET_INVALID, ASSET_FILE, ASSET_CWD, ASSET_CHMOD, ASSET_CHOWN, ASSET_CHGRP,
+    ASSET_COMMENT, ASSET_IGNORE, ASSET_NAME, ASSET_EXEC, ASSET_UNEXEC,
+    ASSET_SRC, ASSET_DISPLY, ASSET_PKGDEP, ASSET_CONFLICTS, ASSET_MTREE,
+    ASSET_DIRRM, ASSET_DIRRMTRY, ASSET_IGNORE_INST, ASSET_OPTION, ASSET_ORIGIN,
+    ASSET_DEPORIGIN, ASSET_NOINST, ASSET_DISPLAY, ASSET_DIR,
+    ASSET_SAMPLE, ASSET_SHELL,
+    ASSET_PREEXEC, ASSET_PREUNEXEC, ASSET_POSTEXEC, ASSET_POSTUNEXEC
 };
 
 typedef enum _AssetListEntryType mportAssetListEntryType;

Modified: trunk/lib/libmport/plist.c
===================================================================
--- trunk/lib/libmport/plist.c	2015-09-26 16:25:00 UTC (rev 7312)
+++ trunk/lib/libmport/plist.c	2015-09-26 17:45:27 UTC (rev 7313)
@@ -161,12 +161,25 @@
 parse_command(const char *s) {
 
     /* This is in a rough frequency order */
+
     if (STRING_EQ(s, "comment"))
         return ASSET_COMMENT;
+
+    if (STRING_EQ(s, "preexec"))
+        return ASSET_PREEXEC;
+    if (STRING_EQ(s, "preunexec"))
+        return ASSET_PREUNEXEC;
+    if (STRING_EQ(s, "postexec"))
+        return ASSET_POSTEXEC;
+    if (STRING_EQ(s, "postunexec"))
+        return ASSET_POSTUNEXEC;
+
+    /* EXEC and UNEXEC are deprecated in favor of their pre/post variants */
     if (STRING_EQ(s, "exec"))
         return ASSET_EXEC;
     if (STRING_EQ(s, "unexec"))
         return ASSET_UNEXEC;
+
     if (STRING_EQ(s, "dirrm"))
         return ASSET_DIRRM;
     if (STRING_EQ(s, "dirrmtry"))
@@ -175,6 +188,7 @@
         return ASSET_DIR;
     if (STRING_EQ(s, "cwd") || STRING_EQ(s, "cd"))
         return ASSET_CWD;
+
     if (STRING_EQ(s, "srcdir"))
         return ASSET_SRC;
     if (STRING_EQ(s, "mode"))



More information about the Midnightbsd-cvs mailing list