Cool Solutions

Restoring ZENworks Images Made Easy! – Updated for ZCM



By:

February 23, 2010 11:01 am

Reads: 6321

Comments:1

Score:0

Even when using automated imaging, there comes a time that you need to restore a specific image file to a computer. Often times, this is for a hard drive replacement or something like that.

The problem comes that you get ready to image, but you don’t remember the name of the file you’re looking for. This leaves you to having to go back to another computer, find the folder on the server, and then look for the file.

To combat this problem, I have developed this script that, along with a correct FTP configuration, will prompt you with a list of images available that you can select by number.

The script accomplishes this by running a quick FTP command to do a listing of the folder, then enumerating the list of image files so that you can pick by number.

The first step to setting this up is to enable FTP on your ZEN imaging server. With SLES 10 or newer, we have the PureFTPd daemon. I’m not going to go into configuring PureFTPd at this time, but if anyone needs help, post a comment and I will post more information.

Once the FTP daemon is configured and enabled, we will create a local user account. This account will only be used for the restore script to log in to get a directory listing.

For the purpose of this tutorial, we’re going to use the following information:

  • Local user name: baseline
  • Local password: password
  • Local path to the image files: /var/opt/novell/zenworks/content-repo/images/backup

Now that you’ve created the user, you should have a /home/baseline folder on the server. We now need to create a path to the image files within that folder. To do so, create a folder called /home/baseline/backup

PureFTPd is shipped with SLES in a configuration that will not allow chrooted users to follow symbolic links outside their home directory. This means that we can’t simply create a symbolic link to the local path.

One way around this is to use a bind mount. The command to do that is:

mount --bind /images/backup /home/baseline/backup

This creates a mount point that is actually another folder in the directory tree. The advantage of this over a symbolic link is that the system treats this exactly as a local folder.

You can make sure that this mount point always loads when the system boots by adding the following line to /etc/fstab

/var/opt/novell/zenworks/content-repo/images/backup    /home/baseline/backup    bind    defaults,bind    0    0

Now that we’ve mounted the folder, check that you can log in using an FTP client. Log in as baseline with a password of password and make sure that you can navigate to /backup and get a file listing (ls).

Once that’s verified, we’re ready to use the script.

A couple points to note about this script:

  • This script is written for ZCM 10. It can work for ZFD7 as well if you make the appropriate adjustments for your path.
  • We remove all partitions and fully reimage the machine each time for security reasons. You may want to adjust this behavior to suit your environment.
  • We also reimage by partition as opposed to by drive as this resolves any potential problems where the drive you are restoring to doesn’t match the size of the drive from the original image.
  • The script dose handle a few command line options:
    1. help – Display the command syntax
    2. partsize:SIZE – Specify the size of the C: partition. This allows you to image using a partition size smaller than the maximum for the drive in the event that you require a second partition on the machine
    3. imagename:IMAGENAME – This option allows you to specify the name of the image file if you already know it which will bypass the selection process.

This script will be stored somewhere in the TFTP server path (/srv/tftp/) of your PXE server. For information about how to automatically download the script each time the imaging environment loads, see my previous article Automating Non-Automatic ZENworks Imaging – Part 1

The script is:

#!/bin/bash
################################################################################
#-- ZENworks Imaging Restoring Script
#
#-- This script is used to restore a previously backed up image to a PC
################################################################################

##--- [BEGIN Configuration section]
# FTP server information
ftpserver="myftp.domain.com" ## Enter your FTP server name here
ftpuser="baseline"
ftppass="password"

# pagelen = Maximum number of files to list per page
pagelen=20

# ftpdir = Directory on FTP server holding the files
#          If you are using an OES server with PureFTPd, you cannot use symbolic
#          links, so you must do a directory bind mount.  Ex:
#              mount --bind /[existing location] /[new location]
#          If your existing files are in /images/backup and the new location is
#          /home/backupuser/images then the command would be:
#              mount --bind /images/backup /home/backupuser/images
#          NOTE:  As with any mount command, the mount point directory must exist
ftpdir="/backup"

# basepath = The ZEN imaging base path for the files.  This is the same base path
#            (without the filename) that you would type into the img application
#            if you were restoring an image manually.
basepath=//$STORAGEADDR/images/backup

##--- [END Configuration section]

##--- [BEGIN additional functions]
## -- Function to display help screen
function getfilename {
   ## -- Create .netrc file for ftp server authentication
   echo "machine $ftpserver" > /.netrc
   echo "        login $ftpuser" >> /.netrc
   echo "        password $ftppass" >> /.netrc
   chmod 700 /.netrc

   ## -- Create FTP command file
   echo "ls $ftpdir" > /tmp/ftp.cmd
   echo "close" >> /tmp/ftp.cmd
   echo "quit" >> /tmp/ftp.cmd

   ftp $ftpserver < /tmp/ftp.cmd > /tmp/ftp.out
   cat /tmp/ftp.out | awk '{print $9}' > /tmp/filelist.txt

   while true; do
      counter=-1
      pagecount=0
      filenum=""
      echo "Available files to restore:"
      echo  

      for i in $(cat /tmp/filelist.txt); do
         if [ $counter -gt 0 ]; then
            echo "$counter: $i"
            pagecount=$(($pagecount + 1))
         fi
         counter=$(($counter + 1))
         if [ $pagecount -eq $pagelen ]; then
            echo
            echo -n "Enter the number of the file you wish to retrieve or enter to continue: "
            read filenum
            
            if [ "$filenum" == "\n" ]; then
               filenum=""
            fi
            
            if [ "$filenum" != "" ]; then
               break
            fi
            
            echo
            echo
            echo "Available files to restore:"
            echo
            pagecount=0
         fi
      done

      if [ "$filenum" == "" ]; then
         echo
         echo -n "Enter the number of the file you wish to retrieve: "
         read filenum
      fi
      
      myfile=""
      counter=-1
      for i in $(cat /tmp/filelist.txt); do
         if [ "$counter" -eq "$filenum" 2> /dev/null ]; then
            imagename=$i
            break
         fi
         counter=$(($counter + 1))
      done

      if [ "$imagename" != "" ]; then
         echo
         read -p "Do you want to restore $imagename (y/N)? " reply
         if [ `echo $reply | tr [:upper:] [:lower:]` = "y" ]; then
            break
         fi
      fi

      echo
      if [ "$imagename" == "" ]; then
         echo Valid file number not specified.
         echo
      fi
      echo   
   done
}

## -- Function to display help screen
function syntax {
   echo "Correct command syntax is:"
   echo "   restoreImage [partsize:SIZE] [imagename:IMAGENAME]"
   echo
   echo "   partsize - Specify the size of the boot partition to be created in megabytes."
   echo "              If not specified, the entire drive will be used. ** 1 GB = 1000 MB"
   echo
   echo "   imagename - optional parameter to specify the name of the image file to"
   echo "   restore.  The extension .zmg is automatically added.  If a file name is"
   echo "   not specified, you will be given a list of available image files to"
   echo "   choose from."
}
##--- [END additional functions]

##--- [BEGIN script]
partsize="0"
imagename=""

## Parse command line variables
for var in "$@"
do
   validcmd=0
   cmd=${var%%:*}
   if [[ $var == *:* ]]; then
      val=${var#*:}
   else
      val=""
   fi
   if [[ $cmd == imagename ]]; then
      if [[ "$val" != "" ]]; then
         imagename=$val
         validcmd=1
      fi
   fi
   if [[ $cmd == help ]]; then
      syntax
      exit
   fi
   if [[ $validcmd == 0 ]]; then
      echo "Invalid command."
      echo
      syntax
      exit
   fi
done

if [ "$imagename" == "" ]; then
   getfilename
fi

## Strip the .zmg from the file name if it is there for consistency
if [ "$imagename" != "" ]; then
   namelen=`expr index "$imagename" .zmg`
   if [ $namelen -ne -1 ]; then
      imagename=${imagename:0:$(($namelen - 1))}
   fi
fi

## Delete all existing partitions
img pd-all

## Create primary partition (max size unless specified)
if [ $partsize -eq 0 ]; then
   img pc1 ntfs
else
   img pc1 ntfs $partsize 
fi

## Download the base image
img rp $PROXYADDR "$basepath/$imagename.zmg" a1:p1

## Set first partition to be active
img pa1

## Reboot and complete the process
reboot -f
##--- [END script]

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

Categories: Uncategorized

Disclaimer: This content is not supported by Novell. It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test it thoroughly before using it in a production environment.

1 Comment

  1. By:ackitsme

    I made the appropriate changes to support ZCM 10, most notably that Novell broke the FTP client such that you can’t pass the user ID and password from the command line like you are supposed to ex:

    ftp ftp://user:pass@ftpserver

    This was worked around by generating a .netrc file which the client will use to pull the login information.

    VN:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)

Comment

RSS