Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Warning
titleEP Install Required

Before continuing to Job 4 please log in to the Destination Repository to allow the Target Enablement Pack to complete it's configuration.
Additionally apply any template changes if required as described here: 

4_Set_Storage_Templates

Job 4 applies the default templates which were set up by the RED 10 Target Enablement Pack, this is why it is important to have completed that install process by logging in to the Destination. This steep can be re-run if it was completed too early, or the individual scripts can be run from the Migration Tooling RED UI. 

...

If the only RED 10 WhereScape Target Enablement Pack you have available was released prior to this version of the migration tooling then it will be missing code to deal with the RED8/9 legacy script output protocol required after a migration to avoid having to rebuild every script. If this is the case then you can update you Action Processing Script Template execute script function directly. This should be performed prior to the action script generation tasks in Jobs 5 and 6 or the scripts beginning with 'c<n>_' if running the tasks manually. 

...

You can replace the functions in each of your PowerShell and Python templates depending on what your enablement provides. After making you changes you should test by manually regenerating the Action Processing Script on a few of your objects in the Destination Repo prior to running the batch generation jobs. The updated functions are as follows:

PowerShell

Replace ExecuteScript function in template wsl_common_pscript_utility_action

Code Block
languagepowershell
titleExecuteScript (PowerShell)
collapsetrue
function ExecuteScript($name){
    $prefix = [string]::Format("WSL_SCRIPT_{0}_",$name)
    $command = [Environment]::GetEnvironmentVariable("${prefix}COMMAND")
    if ([string]::IsNullOrEmpty($command) -or "$command" -like "*${PSCommandPath}*") {
      # Abort if there is no command or the command conatins this action script
      throw [string]::Format("No Script or SQL Block found for routine {0} of $OBJECT$",$name)
    }
    else {
      # Copy accross any routine specific env vars
      Get-ChildItem Env:${prefix}* | ForEach-Object {
        $unprefixedvar = $_.Name -replace $prefix, 'WSL_'
        [Environment]::SetEnvironmentVariable($unprefixedvar,$_.Value)
      }
      # Ensure the environment var WSL_WORKDIR is set and accessible, defaults to current run directory when not
      if ( -not ( (Test-Path env:WSL_WORKDIR) -and (Test-Path "${env:WSL_WORKDIR}") ) ) {
        [Environment]::SetEnvironmentVariable('WSL_WORKDIR',$PSScriptRoot)
      }
    }
    if ( Test-Path "$command" ) {
      # We have an SQL Block file
      $sqlBlockFile = Get-Item "$command"
      if ($sqlBlockFile.Extension -eq '.sql') {
        $block = Get-Content $sqlBlockFile -Raw
        $result = ExecuteSQLBlock $block
        if ( ($result -ne $null) -and ($result[1] -ne $null) -and ($result[1] -ne -1) ) {
          WriteAudit "Rows affected:$($result[1])"
        }
      }
      else {
        throw [string]::Format("SQL Block file had unexpected file extension: {0}",$command)
      }
    }
    else {
        $legacyOutputProtocol = $false
        if ( ('$WSL_EXP_LEGACY_SCRIPT_SUPPORT$' -eq 'TRUE') -or ('$PLEGACY_SCRIPT_SUPPORT$' -eq 'TRUE') ) {
          $scriptStdOut = & cmd.exe /c ${env:WSL_COMMAND}
          if ( $scriptStdOut -ne $null ) {
              $stdOutLines = $scriptStdOut -split '\r\n|\n'
              if ( $stdOutLines[0] -in ('1','-1','-2','-3') ) {
                  WriteAudit -message 'Parsing legacy script output protocol' -type "detail"
                  $legacyOutputProtocol = $true
                  if ($stdOutLines[0] -in ('-2','-3')) {
                      WriteAudit -message $stdOutLines[1] -statusCode "E"
                  }
                  elseif ($stdOutLines[0] -in ('-1')) {
                      WriteAudit -message $stdOutLines[1] -statusCode "W"
                  }
                  else {
                      WriteAudit -message $stdOutLines[1]
                  }
                  for ($i = 2; $i -lt $stdOutLines.Length; $i++){
                      WriteAudit -message $stdOutLines[$i]
                  }
              } 
              else {
                # We couldn't detect legacy output protocol so assume new protocol and pass stdout through
                WriteAudit 'Using new script output protocol' -type "detail"
                $stdOutLines | Write-Host
              }
          }
      }
      else {
        & cmd.exe /c ${env:WSL_COMMAND}
      }
      if ( $LASTEXITCODE -ne 0 -or ( $legacyOutputProtocol -and $stdOutLines[0] -in ('-2','-3') ) ) {
        if ( $LASTEXITCODE -ne 0 ) {
          $exitCode = $LASTEXITCODE
        }
        else {
          $exitCode = $scriptStdOut[0]
        }
        throw [string]::Format("Script execution failed with exit code: {0}. Check both audit and detail logs.",$exitCode)
      }
    }
}


Python

Replace ExecuteScript function in template wsl_common_pyscript_utility_action

Code Block
languagepython
titleExecuteScript (Python)
def ExecuteScript(name):
    env = dict(os.environ)
    # Environment variables specific to the script (e.g. WORKDIR, which comes
    # from the script's connection) are stored prefixed. We copy such variables
    # to their unprefixed name.
    prefix = 'WSL_SCRIPT_{}_'.format(name)
    command = os.getenv(prefix + 'COMMAND')
    if ( not command ) or ( sys.argv[0] in command ):
        raise Exception("No Script or SQL Block found for routine {}".format(name))
    write_detail("Executing command: {}".format(command))
    for var in os.environ:
        if var.startswith(prefix):
            unprefixedvar = 'WSL_' + var[len(prefix):]
            #write_detail("Overriding environment: {} -> {}".format(var, unprefixedvar))
            env[unprefixedvar] = os.environ[var]
    # Ensure our work directory is valid and default to script root if not
    env['WSL_WORKDIR'] = os.getenv('WSL_WORKDIR','Work_Directory_Not_Set')
    if not os.path.exists(env['WSL_WORKDIR']):
        # default to script root
        env['WSL_WORKDIR'] = os.path.dirname(sys.argv[0])
        write_detail("Overriding environment: {} -> {}".format('WSL_WORKDIR', env['WSL_WORKDIR']))
    if os.path.exists(command) and os.path.splitext(command)[1] == '.sql':
        # We have an sql block not a script
        with open(command) as f:
            block = f.read()
            result = ExecuteSQLBlock(block)
        if result == True:
            write_detail("Executed SQL Block")        
    else:
        legacy_script = False
        if '$WSL_EXP_LEGACY_SCRIPT_SUPPORT$' == 'TRUE' or '$PLEGACY_SCRIPT_SUPPORT$' == 'TRUE':
            # Parse output for LEGACY_SCRIPT_SUPPORT if the matching extended property or parameter is TRUE
            result = subprocess.run(command, shell=True, env=env, capture_output=True, text=True)
            return_code = result.returncode if result.returncode < 2**31 else result.returncode - 2**32
            if result.stdout:
                stdout_lines = result.stdout.splitlines()
                if stdout_lines[0] in ['1','-1','-2','-3']:
                    legacy_script = True
                    write_detail("Parsing legacy script output protocol.")
                    # We have legacy script output protocol
                    legacy_returncode = stdout_lines[0]
                    if legacy_returncode in ['-2','-3']:
                        # error
                        return_code = 2
                        if stdout_lines[1]:
                            write_audit(stdout_lines[1],'audit','E')
                    elif legacy_returncode == '-1':
                        # success with warning
                        return_code = 0
                        if stdout_lines[1]:
                            write_audit(stdout_lines[1],'audit','W')
                    elif legacy_returncode == '1':
                        # success
                        return_code = 0
                        if stdout_lines[1]:
                            write_audit(stdout_lines[1],'audit','I')
                    for line in stdout_lines[2:(len(stdout_lines))]:
                        write_audit(line)
                else:
                    write_detail("Using new script output protocol")
                    # First line didn't conform to legacy script output protocol 
                    # so assume we have new output protocol and just pass stdout through
                    for line in stdout_lines:
                      print(line, flush=True)
        else:
            # Assume that we can just pass all the output from the script as our output
            # and the return code indicates success/failure
            result = subprocess.run(command, shell=True, env=env, stderr=subprocess.PIPE, text=True)
            return_code = result.returncode if result.returncode < 2**31 else result.returncode - 2**32   
        if result.stderr != "":
            write_audit(str(result.stderr),'detail','E')
        if ( (result.stderr != "" and not legacy_script) or ( str(return_code) != "0" ) ):
            # Finally signal a failure if one occured.
            raise Exception("Script execution failed with exit code: {}. Check both audit and detail logs.".format(return_code))