[PC-BSD Commits] r18357 - pcbsd/current/src-sh/pc-metapkgmanager

svn at pcbsd.org svn at pcbsd.org
Wed Aug 8 13:06:41 PDT 2012


Author: kris
Date: 2012-08-08 20:06:41 +0000 (Wed, 08 Aug 2012)
New Revision: 18357

Modified:
   pcbsd/current/src-sh/pc-metapkgmanager/pc-metapkgmanager
Log:

Large update to pc-metapkgmanager. Now when we add pkgs from remote, we
will display the full list of pkgs+depends, and show fetch status, allowing
user to know whats going on. 

When removing packages, we better parse the removal list, and don't need to sweep the
entire pkg tree. 



Modified: pcbsd/current/src-sh/pc-metapkgmanager/pc-metapkgmanager
===================================================================
--- pcbsd/current/src-sh/pc-metapkgmanager/pc-metapkgmanager	2012-08-08 18:38:16 UTC (rev 18356)
+++ pcbsd/current/src-sh/pc-metapkgmanager/pc-metapkgmanager	2012-08-08 20:06:41 UTC (rev 18357)
@@ -76,10 +76,16 @@
 		loc="PATH"
 	fi
 
+        echo "Preparing to add: $_apkg... Checking for updates to old packages..."
+        updatepkgs "all" "SILENT"
+
 	echo "Installing Meta-Package: $_apkg"
-	changes=`wc -l ${MPDIR}/${_apkg}/pkg-list | tr -s '\t' ' ' | cut -d ' ' -f 2`
-	echo "Pending package changes: $changes"
 
+	# Start by building the list of packages to download
+	build_pkg_list "$_apkg" "YES"
+
+	echo "Pending package changes: $PKGCOUNT"
+
 	# If a pre-install script, run it now
 	if [ -e "${MPDIR}/${_apkg}/pre-install.sh" ] ; then
 	  if [ -z "$_chroot" ] ; then
@@ -91,28 +97,49 @@
           fi
 	fi
 
-        # Now query pkg_info to confirm each pkg is installed
-        while read pkg
+        # Download / Copy each package now
+        for pkg in $PKGLIST
         do
-		echo "Installing package: $pkg"
-		echo "Installing package: $pkg" >>${LOGFILE}
-		# Start installing the packages now
+		# Start installing / downloading the packages now
 		if [ "$loc" = "NET" ] ; then
-			PACKAGESITE="$MIRRORURL" ; export PACKAGESITE
-			${_chrootcmd} pkg_add -f -r "${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
+		   echo "Downloading package: $pkg"
+		   echo "Downloading package: $pkg" >>${LOGFILE}
+
+	           # Create the TMPDIR
+		   if [ ! -d "${_chroot}/$TMPDIR" ]; then mkdir -p "${_chroot}/$TMPDIR"; fi
+
+		   # Download all the packages first
+		   get_file "${MIRRORURL}/${pkg}.txz" "${_chroot}/${TMPDIR}/${pkg}.txz" 
+		   if [ $? -ne 0 ] ; then
+		      exit_err "Failed downloading: ${MIRRORURL}/${pkg}.txz"
+		   fi
+
 		else
-		  if [ -z "$_chroot" ] ; then
-		     cd "${MIRRORURL}"
-		     pkg_add -f "${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
-		  else
-		     # Do some nullfs mounting to get our dist dir into the chroot
-		     mkdir ${_chroot}/.mnt.$$
-		     mount_nullfs "$MIRRORURL" "${_chroot}/.mnt.$$"
-		     ${_chrootcmd} pkg_add -f "/.mnt.$$/${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
-		  fi
+		   echo "Installing package: $pkg"
+		   echo "Installing package: $pkg" >>${LOGFILE}
+		   if [ -z "$_chroot" ] ; then
+		      cd "${MIRRORURL}"
+		      pkg_add -f -F "${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
+		   else
+		      # Do some nullfs mounting to get our dist dir into the chroot
+		      mkdir ${_chroot}/.mnt.$$
+		      mount_nullfs "$MIRRORURL" "${_chroot}/.mnt.$$"
+		      ${_chrootcmd} pkg_add -f -F "/.mnt.$$/${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
+		   fi
 		fi
-        done < ${MPDIR}/${_apkg}/pkg-list
+        done
 
+	# If this is a network install, then packages are now downloaded, lets install
+	if [ "$loc" = "NET" ] ; then
+           for pkg in $PKGLIST
+           do
+	      echo "Installing package: $pkg"
+	      echo "Installing package: $pkg" >>${LOGFILE}
+	      ${_chrootcmd} pkg_add -f -F "${TMPDIR}/${pkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
+	      rm "${_chroot}/${TMPDIR}/${pkg}.txz"
+           done
+	fi
+
 	# Umount any nullfs stuff in chroot
         if [ -n "${_chroot}" -a "$loc" = "PATH" ] ; then
 	   sleep 1
@@ -184,10 +211,6 @@
 	# kPkgs is our list of packages which are required by other installed meta-pkgs
 	export kPkgs
 
-	# Echo the status
-	changes=`wc -l ${MPDIR}/${_dpkg}/pkg-list | tr -s '\t' ' ' | cut -d ' ' -f 2`
-	echo "Pending package changes: $changes"
-
 	# If a pre-remove script, run it now
 	if [ -e "${MPDIR}/${_dpkg}/pre-remove.sh" ] ; then
 	  if [ -z "$_chroot" ] ; then
@@ -199,10 +222,12 @@
           fi
 	fi
 
+	build_pkg_list "$_dpkg" "NO"
+	echo "Pending package changes: $PKGCOUNT"
+
 	# Lets remove the pkgs from this meta-pkg
-	while read rmPkg
+	for rmPkg in $PKGLIST
 	do
-
 		# Make sure this pkg is installed
 		${_chrootcmd} pkg_info $rmPkg >/dev/null 2>/dev/null
 		if [ "$?" != "0" ] ; then 
@@ -211,19 +236,19 @@
 			continue
 		fi
 
-		# confirm this package isn't required by any others
-		${_chrootcmd} pkg_info -R ${rmPkg} 2>/dev/null | grep "Required by:" >/dev/null 2>/dev/null
+		# Check that this isnt an apart of another meta-pkg installed list
+		echo "$kPkgs" | grep -q "${rmPkg}:"
 		if [ "$?" = "0" ] ; then 
-			echo "Skipping Required: ${rmPkg}" 
-			echo "Skipping Required: ${rmPkg}" >>${LOGFILE}
+			echo "Skipping Meta-Required: ${rmPkg}" 
+			echo "Skipping Meta-Required: ${rmPkg}" >>${LOGFILE}
 			continue
 		fi
 
-		# Check that this isnt an apart of another meta-pkg installed list
-		echo "$kPkgs" | grep "${rmPkg}:" >/dev/null 2>/dev/null
+		# confirm this package isn't required by any others
+		${_chrootcmd} pkg_info -R ${rmPkg} 2>/dev/null | grep -q "Required by:"
 		if [ "$?" = "0" ] ; then 
-			echo "Skipping Meta-Required: ${rmPkg}" 
-			echo "Skipping Meta-Required: ${rmPkg}" >>${LOGFILE}
+			# Still in use, we will re-scan it at the end
+			skippedPkgs="${rmPkg} ${skippedPkgs}"
 			continue
 		fi
 
@@ -231,8 +256,11 @@
 		echo "Removing: ${rmPkg}" >>${LOGFILE}
 		${_chrootcmd} pkg_delete -f ${rmPkg} >>${LOGFILE} 2>>${LOGFILE}
 
-	done < ${MPDIR}/${_dpkg}/pkg-list
+	done
 
+	# Check if we have any packages skipped that need removing
+	recheck_skipped "$skippedPkgs"
+
 	# If the program is still fully installed, set status to error
 	stat_metapkg ${_dpkg}
 	if [ "$?" = "0" ] ; then _pkgStatus=1 ; fi
@@ -248,27 +276,36 @@
           fi
 	fi
 
-        # Now check what packages we have and prune those whom aren't needed
-	echo "Pruning unused packages... This may take a while..."
-        while
-        z="1"
-        do
-                FOUND=""
-                for j in `${_chrootcmd} pkg_info -I -a | cut -d ' ' -f 1`
-                do
-                        echo "$kPkgs" | grep "${j}:" >/dev/null 2>/dev/null
-                        if [ "$?" != "0" ] ; then
-                                check_remove_pkg "${j}"
-                                if [ "$?" = "0" ] ; then
-                                        FOUND="1"
-                                fi
-                        fi
-                done
-        
-                # All done pruning ports
-                if [ -z "$FOUND" ] ; then break ; fi
-        done
+}
 
+# Loop through skipped pkgs, until we are sure there are no more ones to remove
+recheck_skipped()
+{
+   local found=0
+   local newSkipped=""
+   for skPkg in $1
+   do
+      ${_chrootcmd} pkg_info -R ${skPkg} 2>/dev/null | grep -q "Required by:"
+      if [ "$?" = "0" ] ; then 
+        newSkipped="$skPkg $newSkipped"	
+        continue
+      fi
+      found=1
+      echo "Removing: ${skPkg}"
+      echo "Removing: ${skPkg}" >>${LOGFILE}
+      ${_chrootcmd} pkg_delete -f ${skPkg} >>${LOGFILE} 2>>${LOGFILE}
+   done
+
+   if [ $found -eq 1 ] ; then
+      recheck_skipped "$newSkipped"
+   else
+     # List the packages which still have things depending upon them
+     for skPkg in $newSkipped
+     do
+	echo "Skipping Required: ${skPkg}" 
+	echo "Skipping Required: ${skPkg}" >>${LOGFILE}
+     done
+   fi
 }
 
 # Check if the specified pkg doesn't have anything which requires it, and remove it if so
@@ -514,6 +551,7 @@
 updatepkgs() {
   # Check for updates to the pkgs quietly
   checkup_pkgs "YES"
+  if [ -z "$PKGUPDATES" -a "$2" = "SILENT" ] ; then return; fi
   if [ -z "$PKGUPDATES" ] ; then
      echo "No packages need updating!"
      exit 1
@@ -599,10 +637,13 @@
   echo "Updating package: $oPkg -> $nPkg" >> ${LOGFILE}
 
   # Make sure the new package is fetchable
-  fetch -s "${MIRRORURL}${nPkg}.txz" >/dev/null 2>/dev/null
+  # Create the TMPDIR
+  if [ ! -d "${_chroot}/$TMPDIR" ]; then mkdir -p "${_chroot}/$TMPDIR"; fi
+
+  # Download all the packages first
+  get_file "${MIRRORURL}/${nPkg}.txz" "${_chroot}/${TMPDIR}/${pkg}.txz"
   if [ $? -ne 0 ] ; then
-     echo "ERROR: Cound not fetch ${nPkg}.txz"
-     exit 1
+      exit_err "Failed downloading: ${MIRRORURL}/${nPkg}.txz"
   fi
 
   # Remove the old pkg
@@ -611,8 +652,7 @@
 
   # Start installing the packages now
   if [ "$loc" = "NET" ] ; then
-     #echo "${_chrootcmd} pkg_add -f -r $nPkg"
-     ${_chrootcmd} pkg_add -f -r "${nPkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
+     ${_chrootcmd} pkg_add -f "${TMPDIR}/${nPkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
   else
      if [ -z "$_chroot" ] ; then
         pkg_add -f "${nPkg}.txz" >>${LOGFILE} 2>>${LOGFILE}
@@ -641,6 +681,123 @@
   rm /tmp/.plist.$$ 2>/dev/null
 }
 
+get_pkg_deps()
+{
+  local tPkg="$1"
+  if [ ! -e "${DEPDIR}/${tPkg}.deps" ] ; then
+     echo "Warning: No dependancy file for ${tPkg}!"
+     return
+  fi
+  while read pkgDeps
+  do
+     echo "$pkgDeps" | grep -q "Dependency: "
+     if [ $? -ne 0 ] ; then continue ; fi
+     pkgDeps=`echo $pkgDeps | cut -d ' ' -f 2`
+
+     echo "${DEPS}" | grep -q " $pkgDeps"
+     if [ $? -eq 0 ] ; then continue ; fi
+
+     # Save this as a dependency
+     #echo "Added DEP: $pkgDeps"
+     DEPS="${DEPS} $pkgDeps"
+
+     # Drill down
+     get_pkg_deps "$pkgDeps"
+  
+  done < ${DEPDIR}/${tPkg}.deps
+  
+}
+
+build_pkg_list() 
+{
+  local _mpkg="$1"
+  local _strip="$2"
+  PKGLIST=""
+  DEPS=""
+  echo "Getting package list..."
+  while read mPkg
+  do
+    if [ ! -e "${DEPDIR}/${mPkg}.deps" ] ; then
+       echo "Warning: No dependancy file for ${mPkg}!"
+       continue
+    fi
+    get_pkg_deps "$mPkg"
+    DEPS="$mPkg $DEPS"
+  done < ${MPDIR}/${_mpkg}/pkg-list
+
+  for pkg in $DEPS
+  do
+    echo "$pkg" >> /tmp/.pc-meta-sort.$$
+  done
+  sort /tmp/.pc-meta-sort.$$ > /tmp/.pc-meta-sort2.$$
+  mv /tmp/.pc-meta-sort2.$$ /tmp/.pc-meta-sort.$$
+
+  PKGCOUNT=0
+  while read line
+  do
+     if [ -d "/var/db/pkg/$line" -a "$_strip" = "YES" ] ; then continue ; fi
+     PKGLIST="${PKGLIST} ${line}"
+     PKGCOUNT=`expr ${PKGCOUNT} + 1`
+  done < /tmp/.pc-meta-sort.$$
+  rm /tmp/.pc-meta-sort.$$
+}
+
+# Function to download a file from remote using fetch
+get_file() {
+	_rf="${1}"
+	_lf="${2}"
+
+	if [ -e "${_lf}" ] ; then 
+		echo "Resuming download of: ${_lf}"
+	fi
+
+	if [ "$GUI_FETCH_PARSING" != "YES" ] ; then
+		fetch -r -o "${_lf}" "${_rf}"
+		_err=$?
+	else
+		# Doing a front-end download, parse the output of fetch
+		_eFile="/tmp/.fetch-exit.$$"
+		fetch -s "${_rf}" > /tmp/.fetch-size.$$ 2>/dev/null
+		_fSize=`cat /tmp/.fetch-size.$$ 2>/dev/null`
+		_fSize="`expr ${_fSize} / 1024 2>/dev/null`"
+		rm "/tmp/.fetch-size.$$" 2>/dev/null
+		_time=1
+
+		( fetch -r -o "${_lf}" "${_rf}" >/dev/null 2>/dev/null ; echo "$?" > ${_eFile} ) &
+		FETCH_PID=`ps -auwwwx | grep -v grep | grep "fetch -r -o ${_lf}" | awk '{print $2}'`
+		while : 
+		do
+			if [ -e "${_lf}" ] ; then
+				_dSize=`du -k ${_lf} | tr -d '\t' | cut -d '/' -f 1`
+				if [ $(is_num "$_dSize") ] ; then
+					if [ ${_fSize} -lt ${_dSize} ] ; then _dSize="$_fSize" ; fi
+					_kbs=`expr ${_dSize} \/ $_time`
+					echo "SIZE: ${_fSize} DOWNLOADED: ${_dSize} SPEED: ${_kbs} KB/s"
+				fi
+			fi
+
+			# Make sure download isn't finished
+			ps -p $FETCH_PID >/dev/null 2>/dev/null
+			if [ "$?" != "0" ] ; then break ; fi
+			sleep 2
+			_time=`expr $_time + 2`
+		done
+
+		_err="`cat ${_eFile}`"
+		if [ "$_err" = "0" ]; then echo "FETCHDONE" ; fi
+		unset FETCH_PID
+	fi
+
+	echo ""
+	return $_err
+}
+
+is_num()
+{
+        expr $1 + 1 2>/dev/null
+        return $?
+}
+
 # Unset some vars
 _chroot=""
 _chrootcmd=""
@@ -656,6 +813,8 @@
 _pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
 if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
 MPDIR="${DBDIR}/${PKGSET}"
+DEPDIR="${MPDIR}/pkg-deps"
+TMPDIR="/usr/local/tmp"
 
 if [ $# -eq 0 ]; then display_usage; fi
 
@@ -683,6 +842,7 @@
 	    _pkgChk="`sed -n 's/PCBSD_METAPKGSET: //p' ${PCBSD_ETCCONF} 2>/dev/null`"
 	    if [ -n "${_pkgChk}" ] ; then PKGSET="$_pkgChk" ; fi
             MPDIR="${DBDIR}/${PKGSET}"
+	    DEPDIR="${MPDIR}/pkg-deps"
 	    shift
             ;;
   --pkgset) if [ -z "$2" ] ; then display_usage ; fi  
@@ -692,6 +852,7 @@
               exit 1
             fi
             MPDIR="${DBDIR}/${PKGSET}"
+	    DEPDIR="${MPDIR}/pkg-deps"
             shift ;;
          *) if [ -z "$1" ] ; then
 	      shift



More information about the Commits mailing list