Deployment Lifecycle Scripts

Script Workflow

Scripts can be called at multiple points during a deployment. The following images depict the execution process for each service workflow:

Node Initialization Workflow

The following image shows the node initialization workflow. nodeintworkflow 4.10

External Initialization Workflow for VM tiers.

See External Service for additional context.

The following image shows the external initialization workflow for VM tiers.

extinitvmbased4.10

External Initialization Workflow

For non-VM tiers like application tiers. See External Service for additional context.

The following image shows the external initialization workflow. extservapptier410

Node Reboot Workflow

Triggered from either the VM Reboot or Suspend/Resume action in the Deployments page.

The Suspend script is similar to the Resume script that is triggered when the node is suspended.

The following image shows the node reboot workflow. nodereboot4.10

Node Update Workflow

Triggered by a VM scaling action or a reboot on other VMs.

The following image shows the node update workflow.

nodeupdate4.10

Node Terminate Workflow

Requires all nodes to be running in order for the application to be powered off.

The following image shows the node terminate workflow.

nodeterminate410

Script Categories

Service lifecycle actions can be divided into two categories:

  • Service Scripts: Each service script corresponds to a Service Lifecycle Actions. See Service Administration for additional context. Once the root admin configures the services and makes it available to users, users can access the service and add on their own application scripts to each service or tier as required.

  • Application Scripts: Users specify each application script when modeling an application or application profile. The New Application and New Application Profile sections provide more details on these scripts.

Using Scripts in Application Profiles

While the Topology Modeler > Services tab (or palette) allows the root admin to add on the required services for each user or tenant, the Topology Modeler > Properties tab allows users to initialize, clean up, or resume the app tier. The following images highlight the application script configuration location in the Topology Modeler's Properties tab.

  • Service Initialization Pre-Start and Post-Start as displayed in the following screenshot:

  • Node Initialization and Clean Up as displayed in the following screenshot:

  • External Initialization (see External Service for additional context) as displayed in the following screenshot:

  • Similarly, you will also find the Migration and Upgrade in the configuration location in the Topology Modeler's Properties tab.

Script Source Details

The different script sources are explained in the following table.

Sourcing MethodsDescriptionAdditional Details
Repositories

Points to a repository hosted in the external site (such as HTTP or Amazon S3).

See Artifact Repository

File in package

The script resides in the Application Content Package.

See Application Using App Package
URL or Command

A URL Points to a file that is downloaded and executed by the Management Agent. This URL can point to any location relevant to this service.

A command (shell or powershell direct commands) is used to run all service-related actions. For example: apt-get install foo, or echo hello, or rerun cliqr, and so forth.

The script option does not work when using the command line. Instead, use the URL option and add a script URL.

See Parameters and Macros

Script from bundle (for Service Lifecycle Actions)

The script path is a relative path inside the extracted folder (/usr/local/osmosix/service).

The name of the bundle directory must match the name displayed in the Identifier field. This step is essential – the service cannot be created if the name or the relative path differs.

This action is only available if the service points to a bundle Location.

See Bundle Store – Repo (Conditional)

Lifecycle Action Script Definition

This section explains the level and details required to define and use each script.

See the following sections for additional information on the lifecycle action script definition at each level:

All scripts are executed from the current script directory and allow multiple scripts to be issued at the same time.

Script Download Owner Permission

The download owner permission for all scripts at all levels is root (-rwxr-xr-x).

The following table identifies the level and details required to define and use each script.

 ScriptLevel of Script

Definition

Script Download LocationUser Running ScriptScript Run Location
Pre-VM StartRegion



  • /opt/remoteFiles/cliqr_local_file/
  • C:\temp\remoteFiles\cliqr_local_file\



cliqruser




Same as Script Download Location




Pre-VM Init
Post-VM Init
Pre-VM Stop
Post-VM Stop
InstallService







  • /usr/local/osmosix/service/{serviceName}/
  • C:\program files\osmosix\service\{serviceName}\
root







Same as Script Download Location
Configure
Deploy
Start
Stop
Restart
Reload
Upgrade
Clean Up
Pre-VM StartService
  • /opt/remoteFiles/cliqr_local_file/
  • C:\temp\remoteFiles\cliqr_local_file\

cliqruser

Same as Script Download Location
Pre-VM Init
Post-VM Init
Pre-VM Stop
Post-VM Stop
Initialization ScriptApplication
  • /opt/remoteFiles/initScript/
  • C:\temp\remoteFiles\initScript\
Agent user (typically cliqruser)Same as Script Download Location
Cleanup Script
  • /opt/remoteFiles/cleanupScript/
  • C:\temp\remoteFiles\cleanupScript\

cliqruser

  • Resume Script
  • Suspend Script
  • /opt/remoteFiles/resumeScript/
  • C:\temp\remoteFiles\resumeScript\
Agent user (typically cliqruser)
Pre-Start Script

Application

(Service Initialization)






  • /opt/remoteFiles/cliqr{serviceName}PreStartAction/
  • C:\temp\remoteFiles\cliqr{serviceName}PreStartAction\

cliqruser

/usr/local/jetty/
Post-Start Script
  • /opt/remoteFiles/cliqr{serviceName}PostStartAction/
  • C:\temp\remoteFiles\cliqr{serviceName}PostStartAction\
Pre-Stop Script
  • /opt/remoteFiles/cliqr{serviceName}PreStopAction/
  • C:\temp\remoteFiles\cliqr{serviceName}PreStopAction\
Post-Stop Script
  • /opt/remoteFiles/cliqr{serviceName}PostStopAction/
  • C:\temp\remoteFiles\cliqr{serviceName}PostStopAction\
VM Pre-provision Script
  • /opt/remoteFiles/cliqr_local_file/
  • C:\temp\remoteFiles\cliqr_local_file\
Same as Script Download Location
VM Pre-initialization Script
VM Post-start ScriptApplication (External Initialization)


  • /opt/remoteFiles/cliqr_local_file/
  • C:\temp\remoteFiles\cliqr_local_file\

cliqruser

Same as Script Download Location
VM Pre-terminate Script
VM Post-terminate Script
Pre Migrate ScriptApplication
  • /opt/remoteFiles/preMigrateScript/
  • C:\temp\remoteFiles\preMigrateScript\
Agent user (typically cliqruser)/home/cliqruser/
Backup Script
  • /opt/remoteFiles/backupScript/
  • C:\temp\remoteFiles\backupScript\
Restore Script
  • /opt/remoteFiles/restoreScript/
  • C:\temp\remoteFiles\restoreScript\

cliqruser

/usr/local/jetty/
Post Migrate Script
  • /opt/remoteFiles/postMigrateScript/
  • C:\temp\remoteFiles\postMigrateScript\
Pre Upgrade Script
  • /opt/remoteFiles/upgradeScript/
  • C:\temp\remoteFiles\upgradeScript\
Upgrade Script
Post Upgrade Script
Rollback Script

The dynamically-generated VM password is injected as part of the lifecycle action and made available for use inside External scripts.

  • Windows deployments: The password for cliqr users is available in the cliqrWindowsPassword environment variable in the pre-Init, post-start, pre-terminate, and post-terminate phases.

  • Linux deployments:

    • The user name is available in the sshUserName environment variable

    • The SSH private key is available in the sshKey environment variable.

    • The SSH public key is available in the sshPublicKey environment variable

Utility Files

Users can also include utility files in scripts.

The Request Utility, for both Linux and Windows requires that the repo server you refer to use the HTTP or HTTPS protocol.


The following are some examples of utility files that can be sourced by Linux users:

  • Environment Variables: /usr/local/osmosix/etc/userenv

  • OS Information: /usr/local/osmosix/service/utils/os_info_util.sh

  • Service Install Utility: /usr/local/osmosix/service/utils/install_util.sh

  • Configuration Utility: /usr/local/osmosix/service/utils/cfgutil.sh

  • Request Utility: /usr/local/osmosix/etc/request_util.sh (send request to agent to download a file or folder from the repo)

The following are utility files that can be sourced by Windows users:

  • Environment Variables: c:\temp\userenv.ps1

  • Utility Information: c:\Program Files\osmosix\etc\cliqr.ps1

  • Request Utility: c:\Program Files\osmosix\etc\request_util.ps1

In earlier releases, users were able to use special characters in the userenv file. However, sourcing files with these special characters caused issues in scripts that used the userenv file.

  • Special characters like pipe or double quotes are configured with escape sequences that use single quotes, not double quotes.

  • An example:

    export nameOfVar = 'ExampleABC'
  • You can successfully source userenv files that contain these special characters.

Accessing Files from a Configured Repo

While you can use the File in Package option to model an Application Using App Package, this option bundles the required files into a zip file that you can download.

Alternately, you may also opt to download something from inside a script that is stored in a configured repository. For example, you have configured a file in a repository called MyFiles for your lifecycle scripts using the HTTP protocol and have it password protected, as well as configured a nodeInit script called myscript as follows:

Repo: MyFiles, path:/myscript.sh

Later, you may need another user to download a file from the same MyFiles repo without knowing the credentials or the contents for either agent-based and external actions.

The following table provides usage details on accessing a file from a configured repository. 

Usage 

SyntaxExample

download $<relative folder path on repo> <node service step>

download <path_on_repo>/<filename.txt> <initScript/ prestart/ poststart/ prestop/ poststop>

download auto/record_results.sh initScript

The file is downloaded to /opt/remoteFiles

backupFile $<relative file path on repo> $<location of local file to be backup >

backupFile <path_backup_folder_on_repo>/<backup_filename.txt> /tmp/test_backup.txt

backupFile $CliqrDeploymentId/dbbakup.sql /tmp/dbbakup.sql

restoreFile $<relative file path on repo>

restoreFile <path_backup_folder_on_repo>/<backup_fliename.txt>restoreFile $migrateFromDepId/wpbkup.zip

Parameters and Configuration Files

CloudCenter-Defined Parameters are also available for use in application profiles to automate jobs without writing extensive scripts (examples include timestamp, dynamically-generated IP address, private IP address, IP address of a tier, environment variables, automation policy parameters, number of nodes in a cluster, deployment name, and so forth).

Sometimes, you may have a custom parameter already defined in a particular service that you do not want to set in the application profile. Instead, you want to leave it to your end users to Substitute a Parameter or use Troubleshooting Parameters when they model application profiles or deploy applications.

If you use parameters (either CloudCenter-Defined Parameters or Substitute Parameters), you may need to Modify the Service Configuration Files to reflect the correct property defined in the relevant parameter.

Internal Reboot During Node Initialization

The reboot referenced above is initiated externally when a user reboots the VM, or issues a Suspend/Resume command, or a direct OS reboot command. This reboot usually happens after the node is fully initialized and running. 

Another reboot scenario is the internal reboot – when the reboot is part of node initialization process. This reboot is initiated by the management agent. Once the agent detects the .cliqrRebootResumeInit flag, it performs a backup and reboots itself.

You can setup multiple stage node init scripts by using appropriate flow-control logic and manipulating the following files:

  • /tmp/.cliqrRebootResumeInit 
  • $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit

    $OSMOSIX_PROD_HOME defaults to /usr/local/osmosix

The CloudCenter platform executes each pass in order, picking up where it left off each time. Consider the following sample scripts:

  • Linux
    #!/bin/bash
    # Make sure to source these files to pick up all the CloudCenter environment variables.
    . /usr/local/osmosix/etc/.osmosix.sh
    . /usr/local/osmosix/etc/userenv
      
    # After triggered reboot, the agent generates file $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit
    # with prior state from /tmp/.cliqrRebootResumeInit
     
    # If this file DOES NOT exist, it means that this is the first pass through the script.
    # The agent has not previously triggered a reboot and created this file.
    if [ ! -e $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit ];
    then
        # Node was not rebooted already by nodeInit. First pass through this script.
     
        # Triggers a reboot after the script exits, then this file is deleted.
        # "Step 2" will now appear in $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit
        echo "Part 2" > /tmp/.cliqrRebootResumeInit
    else
        # Node was rebooted on the last pass through the script.
        # Read in prior state from file generated by CloudCenter
        step=`cat $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit`
     
        # Check the prior state to continue with the next part of the script.
        case $step in
            "Part 2")
                # Triggers a reboot after the script exits, then this file is deleted.
                # "Step 3" will now appear in $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit
                echo "Part 3" > /tmp/.cliqrRebootResumeInit
                ;;
            "Part 3")
                # Don't write to /tmp/.cliqrRebootResumeInit this time. The CloudCenter platform will not reboot.
                # Script exists, and node init is complete.
                ;;
        esac
    fi
  • Windows
    #Set the "numOfReboots" variable to reflect the number of reboots required. In #this example the VM will be rebooted 5 times.
    
    
    $startTime = Get-Date
    $VerbosePreference = "Continue" 
    $numOfReboots = 5 
    $logPath = "C:\nodeinit"
    $logFile = "cliqr-nodeinitlog.txt"
    $envscript = ' c:\temp\userenv.ps1'
    $agent_utils = ". 'C:\Program Files\osmosix\service\utils\agent_util.ps1'"
    $tmpfolder = "C:\tmp"
    $logfolderFlag = 1
    $tmpFolderFlag = 1
    $logFileCreationFlag = 1
    
    Invoke-Expression $envscript
    Invoke-Expression $agent_utils
    
    if (!(Test-Path $logPath)){
        $logDir = New-Item -ItemType Dir $logPath 
     } else {
        $logfolderFlag = 0
     }
    
    
    if (!(Test-Path $tmpfolder)){
        $tmpDir = New-Item -ItemType Dir $tmpfolder 
    } else {
        $tmpDir = $tmpfolder
        $tmpFolderFlag = 0
    }
    
    $logFilePath = Join-Path $logPath $logFile
    if (!(Test-Path $logFilePath)){
        $logFile = New-Item -ItemType File (Join-Path $logPath $logFile) 
    } else {
        $logFile = $logFilePath
        $logFileCreationFlag = 0
    }
    
    
    function print($line,$logFileHandle) {
        $timestamp = get-date
        $line = [string]$timestamp + " : INFO " + $line
        Write-Output $line >> $logFileHandle
        Write-Verbose $line
        agentSendLogMessage $line
        
    }
    
    
    ############MAIN ##########################
    
    $resumeinitfile1 = Join-Path (Get-ChildItem env:OSMOSIX_HOME).Value ".cliqrRebootResumeInit"
    $resumeinitfile2 = Join-Path $tmpDir ".cliqrRebootResumeInit"
    
    if (! (Test-Path $resumeinitfile1)) {
       #Checking for existence of file for first reboot. If not then create the flag file 
       print "File .cliqrRebootResumeInit not created yet" $logFile
       Write-Output "RC=1" > $resumeinitfile2
       print "Restart Count = 1" $logFile    
    } else {
       #For subsequent reboots flag file will exist in a different location
       print "File '$resumeinitfile1' Found" $logFile 
       $data = gc $resumeinitfile1
       $rcCount = $data.trim().split("=")[-1]
       print "Data from $resumeinitfile1 file => $data" $logFile
         
       if ([int]$rcCount -lt $numOfReboots) {
            $rcCount = [int]$rcCount + 1
            $strdata = "RC=" + $rcCount 
            print "Writing data '$strdata' to file '$resumeinitfile2'" $logFile
            Write-Output $strdata > $resumeinitfile2
       }
       print "Restart Count = $rcCount" $logFile     
       
    }
    
    $VerbosePreference = "SilentlyContinue" 

The #!CliQrReboot: Header

The #!CliQrReboot: header to the /tmp/.cliqrRebootResumeInit file – Once the agent detects the #!CliQrReboot: header, it resumes after a reboot in the service lifecycle flow depending upon the context set in the header. You can control the resume flow after reboot by adding the resume context header to the /tmp/.cliqrRebootResumeInit file. 

For example, #!CliQrReboot:Current as a header allows you to resume the current lifecycle action. Similarly, #!CliQrReboot:Next to resume to next step in the lifecycle actions and #!CliQrReboot:Deploy to resume from deploy service lifecycle actions. Consider the following sample scripts:

  • The following sample Linux script reboots twice and resumes the same lifecycle action after the reboot. The resume context is only supported in a deployment's deploy flow. It is not supported during the deployment suspend, resume or terminate flows.

    Linux Sample Script
    #!/bin/bash
    
    . /usr/local/osmosix/service/utils/agent_util.sh
    . /usr/local/osmosix/etc/userenv
    . /usr/local/osmosix/etc/.osmosix.sh
    
    
    action=$1
    
    if [ $2 == "reboot" ]; then
        if [ ! -e $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit ]; then
            action="$action-step-1"
            agentSendLogMessage "Calling First Reboot... $action"
            echo "#!CliQrReboot:Current" > /tmp/.cliqrRebootResumeInit
            echo "2" > ~/step
        else
            step=`cat ~/step`
            case $step in
                "2")
                    action="$action-step-2"
                    agentSendLogMessage "Calling Second Reboot... $action"
                    echo "#!CliQrReboot:Current" > /tmp/.cliqrRebootResumeInit
                    echo "3" > ~/step
                    ;;
                *)
                    action="$action-step-3"
                    agentSendLogMessage "Resuming after Final Reboot... $action"
                    rm -fr ~/step
                    rm -fr $OSMOSIX_PROD_HOME/.cliqrRebootResumeInit
                    ;;
            esac
        fi
    fi
    


  • The following Windows sample script takes two parameters (action and reboot)

    To use the .#!CliQrReboot: header, you must use ASCII encoding – otherwise, the agent will not be able to pickup the required directives.

    However, if you are not using the .#!CliQrReboot: header, you can use other encoding as well.

    Windows Sample Script
    param (
       [string]$action,
       [string]$reboot
    )
    
    # Source userenv to get all cloud/app/job/tier data
    . 'c:\temp\userenv.ps1'
    . 'C:\Program Files\osmosix\service\utils\agent_util.ps1'
    
    # Verify reboots and capture results with every reboot
    $numOfReboots = 2
    $tmpfolder = "C:\tmp"
    
    if (!(Test-Path $tmpfolder)){
        $tmpDir = New-Item -ItemType Dir $tmpfolder
    } else {
        $tmpDir = $tmpfolder
        $tmpFolderFlag = 0
    }
    
    $resumeinitfile1 = Join-Path (Get-ChildItem env:OSMOSIX_HOME).Value ".cliqrRebootResumeInit"
    $resumeinitfile2 = Join-Path $tmpDir ".cliqrRebootResumeInit"
    $resumeinitfile3 = Join-Path $tmpDir ".step"
    
    if ( $reboot -match "reboot") {
        if (! (Test-Path $resumeinitfile1)) {
            #Checking for existence of file for first reboot. If not then create the flag file
            Set-Content -Path $resumeinitfile2 -Value "#!CliQrReboot:Current"
            Set-Content -Path $resumeinitfile3 -Value "RC=1" 
            agentSendLogMessage "Calling 1 Reboot... $action" 
        } else {
            #For subsequent reboots flag file will exist in a different location
            $data = gc $resumeinitfile3
            $rcCount = $data.trim().split("=")[-1]
            
            if ([int]$rcCount -lt $numOfReboots) {
                $rcCount = [int]$rcCount + 1
                $strdata = "RC=" + $rcCount
                agentSendLogMessage "Calling $rcCount Reboot... $action" 
                Set-Content -Path $resumeinitfile2 -Value "#!CliQrReboot:Current"
                Set-Content -Path $resumeinitfile3 -Value $strdata
            } else {
                agentSendLogMessage "Resuming after Final Reboot... $action"
                Remove-Item $resumeinitfile1
                Remove-Item $resumeinitfile3
            }     
        }
    }



  • No labels
© 2017-2019 Cisco Systems, Inc. All rights reserved