Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 13
For anyone that likes/needs to use VMWare Server a lot... To me, the only advantage in using VMWare Workstation is the option to create "linked clones" via the WKS GUI. ...
  1. #1
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695

    Script - Linked Clones on VMWare Server

    For anyone that likes/needs to use VMWare Server a lot...

    To me, the only advantage in using VMWare Workstation is the option to create "linked clones" via the WKS GUI. But VMWare Server *can* do this as well - it's just not available in the Console. (A linked clone is a cloned virtual machines that uses a "base" VM disk for reference. If you have a 5GB Windows VM, making 5 "full" clones would require 25GB. Initially, 5 linked clones would require only a few MB of extra disk space. As things change, the linked clone VM HDD's will grow, but typically takes up much less space than if they were full clones.)

    You can read further about linked clones on VMWare's website. While the manual steps to create a linked clone are easy to find, I needed something to automate this process for a number of users.

    It continues to be improved with new features, and if there is interest, I will post any changes as well.

    To use, copy/paste the code below into a file named something like vmclone.sh, copy it to /usr/bin, and chmod to make it executable.

    Any feedback/suggestions/improvements are welcome.


    Code:
    #!/bin/bash
    
    # VMClone.sh
    # Small shell script to create *linked clones* on VMWare Server.
    
    # Author: HROAdmin26
    # Last Edited: 2008-04-16
    # Revision: 1.5
    VER="1.5_2008-04-16"
    
    # README:
    # Copy this script to some place in your PATH statement
    # and make it executable - /usr/bin is a good place.
    # On the command line, CD into the directory of your base VM.
    # Run vmclone.sh with no switches for the HELP info.
    
    # Run script as ROOT.
    # DO NOT use if your guest VMDK's are split into 2GB chunks.
    # If any of your names have spaces in them, use quotes.
    
    # Script is run on command line and expects 4 (or more) parameters:
    # $1 = BASE_VM_NAME
    # $2 = BASE_VM_VMX_FILE
    # $3 = BASE_VMDK_FILE
    # $4 = CLONE_VM_NAME/MULTI_BASE_NAME
    
    # Example: vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY
    
    # $5 = Extra functionality. These are *NOT combinable.* Current options:
    # 1) If "start" is specified, the cloned VM is registered and started after cloning.
    # 2) If "multi" is specified, it must be followed by a number between 2 and 10 for the number of clones to create. The MULTI_BASE_NAME is appended with -1, -2, etc to name the multiple clones.
    
    # Examples:
    # 1) vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY start
    # 2) vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" NODES multi 7
    
    
    if [ $# -lt 4 ]
    then
       echo "*****"
       echo "Usage: vmclone.sh \"BASE_VM_NAME\" \"BASE_VMX_FILE\" \"BASE_VMDK_FILE\" \"CLONE_VM_NAME\""
       echo " "
       echo "Example: vmclone.sh \"BIG SERVER\" \"SLES_9.vmx\" \"BigTuna.vmdk\" \"BIGGER_SERVER\""
       echo " "
       echo "==> WARNING! Do not use this script if the .VMDK files are split into 2GB chunks."
       echo "==> Usage Steps:"
       echo "==> ** This new version of vmclone will create the snapshot for you if it does not already exist."
       echo "==> 1) Change directory INTO the folder of your BASE VM and then run vmclone."
       echo "==> More usage options can be found in the script itself - \"more vmclone.sh\"."
       echo "==> VMClone Version: $VER"
       echo "*****"
       exit
    fi
    
    # Check for ROOT permissions.
    if [ $EUID -ne "0" ]
    then
       echo " "
       echo "Effective permissions not ROOT."
       echo "Please run this script as ROOT user."
       echo " "
       exit
    fi
    
    # Set some initial variables...
    REN_CMD="`which vmware-vdiskmanager`"
    SNAP_CMD="`which vmrun`"
    VM_CMD="`which vmware-cmd`"
    B_PATH="`pwd`"
    B_NAME=$1
    B_VMX=$2
    B_VMDK=$3
    C_NAME=$4
    
    # Check if OPTION is specified...
    if [ -n "$5" ]
    then
       OPTION=$5
    fi
    
    # Figure out the snapshot file name.
    B_SNAP=`echo "$B_VMDK" | sed 's/.vmdk/-000001.vmdk/'`
    
    # Define some useful functions...
    # Check if snapshot is already done - if not, create the snapshot.
    check_for_snap ()
    {
       if [ ! -e "$B_SNAP" ]
       then
          $VM_CMD -s register "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
          $SNAP_CMD snapshot "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
       fi
    }
    
    # Assumes CWD is $B_NAME - after clone creation, returns to $B_NAME.
    make_clone ()
    {
       mkdir ../"$C_NAME"
       cp "$B_VMX" "$C_NAME.vmx"
       rm -f *.vmsn
       rm -f *.vmsd
       mv "$C_NAME.vmx" ../"$C_NAME"
       mv "$B_SNAP" ../"$C_NAME"
    
       # Replace the snapshot disk in B_VMX so that another snap can be taken.
       cat "$B_VMX" | sed 's/'"$B_SNAP"'/'"$B_VMDK"'/g' > "$B_VMX.new"
       mv "$B_VMX.new" "$B_VMX"
    
       cd ../"$C_NAME"
       # Now that we're in the clone's dir, set $C_PATH.
       C_PATH="`pwd`"
       $REN_CMD -q -n "$B_SNAP" "$C_NAME.vmdk"
       ln -s ../"$B_NAME"/"$B_VMDK" "$B_VMDK"
    
       # Edit the clone's VMX to reflect the new VMDK name and console display name.
       cat "$C_NAME.vmx" | sed 's/'"$B_SNAP"'/'"$C_NAME"'.vmdk/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       cat "$C_NAME.vmx" | sed 's/'"$B_NAME"'/'"$C_NAME"'/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       chmod 754 *
       # Register the clone with VM Server
       $VM_CMD -s register "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
    
       cd ../"$B_NAME"
    }
    
    
    # MAIN
    
    # If OPTION is "multi", then we need to create multiple clones, using C_NAME as a base name.
    if [ "$OPTION" = "multi" ]
    then
       # If $6 is a valid number of clones between 2 and 10, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 10 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, MULTI was specified, but the number of VM's to create was not between 2 and 10."
          echo "Please try again."
          echo " "
          exit
       fi
    
       #Save the base name before calling make_clone() multiple times.
       M_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$M_BASE-$i"
          check_for_snap
          make_clone
       done
    else
       # No MULTI - single clone to create.
       check_for_snap
       make_clone
       # If $OPTION "start" was specified, start the clone VM.
       if [ -n "$OPTION" ] && [ "$OPTION" = "start" ]
       then
          $SNAP_CMD start "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    fi
    
    
    echo " "
    echo "Linked clone created successfully..."
    echo "Within a few seconds, you should see the clone VM listed in the VMWare Console."
    echo " "
    echo " "
    
    exit

  2. #2
    Just Joined!
    Join Date
    Aug 2008
    Posts
    11
    I'm having a problem. When the script executes it seems everything is fine, but when I go to start the linked clone from the console I get an error message the disk isn't there. This is no VMWare 1.0.6 and ubuntu 8.04 Server.

  3. #3
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    Here is the latest and greatest - it includes an option to create clusters. The script does *not* do a lot of error checking, so if your VM is not set up correctly, the results may vary.

    Note that the VMDK file cannot be split into 2GB chunks.

    Code:
    #!/bin/bash
    
    # VMClone.sh
    # Small shell script to create *linked clones* on VMWare Server.
    
    # Author: HROAdmin26
    # Last Edited: 2008-04-22
    # Revision: 1.7
    VER="1.7_2008-04-22"
    
    # README:
    # Copy this script to some place in your PATH statement
    # and make it executable - /usr/bin is a good place.
    # On the command line, CD into the directory of your base VM.
    # Run vmclone.sh with no switches for the HELP info.
    
    # Run script as ROOT.
    # DO NOT use if your guest VMDK's are split into 2GB chunks.
    # If any of your names have spaces in them, use quotes.
    
    # Script is run on command line and expects 4 (or more) parameters:
    # $1 = BASE_VM_NAME
    # $2 = BASE_VM_VMX_FILE
    # $3 = BASE_VMDK_FILE
    # $4 = CLONE_VM_NAME/MULTI_BASE_NAME/CLUSTER_NAME
    
    # Example: vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY
    
    # $5 = Extra functionality. These are *NOT combinable.* Current options:
    # 1) If "start" is specified, the cloned VM is registered and started after cloning.
    # 2) If "multi" is specified, it must be followed by a number between 2 and 10 for the number of clones to create. The MULTI_BASE_NAME is appended with -1, -2, etc to name the multiple clones.
    # 3) If "cluster" is specified, it must be followed by a number between 2 and 5 for the number of nodes.
    
    # Examples:
    # 1) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY start
    # 2) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" CLONAL multi 7
    # 3) vmclone.sh "BONGO" "BONGO.vmx" "BIG_DISK.vmdk" NODAL cluster 3
    
    # CAVEATS! PLEASE READ AND UNDERSTAND!
    # > Some users have reported issues if the base VM has more than 1 disk - your mileage may vary. <
    # > Your DISPLAY_NAME for the Base VM in the VMWare Console must match the folder name of the Base VM. <
    # > When using the 'cluster' switch, the shared disks are added on an LSILOGIC adapter. <
    # > When using the 'cluster' switch, a folder named CLUSTER_NAME is created - the nodes and shared disks are created inside this folder. <
    
    
    if [ $# -lt 4 ]
    then
       echo "*****"
       echo "Usage: vmclone.sh \"BASE_VM_NAME\" \"BASE_VMX_FILE\" \"BASE_VMDK_FILE\" \"CLONE_VM_NAME\""
       echo " "
       echo "Example: vmclone.sh \"BIG SERVER\" \"SLES_9.vmx\" \"BigTuna.vmdk\" \"BIGGER_SERVER\""
       echo " "
       echo "==> WARNING! Do not use this script if the .VMDK files are split into 2GB chunks."
       echo "==> Usage Steps:"
       echo "==> ** This new version of vmclone will create the snapshot for you if it does not already exist."
       echo "==> Step 1) Change directory INTO the folder of your BASE VM and then run vmclone."
       echo "==> More usage options can be found in the script itself - \"more vmclone.sh\"."
       echo " "
       echo "==> Some more usage examples:"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" TIMMAY start"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" NODES multi 4"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" WIN_CLUSTER cluster 3"
       echo " "
       echo "==> VMClone Version: $VER"
       echo "*****"
       exit
    fi
    
    # Check for ROOT permissions.
    if [ $EUID -ne "0" ]
    then
       echo " "
       echo "Effective permissions not ROOT."
       echo "Please run this script as ROOT user."
       echo " "
       exit
    fi
    
    # Set some initial variables...
    B_NAME=$1
    B_VMX=$2
    B_VMDK=$3
    C_NAME=$4
    REN_CMD="`which vmware-vdiskmanager`"
    SNAP_CMD="`which vmrun`"
    VM_CMD="`which vmware-cmd`"
    B_PATH="`pwd`"
    
    # Check if OPTION is specified...
    if [ -n "$5" ]
    then
       OPTION=$5
    fi
    
    # Figure out the snapshot file name.
    B_SNAP=`echo "$B_VMDK" | sed 's/.vmdk/-000001.vmdk/'`
    
    
    
    #################
    # FUNCTION LIST #
    #################
    
    
    
    # Define some useful functions...
    # Check if snapshot is already done - if not, create the snapshot.
    check_for_snap ()
    {
       if [ ! -e "$B_SNAP" ]
       then
          $VM_CMD -s register "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
          $SNAP_CMD snapshot "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
       fi
    }
    
    
    # Assumes CWD is $B_NAME - after clone creation, returns to $B_NAME.
    make_clone ()
    {
       if [ "$OPTION" = "cluster" ]
       then
          mkdir -p ../"$CL_BASE"/"$C_NAME"
       else
          mkdir ../"$C_NAME"
       fi
       cp "$B_VMX" "$C_NAME.vmx"
       rm -f *.vmsn
       rm -f *.vmsd
       if [ "$OPTION" = "cluster" ]
       then
          mv "$C_NAME.vmx" ../"$CL_BASE"/"$C_NAME"
          mv "$B_SNAP" ../"$CL_BASE"/"$C_NAME"
       else
          mv "$C_NAME.vmx" ../"$C_NAME"
          mv "$B_SNAP" ../"$C_NAME"
       fi
    
       # Replace the snapshot disk in B_VMX so that another snap can be taken.
       cat "$B_VMX" | sed 's/'"$B_SNAP"'/'"$B_VMDK"'/g' > "$B_VMX.new"
       mv "$B_VMX.new" "$B_VMX"
    
       if [ "$OPTION" = "cluster" ]
       then
          cd ../"$CL_BASE"/"$C_NAME"
       else
          cd ../"$C_NAME"
       fi
       # Now that we're in the clone's dir, set $C_PATH.
       C_PATH="`pwd`"
       $REN_CMD -q -n "$B_SNAP" "$C_NAME.vmdk" 2>/dev/null >/dev/null
       if [ "$OPTION" = "cluster" ]
       then
          ln -s ../../"$B_NAME"/"$B_VMDK" "$B_VMDK"
       else
          ln -s ../"$B_NAME"/"$B_VMDK" "$B_VMDK"
       fi
    
       # Edit the clone's VMX to reflect the new VMDK name and console display name.
       cat "$C_NAME.vmx" | sed 's/'"$B_SNAP"'/'"$C_NAME"'.vmdk/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       cat "$C_NAME.vmx" | sed 's/'"$B_NAME"'/'"$C_NAME"'/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       chmod 754 *
    
       # Register the clone with VM Server *if not* a cluster node.
       if [ "$OPTION" != "cluster" ]
       then
          $VM_CMD -s register "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    
       # CD back into the BASE VM dir.
       if [ "$OPTION" = "cluster" ]
       then
          cd ../../"$B_NAME"
       else
          cd ../"$B_NAME"
       fi
    }
    
    
    # Creates shared disks, adds shared disks to node VMX files, and adds 2 NIC's to node VMX files.
    add_cluster_resources ()
    {
       # Create the shared disks.
       mkdir ../"$CL_BASE"/SHARED
       cd ../"$CL_BASE"/SHARED
       for ((i=1; i <= $NUM_SH_DISKS; i++))
       do
          SH_DISK_NAME="$CL_BASE-D$i.vmdk"
          $REN_CMD -c -s "$SZ_SH_DISKS"Mb -a lsilogic -t 2 $SH_DISK_NAME 2>/dev/null >/dev/null
       done
       
       # Add the shared disks into the NODES' VMX files.
       for ((i=1; i <= REPS; i++))
       do
          N_FILE="../$CL_BASE-N$i/$CL_BASE-N$i.vmx"
          echo "disk.locking = \"FALSE\"" >> $N_FILE
          echo "diskLib.dataCacheMaxSize = \"0\"" >> $N_FILE
          echo "scsi3.sharedBus = virtual" >> $N_FILE
          echo "scsi3.present = \"TRUE\"" >> $N_FILE
          echo "scsi3.virtualDev = \"lsilogic\"" >> $N_FILE
          for ((z=1; z <= $NUM_SH_DISKS; z++))
          do
             if [ $z -lt 7 ]
             then
                echo "scsi3:$z.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$z.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.mode = \"independent-persistent\"" >> $N_FILE
             else
                # Must skip ID 7 when setting SCSI ID.
                let y=$z+1
                echo "scsi3:$y.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$y.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.mode = \"independent-persistent\"" >> $N_FILE
             fi
          done
       done
    
       # Check if more than 1 NIC preset - if not, add 2 NIC's on HOSTONLY network.
       # Since they are clones, we can just check the first node's VMX.
       cd ../"$CL_BASE-N1"
       if grep -q "Ethernet1.present" "$CL_BASE-N1.vmx"
       then
          echo " "
          echo "Cluster Nodes appear to already have more than one NIC - not adding any NIC's."
          cd ..
       else
          echo " "
          echo "Cluster Nodes have 1 NIC - adding 2 more NIC's to the HOSTONLY network..."
          # Grab the name of the NIC device in use.
          NIC_LINE="`grep Ethernet0.virtualDev \"$CL_BASE-N1.vmx\"`"
          NIC1="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet1'/g'`"
          NIC2="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet2'/g'`"
          cd ..
          for ((i=1; i <= REPS; i++))
          do
             N_FILE="$CL_BASE-N$i"/"$CL_BASE-N$i.vmx"
             echo "Ethernet1.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet1.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC1" >> $N_FILE
             echo "Ethernet2.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet2.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC2" >> $N_FILE
          done
       fi
       cd "$B_PATH"
    }
    
    register_cluster_nodes ()
    {
       # Do this last because we want to add the shared disks and NIC's before updating VM Server.
       for ((i=1; i <= REPS; i++))
       do
          cd ../"$CL_BASE"/"$CL_BASE-N$i"
          L_PATH="`pwd`"
          $VM_CMD -s register "$L_PATH"/"$CL_BASE-N$i.vmx" 2>/dev/null >/dev/null
          cd "$B_PATH"
       done
    }
    
    
    ########
    # MAIN #
    ########
    
    
    
    # If OPTION is "multi", then we need to create multiple clones, using C_NAME as a base name.
    if [ "$OPTION" = "multi" ]
    then
       # If $6 is a valid number of clones between 2 and 10, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 10 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, MULTI was specified, but the number of VM's to create was not between 2 and 10."
          echo "Please try again."
          echo " "
          exit
       fi
    
       #Save the base name before calling make_clone() multiple times.
       M_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$M_BASE-$i"
          check_for_snap
          make_clone
       done
    
    #Check for "cluster" option.
    elif [ "$OPTION" = "cluster" ]
    then
       # If $6 is a valid number of cluster nodes between 2 and 5, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 5 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, CLUSTER was specified, but the number of NODES to create was not between 2 and 5."
          echo "Please try again."
          echo " "
          exit
       fi
       #Prompt for the size of the shared disks - in MB.
       #And prompt for how many. Valid = 1 to 14 (beyond that is another SCSI bus.)
       #Warn user that this requires full disk space.
       echo " "
       echo "Cluster was specified - if this is not correct, use CONTROL-C to exit."
       echo "Creating shared disks...NOTE that the shared disks require full disk space."
       echo "IE - (4) disks @ 500MB = 2GB used disk space."
       echo " "
       echo -n "How many shared disks to create? (Valid = 1 to 14):"
       read NUM_SH_DISKS
       echo -n "And what size for the shared disks - in MB? (Valid = 100 to 2048):"
       read SZ_SH_DISKS
       if [ $NUM_SH_DISKS -lt 1 ] || [ $NUM_SH_DISKS -gt 14 ] 
       then
          echo "The number of disks is invalid - exiting..."
          echo " "
          exit 5
       fi
       if [ $SZ_SH_DISKS -lt 100 ] || [ $SZ_SH_DISKS -gt 2048 ]
       then
          echo "The size of the shared disks is invalid - exiting..."
          echo " "
          exit 5
       fi
    
       #Save the cluster name before calling make_clone() multiple times.
       CL_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$CL_BASE-N$i"
          check_for_snap
          make_clone
       done
       # Testing...
       echo " "
       echo "Adding $NUM_SH_DISKS shared disks at $SZ_SH_DISKS MB each..."
       add_cluster_resources
       register_cluster_nodes
    
    else
       # No OPTION - single clone to create.
       check_for_snap
       make_clone
       # If $OPTION "start" was specified, start the clone VM.
       if [ -n "$OPTION" ] && [ "$OPTION" = "start" ]
       then
          $SNAP_CMD start "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    fi
    
    
    echo " "
    echo "Linked clone(s) created successfully..."
    echo "Within a few seconds, you should see the clone VM listed in the VM Console."
    echo " "
    echo " "
    
    exit
    There is also more README info as well - such as the DISPLAY NAME in VMWare should match the FOLDER NAME in the filesystem.

  4. #4
    Just Joined!
    Join Date
    Aug 2008
    Posts
    11
    Thanks for the quick reply.
    I saw the caveat about the 2GB chunks and it's not set up that way. I'll try this one. THanks.

  5. #5
    Just Joined!
    Join Date
    Aug 2008
    Posts
    11
    Quote Originally Posted by HROAdmin26 View Post
    Here is the latest and greatest - it includes an option to create clusters. The script does *not* do a lot of error checking, so if your VM is not set up correctly, the results may vary.

    Note that the VMDK file cannot be split into 2GB chunks.

    Code:
    #!/bin/bash
    
    # VMClone.sh
    # Small shell script to create *linked clones* on VMWare Server.
    
    # Author: HROAdmin26
    # Last Edited: 2008-04-22
    # Revision: 1.7
    VER="1.7_2008-04-22"
    
    # README:
    # Copy this script to some place in your PATH statement
    # and make it executable - /usr/bin is a good place.
    # On the command line, CD into the directory of your base VM.
    # Run vmclone.sh with no switches for the HELP info.
    
    # Run script as ROOT.
    # DO NOT use if your guest VMDK's are split into 2GB chunks.
    # If any of your names have spaces in them, use quotes.
    
    # Script is run on command line and expects 4 (or more) parameters:
    # $1 = BASE_VM_NAME
    # $2 = BASE_VM_VMX_FILE
    # $3 = BASE_VMDK_FILE
    # $4 = CLONE_VM_NAME/MULTI_BASE_NAME/CLUSTER_NAME
    
    # Example: vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY
    
    # $5 = Extra functionality. These are *NOT combinable.* Current options:
    # 1) If "start" is specified, the cloned VM is registered and started after cloning.
    # 2) If "multi" is specified, it must be followed by a number between 2 and 10 for the number of clones to create. The MULTI_BASE_NAME is appended with -1, -2, etc to name the multiple clones.
    # 3) If "cluster" is specified, it must be followed by a number between 2 and 5 for the number of nodes.
    
    # Examples:
    # 1) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY start
    # 2) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" CLONAL multi 7
    # 3) vmclone.sh "BONGO" "BONGO.vmx" "BIG_DISK.vmdk" NODAL cluster 3
    
    # CAVEATS! PLEASE READ AND UNDERSTAND!
    # > Some users have reported issues if the base VM has more than 1 disk - your mileage may vary. <
    # > Your DISPLAY_NAME for the Base VM in the VMWare Console must match the folder name of the Base VM. <
    # > When using the 'cluster' switch, the shared disks are added on an LSILOGIC adapter. <
    # > When using the 'cluster' switch, a folder named CLUSTER_NAME is created - the nodes and shared disks are created inside this folder. <
    
    
    if [ $# -lt 4 ]
    then
       echo "*****"
       echo "Usage: vmclone.sh \"BASE_VM_NAME\" \"BASE_VMX_FILE\" \"BASE_VMDK_FILE\" \"CLONE_VM_NAME\""
       echo " "
       echo "Example: vmclone.sh \"BIG SERVER\" \"SLES_9.vmx\" \"BigTuna.vmdk\" \"BIGGER_SERVER\""
       echo " "
       echo "==> WARNING! Do not use this script if the .VMDK files are split into 2GB chunks."
       echo "==> Usage Steps:"
       echo "==> ** This new version of vmclone will create the snapshot for you if it does not already exist."
       echo "==> Step 1) Change directory INTO the folder of your BASE VM and then run vmclone."
       echo "==> More usage options can be found in the script itself - \"more vmclone.sh\"."
       echo " "
       echo "==> Some more usage examples:"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" TIMMAY start"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" NODES multi 4"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" WIN_CLUSTER cluster 3"
       echo " "
       echo "==> VMClone Version: $VER"
       echo "*****"
       exit
    fi
    
    # Check for ROOT permissions.
    if [ $EUID -ne "0" ]
    then
       echo " "
       echo "Effective permissions not ROOT."
       echo "Please run this script as ROOT user."
       echo " "
       exit
    fi
    
    # Set some initial variables...
    B_NAME=$1
    B_VMX=$2
    B_VMDK=$3
    C_NAME=$4
    REN_CMD="`which vmware-vdiskmanager`"
    SNAP_CMD="`which vmrun`"
    VM_CMD="`which vmware-cmd`"
    B_PATH="`pwd`"
    
    # Check if OPTION is specified...
    if [ -n "$5" ]
    then
       OPTION=$5
    fi
    
    # Figure out the snapshot file name.
    B_SNAP=`echo "$B_VMDK" | sed 's/.vmdk/-000001.vmdk/'`
    
    
    
    #################
    # FUNCTION LIST #
    #################
    
    
    
    # Define some useful functions...
    # Check if snapshot is already done - if not, create the snapshot.
    check_for_snap ()
    {
       if [ ! -e "$B_SNAP" ]
       then
          $VM_CMD -s register "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
          $SNAP_CMD snapshot "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
       fi
    }
    
    
    # Assumes CWD is $B_NAME - after clone creation, returns to $B_NAME.
    make_clone ()
    {
       if [ "$OPTION" = "cluster" ]
       then
          mkdir -p ../"$CL_BASE"/"$C_NAME"
       else
          mkdir ../"$C_NAME"
       fi
       cp "$B_VMX" "$C_NAME.vmx"
       rm -f *.vmsn
       rm -f *.vmsd
       if [ "$OPTION" = "cluster" ]
       then
          mv "$C_NAME.vmx" ../"$CL_BASE"/"$C_NAME"
          mv "$B_SNAP" ../"$CL_BASE"/"$C_NAME"
       else
          mv "$C_NAME.vmx" ../"$C_NAME"
          mv "$B_SNAP" ../"$C_NAME"
       fi
    
       # Replace the snapshot disk in B_VMX so that another snap can be taken.
       cat "$B_VMX" | sed 's/'"$B_SNAP"'/'"$B_VMDK"'/g' > "$B_VMX.new"
       mv "$B_VMX.new" "$B_VMX"
    
       if [ "$OPTION" = "cluster" ]
       then
          cd ../"$CL_BASE"/"$C_NAME"
       else
          cd ../"$C_NAME"
       fi
       # Now that we're in the clone's dir, set $C_PATH.
       C_PATH="`pwd`"
       $REN_CMD -q -n "$B_SNAP" "$C_NAME.vmdk" 2>/dev/null >/dev/null
       if [ "$OPTION" = "cluster" ]
       then
          ln -s ../../"$B_NAME"/"$B_VMDK" "$B_VMDK"
       else
          ln -s ../"$B_NAME"/"$B_VMDK" "$B_VMDK"
       fi
    
       # Edit the clone's VMX to reflect the new VMDK name and console display name.
       cat "$C_NAME.vmx" | sed 's/'"$B_SNAP"'/'"$C_NAME"'.vmdk/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       cat "$C_NAME.vmx" | sed 's/'"$B_NAME"'/'"$C_NAME"'/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       chmod 754 *
    
       # Register the clone with VM Server *if not* a cluster node.
       if [ "$OPTION" != "cluster" ]
       then
          $VM_CMD -s register "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    
       # CD back into the BASE VM dir.
       if [ "$OPTION" = "cluster" ]
       then
          cd ../../"$B_NAME"
       else
          cd ../"$B_NAME"
       fi
    }
    
    
    # Creates shared disks, adds shared disks to node VMX files, and adds 2 NIC's to node VMX files.
    add_cluster_resources ()
    {
       # Create the shared disks.
       mkdir ../"$CL_BASE"/SHARED
       cd ../"$CL_BASE"/SHARED
       for ((i=1; i <= $NUM_SH_DISKS; i++))
       do
          SH_DISK_NAME="$CL_BASE-D$i.vmdk"
          $REN_CMD -c -s "$SZ_SH_DISKS"Mb -a lsilogic -t 2 $SH_DISK_NAME 2>/dev/null >/dev/null
       done
       
       # Add the shared disks into the NODES' VMX files.
       for ((i=1; i <= REPS; i++))
       do
          N_FILE="../$CL_BASE-N$i/$CL_BASE-N$i.vmx"
          echo "disk.locking = \"FALSE\"" >> $N_FILE
          echo "diskLib.dataCacheMaxSize = \"0\"" >> $N_FILE
          echo "scsi3.sharedBus = virtual" >> $N_FILE
          echo "scsi3.present = \"TRUE\"" >> $N_FILE
          echo "scsi3.virtualDev = \"lsilogic\"" >> $N_FILE
          for ((z=1; z <= $NUM_SH_DISKS; z++))
          do
             if [ $z -lt 7 ]
             then
                echo "scsi3:$z.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$z.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.mode = \"independent-persistent\"" >> $N_FILE
             else
                # Must skip ID 7 when setting SCSI ID.
                let y=$z+1
                echo "scsi3:$y.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$y.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.mode = \"independent-persistent\"" >> $N_FILE
             fi
          done
       done
    
       # Check if more than 1 NIC preset - if not, add 2 NIC's on HOSTONLY network.
       # Since they are clones, we can just check the first node's VMX.
       cd ../"$CL_BASE-N1"
       if grep -q "Ethernet1.present" "$CL_BASE-N1.vmx"
       then
          echo " "
          echo "Cluster Nodes appear to already have more than one NIC - not adding any NIC's."
          cd ..
       else
          echo " "
          echo "Cluster Nodes have 1 NIC - adding 2 more NIC's to the HOSTONLY network..."
          # Grab the name of the NIC device in use.
          NIC_LINE="`grep Ethernet0.virtualDev \"$CL_BASE-N1.vmx\"`"
          NIC1="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet1'/g'`"
          NIC2="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet2'/g'`"
          cd ..
          for ((i=1; i <= REPS; i++))
          do
             N_FILE="$CL_BASE-N$i"/"$CL_BASE-N$i.vmx"
             echo "Ethernet1.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet1.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC1" >> $N_FILE
             echo "Ethernet2.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet2.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC2" >> $N_FILE
          done
       fi
       cd "$B_PATH"
    }
    
    register_cluster_nodes ()
    {
       # Do this last because we want to add the shared disks and NIC's before updating VM Server.
       for ((i=1; i <= REPS; i++))
       do
          cd ../"$CL_BASE"/"$CL_BASE-N$i"
          L_PATH="`pwd`"
          $VM_CMD -s register "$L_PATH"/"$CL_BASE-N$i.vmx" 2>/dev/null >/dev/null
          cd "$B_PATH"
       done
    }
    
    
    ########
    # MAIN #
    ########
    
    
    
    # If OPTION is "multi", then we need to create multiple clones, using C_NAME as a base name.
    if [ "$OPTION" = "multi" ]
    then
       # If $6 is a valid number of clones between 2 and 10, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 10 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, MULTI was specified, but the number of VM's to create was not between 2 and 10."
          echo "Please try again."
          echo " "
          exit
       fi
    
       #Save the base name before calling make_clone() multiple times.
       M_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$M_BASE-$i"
          check_for_snap
          make_clone
       done
    
    #Check for "cluster" option.
    elif [ "$OPTION" = "cluster" ]
    then
       # If $6 is a valid number of cluster nodes between 2 and 5, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 5 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, CLUSTER was specified, but the number of NODES to create was not between 2 and 5."
          echo "Please try again."
          echo " "
          exit
       fi
       #Prompt for the size of the shared disks - in MB.
       #And prompt for how many. Valid = 1 to 14 (beyond that is another SCSI bus.)
       #Warn user that this requires full disk space.
       echo " "
       echo "Cluster was specified - if this is not correct, use CONTROL-C to exit."
       echo "Creating shared disks...NOTE that the shared disks require full disk space."
       echo "IE - (4) disks @ 500MB = 2GB used disk space."
       echo " "
       echo -n "How many shared disks to create? (Valid = 1 to 14):"
       read NUM_SH_DISKS
       echo -n "And what size for the shared disks - in MB? (Valid = 100 to 2048):"
       read SZ_SH_DISKS
       if [ $NUM_SH_DISKS -lt 1 ] || [ $NUM_SH_DISKS -gt 14 ] 
       then
          echo "The number of disks is invalid - exiting..."
          echo " "
          exit 5
       fi
       if [ $SZ_SH_DISKS -lt 100 ] || [ $SZ_SH_DISKS -gt 2048 ]
       then
          echo "The size of the shared disks is invalid - exiting..."
          echo " "
          exit 5
       fi
    
       #Save the cluster name before calling make_clone() multiple times.
       CL_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$CL_BASE-N$i"
          check_for_snap
          make_clone
       done
       # Testing...
       echo " "
       echo "Adding $NUM_SH_DISKS shared disks at $SZ_SH_DISKS MB each..."
       add_cluster_resources
       register_cluster_nodes
    
    else
       # No OPTION - single clone to create.
       check_for_snap
       make_clone
       # If $OPTION "start" was specified, start the clone VM.
       if [ -n "$OPTION" ] && [ "$OPTION" = "start" ]
       then
          $SNAP_CMD start "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    fi
    
    
    echo " "
    echo "Linked clone(s) created successfully..."
    echo "Within a few seconds, you should see the clone VM listed in the VM Console."
    echo " "
    echo " "
    
    exit
    There is also more README info as well - such as the DISPLAY NAME in VMWare should match the FOLDER NAME in the filesystem.

    Still says it can't fin the disk on startup.
    Are you getting this err?

  6. #6
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    o.O

    No. I and ~30 other people use this script almost daily. I sent you a PM.

  7. #7
    Just Joined!
    Join Date
    Aug 2008
    Posts
    11
    I sent a PM, did you get it?

  8. #8
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    Problem solved - Bentman was using a "fully allocated" or "thick" virtual disk where the entire disk space is allocated. VMWare creates a second file (-flat.vmdk) when this option is used. While this kind of defeats the purpose of linked clones and using as little disk space as possible, I updated the script to deal with this scenario:

    Code:
    #!/bin/bash
    
    # VMClone.sh
    # Small shell script to create *linked clones* on VMWare Server.
    
    # Author: HROAdmin26
    # Last Edited: 2008-08-20
    # Revision: 1.8
    VER="1.8_2008-08-20"
    
    # README:
    # Copy this script to some place in your PATH statement
    # and make it executable - /usr/bin is a good place.
    # On the command line, CD into the directory of your base VM.
    # Run vmclone.sh with no switches for the HELP info.
    
    # Run script as ROOT.
    # DO NOT use if your guest VMDK's are split into 2GB chunks.
    # If any of your names have spaces in them, use quotes.
    
    # Script is run on command line and expects 4 (or more) parameters:
    # $1 = BASE_VM_NAME
    # $2 = BASE_VM_VMX_FILE
    # $3 = BASE_VMDK_FILE
    # $4 = CLONE_VM_NAME/MULTI_BASE_NAME/CLUSTER_NAME
    
    # Example: vmclone "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY
    
    # $5 = Extra functionality. These are *NOT combinable.* Current options:
    # 1) If "start" is specified, the cloned VM is registered and started after cloning.
    # 2) If "multi" is specified, it must be followed by a number between 2 and 10 for the number of clones to create. The MULTI_BASE_NAME is appended with -1, -2, etc to name the multiple clones.
    # 3) If "cluster" is specified, it must be followed by a number between 2 and 5 for the number of nodes.
    
    # Examples:
    # 1) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" TIMMAY start
    # 2) vmclone.sh "BOBO" "BOBO.vmx" "BOBO.vmdk" CLONAL multi 7
    # 3) vmclone.sh "BONGO" "BONGO.vmx" "BIG_DISK.vmdk" NODAL cluster 3
    
    # CAVEATS! PLEASE READ AND UNDERSTAND!
    # > Some users have reported issues if the base VM has more than 1 disk - your mileage may vary. <
    # > Your DISPLAY_NAME for the Base VM in the VMWare Console must match the folder name of the Base VM. <
    # > When using the 'cluster' switch, the shared disks are added on an LSILOGIC adapter. <
    # > When using the 'cluster' switch, a folder named CLUSTER_NAME is created - the nodes and shared disks are created inside this folder. <
    
    
    if [ $# -lt 4 ]
    then
       echo "*****"
       echo "Usage: vmclone.sh \"BASE_VM_NAME\" \"BASE_VMX_FILE\" \"BASE_VMDK_FILE\" \"CLONE_VM_NAME\""
       echo " "
       echo "Example: vmclone.sh \"BIG SERVER\" \"SLES_9.vmx\" \"BigTuna.vmdk\" \"BIGGER_SERVER\""
       echo " "
       echo "==> WARNING! Do not use this script if the .VMDK files are split into 2GB chunks."
       echo "==> Usage Steps:"
       echo "==> ** This new version of vmclone will create the snapshot for you if it does not already exist."
       echo "==> Step 1) Change directory INTO the folder of your BASE VM and then run vmclone."
       echo "==> More usage options can be found in the script itself - \"more vmclone.sh\"."
       echo " "
       echo "==> Some more usage examples:"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" TIMMAY start"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" NODES multi 4"
       echo "==> vmclone.sh \"BOBO\" \"BOBO.vmx\" \"BOBO.vmdk\" WIN_CLUSTER cluster 3"
       echo " "
       echo "==> VMClone Version: $VER"
       echo "*****"
       exit
    fi
    
    # Check for ROOT permissions.
    if [ $EUID -ne "0" ]
    then
       echo " "
       echo "Effective permissions not ROOT."
       echo "Please run this script as ROOT user."
       echo " "
       exit
    fi
    
    # Set some initial variables...
    B_NAME=$1
    B_VMX=$2
    B_VMDK=$3
    C_NAME=$4
    REN_CMD="`which vmware-vdiskmanager`"
    SNAP_CMD="`which vmrun`"
    VM_CMD="`which vmware-cmd`"
    B_PATH="`pwd`"
    
    # Check if OPTION is specified...
    if [ -n "$5" ]
    then
       OPTION=$5
    fi
    
    # Figure out the snapshot file name.
    B_SNAP=`echo "$B_VMDK" | sed 's/.vmdk/-000001.vmdk/'`
    
    # If virtual disk is "thick", there will be a -flat.vmdk we need to create an ln -s for.
    B_FLAT=`echo "$B_VMDK" | sed 's/.vmdk/-flat.vmdk/'`
    
    
    #################
    # FUNCTION LIST #
    #################
    
    
    
    # Define some useful functions...
    # Check if snapshot is already done - if not, create the snapshot.
    check_for_snap ()
    {
       if [ ! -e "$B_SNAP" ]
       then
          $VM_CMD -s register "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
          $SNAP_CMD snapshot "$B_PATH"/"$B_VMX" 2>/dev/null >/dev/null
       fi
    }
    
    
    # Assumes CWD is $B_NAME - after clone creation, returns to $B_NAME.
    make_clone ()
    {
       if [ "$OPTION" = "cluster" ]
       then
          mkdir -p ../"$CL_BASE"/"$C_NAME"
       else
          mkdir ../"$C_NAME"
       fi
       cp "$B_VMX" "$C_NAME.vmx"
       rm -f *.vmsn
       rm -f *.vmsd
       if [ "$OPTION" = "cluster" ]
       then
          mv "$C_NAME.vmx" ../"$CL_BASE"/"$C_NAME"
          mv "$B_SNAP" ../"$CL_BASE"/"$C_NAME"
       else
          mv "$C_NAME.vmx" ../"$C_NAME"
          mv "$B_SNAP" ../"$C_NAME"
       fi
    
       # Replace the snapshot disk in B_VMX so that another snap can be taken.
       cat "$B_VMX" | sed 's/'"$B_SNAP"'/'"$B_VMDK"'/g' > "$B_VMX.new"
       mv "$B_VMX.new" "$B_VMX"
    
       if [ "$OPTION" = "cluster" ]
       then
          cd ../"$CL_BASE"/"$C_NAME"
       else
          cd ../"$C_NAME"
       fi
       # Now that we're in the clone's dir, set $C_PATH.
       C_PATH="`pwd`"
       $REN_CMD -q -n "$B_SNAP" "$C_NAME.vmdk" 2>/dev/null >/dev/null
       if [ "$OPTION" = "cluster" ]
       then
          ln -s ../../"$B_NAME"/"$B_VMDK" "$B_VMDK"
          # IF B_FLAT exists, need to create link to it also:
          if [ -e ../../"$B_NAME"/"$B_FLAT" ]
          then
             ln -s ../../"$B_NAME"/"$B_FLAT" "$B_FLAT"
          fi
       else
          ln -s ../"$B_NAME"/"$B_VMDK" "$B_VMDK"
          # IF B_FLAT exists, need to create link to it also:
          if [ -e ../"$B_NAME"/"$B_FLAT" ]
          then
             ln -s ../"$B_NAME"/"$B_FLAT" "$B_FLAT"
          fi
       fi
    
       # Edit the clone's VMX to reflect the new VMDK name and console display name.
       cat "$C_NAME.vmx" | sed 's/'"$B_SNAP"'/'"$C_NAME"'.vmdk/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       cat "$C_NAME.vmx" | sed 's/'"$B_NAME"'/'"$C_NAME"'/g' > "$C_NAME.new"
       mv "$C_NAME.new" "$C_NAME.vmx"
       chmod 754 *
    
       # Register the clone with VM Server *if not* a cluster node.
       if [ "$OPTION" != "cluster" ]
       then
          $VM_CMD -s register "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    
       # CD back into the BASE VM dir.
       if [ "$OPTION" = "cluster" ]
       then
          cd ../../"$B_NAME"
       else
          cd ../"$B_NAME"
       fi
    }
    
    
    # Creates shared disks, adds shared disks to node VMX files, and adds 2 NIC's to node VMX files.
    add_cluster_resources ()
    {
       # Create the shared disks.
       mkdir ../"$CL_BASE"/SHARED
       cd ../"$CL_BASE"/SHARED
       for ((i=1; i <= $NUM_SH_DISKS; i++))
       do
          SH_DISK_NAME="$CL_BASE-D$i.vmdk"
          $REN_CMD -c -s "$SZ_SH_DISKS"Mb -a lsilogic -t 2 $SH_DISK_NAME 2>/dev/null >/dev/null
       done
       
       # Add the shared disks into the NODES' VMX files.
       for ((i=1; i <= REPS; i++))
       do
          N_FILE="../$CL_BASE-N$i/$CL_BASE-N$i.vmx"
          echo "disk.locking = \"FALSE\"" >> $N_FILE
          echo "diskLib.dataCacheMaxSize = \"0\"" >> $N_FILE
          echo "scsi3.sharedBus = virtual" >> $N_FILE
          echo "scsi3.present = \"TRUE\"" >> $N_FILE
          echo "scsi3.virtualDev = \"lsilogic\"" >> $N_FILE
          for ((z=1; z <= $NUM_SH_DISKS; z++))
          do
             if [ $z -lt 7 ]
             then
                echo "scsi3:$z.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$z.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$z.mode = \"independent-persistent\"" >> $N_FILE
             else
                # Must skip ID 7 when setting SCSI ID.
                let y=$z+1
                echo "scsi3:$y.present = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.fileName = \"../SHARED/$CL_BASE-D$z.vmdk\"" >> $N_FILE
                echo "scsi3:$y.writeThrough = \"TRUE\"" >> $N_FILE
                echo "scsi3:$y.mode = \"independent-persistent\"" >> $N_FILE
             fi
          done
       done
    
       # Check if more than 1 NIC preset - if not, add 2 NIC's on HOSTONLY network.
       # Since they are clones, we can just check the first node's VMX.
       cd ../"$CL_BASE-N1"
       if grep -q "Ethernet1.present" "$CL_BASE-N1.vmx"
       then
          echo " "
          echo "Cluster Nodes appear to already have more than one NIC - not adding any NIC's."
          cd ..
       else
          echo " "
          echo "Cluster Nodes have 1 NIC - adding 2 more NIC's to the HOSTONLY network..."
          # Grab the name of the NIC device in use.
          NIC_LINE="`grep Ethernet0.virtualDev \"$CL_BASE-N1.vmx\"`"
          NIC1="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet1'/g'`"
          NIC2="`echo "$NIC_LINE" | sed 's/'Ethernet0'/'Ethernet2'/g'`"
          cd ..
          for ((i=1; i <= REPS; i++))
          do
             N_FILE="$CL_BASE-N$i"/"$CL_BASE-N$i.vmx"
             echo "Ethernet1.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet1.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC1" >> $N_FILE
             echo "Ethernet2.present = \"TRUE\"" >> $N_FILE
             echo "Ethernet2.connectionType = \"hostonly\"" >> $N_FILE
             echo "$NIC2" >> $N_FILE
          done
       fi
       cd "$B_PATH"
    }
    
    register_cluster_nodes ()
    {
       # Do this last because we want to add the shared disks and NIC's before updating VM Server.
       for ((i=1; i <= REPS; i++))
       do
          cd ../"$CL_BASE"/"$CL_BASE-N$i"
          L_PATH="`pwd`"
          $VM_CMD -s register "$L_PATH"/"$CL_BASE-N$i.vmx" 2>/dev/null >/dev/null
          cd "$B_PATH"
       done
    }
    
    
    ########
    # MAIN #
    ########
    
    
    
    # If OPTION is "multi", then we need to create multiple clones, using C_NAME as a base name.
    if [ "$OPTION" = "multi" ]
    then
       # If $6 is a valid number of clones between 2 and 10, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 10 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, MULTI was specified, but the number of VM's to create was not between 2 and 10."
          echo "Please try again."
          echo " "
          exit
       fi
    
       #Save the base name before calling make_clone() multiple times.
       M_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$M_BASE-$i"
          check_for_snap
          make_clone
       done
    
    #Check for "cluster" option.
    elif [ "$OPTION" = "cluster" ]
    then
       # If $6 is a valid number of cluster nodes between 2 and 5, set REPS.
       if [ -n "$6" ] && [ $6 -ge 2 ] && [ $6 -le 5 ]
       then
          REPS=$6
       else
          echo " "
          echo "Sorry, CLUSTER was specified, but the number of NODES to create was not between 2 and 5."
          echo "Please try again."
          echo " "
          exit
       fi
       #Prompt for the size of the shared disks - in MB.
       #And prompt for how many. Valid = 1 to 14 (beyond that is another SCSI bus.)
       #Warn user that this requires full disk space.
       echo " "
       echo "Cluster was specified - if this is not correct, use CONTROL-C to exit."
       echo "Creating shared disks...NOTE that the shared disks require full disk space."
       echo "IE - (4) disks @ 500MB = 2GB used disk space."
       echo " "
       echo -n "How many shared disks to create? (Valid = 1 to 14):"
       read NUM_SH_DISKS
       echo -n "And what size for the shared disks - in MB? (Valid = 100 to 2048):"
       read SZ_SH_DISKS
       if [ $NUM_SH_DISKS -lt 1 ] || [ $NUM_SH_DISKS -gt 14 ] 
       then
          echo "The number of disks is invalid - exiting..."
          echo " "
          exit 5
       fi
       if [ $SZ_SH_DISKS -lt 100 ] || [ $SZ_SH_DISKS -gt 2048 ]
       then
          echo "The size of the shared disks is invalid - exiting..."
          echo " "
          exit 5
       fi
    
       #Save the cluster name before calling make_clone() multiple times.
       CL_BASE="$C_NAME"
       for ((i=1; i <= REPS; i++))
       do
          C_NAME="$CL_BASE-N$i"
          check_for_snap
          make_clone
       done
       # Testing...
       echo " "
       echo "Adding $NUM_SH_DISKS shared disks at $SZ_SH_DISKS MB each..."
       add_cluster_resources
       register_cluster_nodes
    
    else
       # No OPTION - single clone to create.
       check_for_snap
       make_clone
       # If $OPTION "start" was specified, start the clone VM.
       if [ -n "$OPTION" ] && [ "$OPTION" = "start" ]
       then
          $SNAP_CMD start "$C_PATH"/"$C_NAME.vmx" 2>/dev/null >/dev/null
       fi
    fi
    
    
    echo " "
    echo "Linked clone(s) created successfully..."
    echo "Within a few seconds, you should see the clone VM listed in the VM Console."
    echo " "
    echo " "
    
    exit

  9. #9
    Just Joined!
    Join Date
    Aug 2008
    Posts
    11
    I was wondering. I have a directory of /var/vm that holds my vm's. I'd like to store all of my images in /var/vm/images. When I run the script to create the linked clone in the /var/vm directory. This help's me keep the directory clean.

    I'm certainly no bash script master, any help would be appreciated.

  10. #10
    Just Joined!
    Join Date
    Sep 2008
    Posts
    9
    Can I use this script on vmware workstation on Linux? If we have hundred of master images on a SAN, each time we update the master image the linked clones will die. I am trying to find a way to easily create new linked clones for each workstation...

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...