r5487 - in trunk: cumin/bin cumin/python/cumin etc

tmckay at fedoraproject.org tmckay at fedoraproject.org
Fri Sep 28 19:02:10 UTC 2012


Author: tmckay
Date: 2012-09-28 19:02:09 +0000 (Fri, 28 Sep 2012)
New Revision: 5487

Modified:
   trunk/cumin/bin/cumin-admin
   trunk/cumin/bin/cumin-database
   trunk/cumin/python/cumin/config.py
   trunk/etc/Profile.bash
Log:
Fix up cumin-admin and cumin-database to recognize a development instance
and prompt for the creation of a development postgres user during database
installation.  The dev postgres user will be necessary to run Cumin from
the development instance since postgres is using auth ident by default and
will want to see a user mathing the developer's OS username.

Note, these changes should have no effect when Cumin is installed as
a package (runs as the 'cumin' user from /usr/bin and /usr/share/cumin)


Modified: trunk/cumin/bin/cumin-admin
===================================================================
--- trunk/cumin/bin/cumin-admin	2012-09-28 15:10:33 UTC (rev 5486)
+++ trunk/cumin/bin/cumin-admin	2012-09-28 19:02:09 UTC (rev 5487)
@@ -19,48 +19,75 @@
 from cumin.admin import SchemaMissing
 
 def main():
+
     uid = os.getuid()
     file_uid = os.stat(sys.argv[0]).st_uid
 
     if uid not in (file_uid, 0):
         error("You have insufficient privileges")
     
-    if uid == 0:
-        import pwd
-        
-        # Okay, if the file is not owned by us, then this is a local 
-        # (development) instance and cumin is not installed as a package.
-        # In this case we need to set the effective uid as the file owner.  
-        # That owner should have added themselves as a postgres user so 
-        # auth will work.
-        if file_uid != uid:
-            os.seteuid(file_uid)
-        else:
-            # Become the cumin user so we have
-            # access to the db with ident authentication
-            cumin = pwd.getpwnam("cumin")
-            os.seteuid(cumin[2])
-
+    # Log to stderr
     setup_initial_logging()
 
-    # Read config file, just the common section
+    # We will read the config file, but just the common section
     config = CuminCommonConfig()
-
-    # Set a log file default...
-    home = os.environ.get("CUMIN_HOME", os.path.normpath("/usr/share/cumin"))
-    config.set_log(os.path.join(home, "log", "admin.log"))
-
     values = config.parse()
 
     # Get options
     parser = CuminOptionParser()
+
+    # The escape string, shutdown timeout, and init-only 
+    # options don't apply to us so eliminate confustion...
     parser.remove_option("--es")
+    parser.remove_option("--tm")
+    parser.remove_option("--init-only")
+
+    # We do however want to add a --no-dev-user flag
+    # so that we can control setuid to the local user for
+    # development instances.  This is used by cumin-database
+    # during installs to create the schema without worrying about
+    # the local user.
+    parser.add_option("--no-dev-user", action="store_true", default=False,
+                      help="Do not setuid to the local user (development only)")
+
+    # And we want to set the default for the log-file option
+    # since the default is empty and we aren't picking up a value
+    # from a config section.
+
+    # cumin-database may set this to /dev/null so that log file ownership
+    # is not an issue during database install.
+    home = os.environ.get("CUMIN_HOME", os.path.normpath("/usr/share/cumin"))
+    parser.set_defaults(log_file=os.path.join(home, "log", "admin.log"))
+
     parser.set_usage(generate_usage())
     opts, args = parser.parse_args()
 
     # Use config values as defaults for unspecified options
     apply_defaults(values.common, opts)
  
+    # Track what we've done for error messages...
+    setuid_dev_user = False
+
+    if uid == 0:
+        import pwd
+        # Okay, if the file is not owned by us, then this is a local 
+        # development instance and cumin is not installed as a package.
+        # In this case we usually want to set the effective uid as the file owner
+        # so that log files, user export files, etc are owned by the developer.
+        # That owner should have added themselves as a postgres user so 
+        # auth will work.
+  
+        # However, cumin-database may turn off this behavior because
+        # it runs as root to create the database.
+        if file_uid != uid and not opts.no_dev_user:
+            setuid_dev_user = True
+            os.seteuid(file_uid)
+        else:
+            # Become the cumin user so we have
+            # access to the db with ident authentication
+            cumin = pwd.getpwnam("cumin")
+            os.seteuid(cumin[2])
+
     setup_operational_logging(opts)
 
     try:
@@ -93,7 +120,11 @@
         app.db_init(schema_version_check=False)
     except OperationalError:
         print "Can't talk to the database"
-        error("Run 'cumin-database check' as root for more information")
+        if setuid_dev_user:
+            error("Root did setuid to the local dev user. "\
+                  "Try again with --no-dev-user?")
+        else:    
+            error("Run 'cumin-database check' as root for more information")
     
     conn = app.database.get_connection()
     cursor = conn.cursor()

Modified: trunk/cumin/bin/cumin-database
===================================================================
--- trunk/cumin/bin/cumin-database	2012-09-28 15:10:33 UTC (rev 5486)
+++ trunk/cumin/bin/cumin-database	2012-09-28 19:02:09 UTC (rev 5487)
@@ -6,7 +6,6 @@
 fi
 
 # A workaround for running this script from the devel environment
-
 if [[ -d cumin && -f etc/devel.profile ]]; then
     source etc/devel.profile &> /dev/null
 fi
@@ -183,6 +182,26 @@
     done
 }
 
+function add-postgres-user {
+    dev_postgres_user=$(stat -c %U $DEVEL_HOME/cumin/bin/cumin-database)
+    if [[ $dev_postgres_user ]]; then
+        cat <<EOF
+
+NOTICE: This appears to be a development instance owned by $dev_postgres_user
+
+To run Cumin as this user you *MUST* add a matching postgres user.
+Enter 'yes' to add the $dev_postgres_user user now:
+EOF
+        
+        read add_dev_user
+        if [[ $add_dev_user == "yes" ]]; then
+	    run "createuser --superuser ${dev_postgres_user}" postgres
+        else
+           echo No additional postgres user created
+        fi
+    fi
+}
+
 function install {
     check-environment || exit 1
 
@@ -268,11 +287,35 @@
     fi
 
     run "createuser --superuser ${dbname}" postgres
+    if [[ $CUMIN_DEVEL_INSTANCE ]]; then
+	add-postgres-user
+    fi
     run "createdb --owner=${dbname} ${dbname}" postgres
 
-    cumin-admin create-schema
-    # cumin-admin add-role user
-    # cumin-admin add-role admin
+    # If we are a dev instance we have to be careful
+    # when we delegate to cumin-admin to create the
+    # schema
+    if [[ $CUMIN_DEVEL_INSTANCE ]]; then
+        # If add_dev_user is 'yes' then we created a dev 
+        # postgres user above, let cumin-admin setuid 
+	# to the dev user.
+
+        # Otherwise, make it setuid to the cumin user with
+        # logging set to /dev/null to ensure that the
+	# schema is created and we don't have log ownership issues.
+
+	# If they did not create the dev postgres user, and there
+	# is no cumin user on the system, they are in trouble.
+	if [[ $add_dev_user == "yes" ]]; then
+	    echo Creating schema as the \'$dev_postgres_user\' user
+	    cumin-admin create-schema
+	else
+	    echo Creating schema as the 'cumin' user
+	    cumin-admin create-schema --no-dev-user --log-file=/dev/null
+	fi
+    else
+	cumin-admin create-schema
+    fi
 }
 
 function drop {
@@ -353,6 +396,9 @@
         check-started || exit 1
         ;;
     install)
+	if [[ $2 == "--devel" ]]; then
+	    CUMIN_DEVEL_INSTANCE=2
+        fi
         confirm-install
         echo "The database is installed"
         ;;

Modified: trunk/cumin/python/cumin/config.py
===================================================================
--- trunk/cumin/python/cumin/config.py	2012-09-28 15:10:33 UTC (rev 5486)
+++ trunk/cumin/python/cumin/config.py	2012-09-28 19:02:09 UTC (rev 5487)
@@ -60,9 +60,6 @@
 
         self.section = CuminConfigSection(self, self.section_name)
 
-    def set_log(self, log):
-        self.section.log_file.default = log
-
 class CuminWebConfig(CuminConfig):
     def __init__(self, section_name="web", strict_section="False"):
         super(CuminWebConfig, self).__init__(section_name)
@@ -300,9 +297,9 @@
         OptionParser.__init__(self)
 
         self.add_option("--init-only", action="store_true", default=False)
-        self.add_option("--es", default="")
+        self.add_option("--es", default="", help="Escape string (used by master)")
 
-        self.add_option("--tm", default="5", type=int)
+        self.add_option("--tm", default="5", type=int, help="Shutdown timeout (used by master)")
 
 
         # Defaults for these come later from the config

Modified: trunk/etc/Profile.bash
===================================================================
--- trunk/etc/Profile.bash	2012-09-28 15:10:33 UTC (rev 5486)
+++ trunk/etc/Profile.bash	2012-09-28 19:02:09 UTC (rev 5487)
@@ -1,6 +1,12 @@
 export DEVEL_HOME="$PWD"
 export DEVEL_MODULES="mint cumin basil parsley wooly rosemary sage"
 
+# This will control certain things, like whether or not
+# cumin-database prompts you for the creation of a
+# database superuser to match your account during install
+export CUMIN_DEVEL_INSTANCE=1
+
+
 if [[ -z "$DEVEL_ORIGINAL_PATH" ]]; then
     export DEVEL_ORIGINAL_PATH="$PATH"
 fi



More information about the cumin-developers mailing list