コード例 #1
0
ファイル: mebackup.php プロジェクト: soar-team/kloxo
function mebackup_main()
{
    global $gbl, $sgbl, $login, $ghtml;
    $progname = $sgbl->__var_program_name;
    $cprogname = ucfirst($progname);
    initProgram('admin');
    lxfile_mkdir("__path_program_home/selfbackup/self/__backup");
    $backup = $login->getObject('general')->selfbackupparam_b;
    $dbf = $sgbl->__var_dbf;
    $pass = trim(lfile_get_contents("__path_program_root/etc/conf/{$progname}.pass"));
    $vd = createTempDir("/tmp", "mebackup");
    $docf = "{$vd}/mebackup.dump";
    // Issue #671 - Fixed backup-restore issue
    //	exec("exec mysqldump --add-drop-table -u $progname -p$pass $dbf > $docf");
    system("exec mysqldump --add-drop-table -u {$progname} -p{$pass} {$dbf} > {$docf}");
    $string = @date('Y-M-d') . '-' . time();
    $bfile = "{$sgbl->__path_program_home}/selfbackup/self/__backup/{$progname}-scheduled-masterselfbackup-{$string}.zip";
    lxshell_zip($vd, $bfile, array("mebackup.dump"));
    lxfile_tmp_rm_rec($vd);
    if ($backup && $backup->isOn('selfbackupflag')) {
        try {
            lxbackup::upload_to_server($bfile, basename($bfile), $backup);
        } catch (Exception $e) {
            print "Sending warning to {$login->contactemail} ..\n";
            lx_mail(null, $login->contactemail, "{$cprogname} Self Database Backup Upload Failed on " . date('Y-M-d') . " at " . date('H') . " Hours", "{$cprogname} Backup upload Failed due to {$e->getMessage()}\n");
        }
    }
    $backup->rm_last_number = 20;
    $backup->nname = 'masterselfbackup';
    lxbackup::clear_extra_backups('selfbackup', 'self', $backup);
}
コード例 #2
0
ファイル: linuxfslib.php プロジェクト: zseand/kloxo
function lxshell_exists_in_zip($archive, $file)
{
    $dir = createTempDir("/tmp", "testzip");
    $ret = lxshell_unzip("__system__", $dir, $archive, array($file));
    lxfile_tmp_rm_rec($dir);
    if (!$ret) {
        return true;
    }
    return false;
}
コード例 #3
0
ファイル: createsliver.php プロジェクト: ahelsing/geni-portal
function prepare_temp_dir($identifier)
{
    return createTempDir($identifier);
}
コード例 #4
0
ファイル: vps__xenlib.php プロジェクト: digideskio/hypervm
 public function setInternalParam($mountpoint)
 {
     $name = $this->main->ostemplate;
     if ($this->main->isWindows()) {
         return;
     }
     if (!$mountpoint) {
         return;
     }
     if ($name === 'unknown') {
         return;
     }
     $name = strtolower($name);
     $mountpoint = expand_real_root($mountpoint);
     $result = $this->getScriptS($name);
     dprint("Distro Name {$name}, Scripts: \n");
     dprintr($result);
     $init = strtilfirst($name, "-");
     dprint("File is  {$init}.inittab\n");
     if (lxfile_exists("../file/sysfile/inittab/{$init}.inittab")) {
         dprint("Copying {$init}.inittab\n");
         $content = lfile_get_contents("../file/sysfile/inittab/{$init}.inittab");
         if ($this->main->text_inittab) {
             $content .= "\n{$this->main->text_inittab}";
         }
         lfile_put_contents("{$mountpoint}/etc/inittab", $content);
     }
     $iplist = get_namelist_from_objectlist($this->main->vmipaddress_a);
     if ($this->main->mainipaddress) {
         $main_ip = $this->main->mainipaddress;
         $iplist = array_remove($iplist, $main_ip);
     } else {
         $main_ip = array_shift($iplist);
     }
     if ($this->main->networknetmask) {
         $main_netmask = $this->main->networknetmask;
     } else {
         $main_netmask = "255.255.255.0";
     }
     $iplist = implode(" ", $iplist);
     $ipadd = $result['ADD_IP'];
     $sethostname = $result['SET_HOSTNAME'];
     $setuserpass = $result['SET_USERPASS'];
     $ipdel = $result['DEL_IP'];
     if ($this->main->networkgateway) {
         $gw = $this->main->networkgateway;
     } else {
         $gw = os_get_network_gateway();
     }
     $gwn = strtil($gw, '.') . '.0';
     $hostname = $this->main->hostname;
     if (!$hostname) {
         $hostname = os_get_hostname();
     }
     if ($result['STARTUP_SCRIPT'] != 'systemd') {
         $name = createTempDir("{$mountpoint}/tmp", 'xen-scripts');
         lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/functions", $name);
         lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$ipadd}", $name);
         lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$sethostname}", $name);
         lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$setuserpass}", $name);
         lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$ipdel}", $name);
         $basepath = strfrom($name, $mountpoint);
         lfile_put_contents("{$name}/tmpfile.sh", "source /{$basepath}/functions\nsource /{$basepath}/{$ipdel}\n");
         $delipstring = "IPDELALL=yes chroot {$mountpoint} bash /{$basepath}/tmpfile.sh";
         log_shell($delipstring);
         log_shell(system($delipstring, $ret1) . ":return {$ret1}");
         putenv("VE_STATE=stopped");
         lfile_put_contents("{$name}/tmpfile.sh", "source /{$basepath}/functions\n source /{$basepath}/{$ipadd}\n");
         $string = "IPDELALL=yes MAIN_NETMASK={$main_netmask} MAIN_IP_ADDRESS={$main_ip} IP_ADDR=\"{$iplist}\" NETWORK_GATEWAY={$gw} NETWORK_GATEWAY_NET={$gwn} chroot {$mountpoint} bash /{$basepath}/tmpfile.sh";
         log_shell($string);
         log_shell(system($string, $ret1) . ":return {$ret1}");
         lfile_put_contents("{$name}/tmpfile.sh", "source /{$basepath}/functions\n source /{$basepath}/{$sethostname}\n");
         $string = "HOSTNM={$hostname} chroot {$mountpoint} bash /{$basepath}/tmpfile.sh";
         log_shell($string);
         log_shell(system($string, $ret1) . ":return {$ret1}");
         if ($this->main->subaction === 'rebuild' || $this->main->dbaction === 'add' || $this->main->isOn('__var_rootpassword_changed') && $this->main->rootpassword) {
             $rootpass = "******";
             lfile_put_contents("{$name}/tmpfile.sh", "source /{$basepath}/functions\n source /{$basepath}/{$setuserpass}\n");
             $string = "USERPW={$rootpass} chroot {$mountpoint} bash /{$basepath}/tmpfile.sh";
             log_shell($string);
             log_shell(system($string));
         }
         lxfile_rm_rec($name);
     } else {
         if ($result['STARTUP_SCRIPT'] == 'systemd') {
             $script_dir = createTempDir("{$mountpoint}", "hypervm-runonce");
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/functions", $script_dir);
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$ipadd}", $script_dir);
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$sethostname}", $script_dir);
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$setuserpass}", $script_dir);
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$ipdel}", $script_dir);
             $basepath = strfrom($script_dir, $mountpoint);
             $startupdir = 'lib/systemd/system';
             $startupscript = 'fedora-startup.service';
             $setrootpass = '';
             if ($this->main->subaction === 'rebuild' || $this->main->dbaction === 'add' || $this->main->isOn('__var_rootpassword_changed') && $this->main->rootpassword) {
                 $rootpass = "******";
                 $setrootpass = "******";
             }
             $run_once_script = "#!/bin/bash\n" . "source {$basepath}/functions\n" . '(' . "IPDELALL=yes source {$basepath}/{$ipdel}" . " & IPDELALL=yes VE_STATE=stopped MAIN_NETMASK={$main_netmask} MAIN_IP_ADDRESS={$main_ip} IP_ADDR=\"{$iplist}\" NETWORK_GATEWAY={$gw} NETWORK_GATEWAY_NET={$gwn} source {$basepath}/{$ipadd}" . " & HOSTNM={$hostname} source {$basepath}/{$sethostname}" . "{$setrootpass})\n" . "service fedora-startup disable\nrm -f /{$startupdir}/{$startupscript}\nrm -rf {$basepath}";
             lfile_put_contents("{$script_dir}/hypervm-runonce.sh", $run_once_script);
             lxfile_cp_rec("__path_program_root/bin/xen-dists/scripts/{$startupscript}", "{$mountpoint}/{$startupdir}");
             lfile_put_contents("{$mountpoint}/{$startupdir}/{$startupscript}", lfile_get_contents("{$mountpoint}/{$startupdir}/{$startupscript}") . "ExecStart={$basepath}/hypervm-runonce.sh\n");
             system("ln -s /lib/systemd/system/fedora-startup.service {$mountpoint}/etc/systemd/system/multi-user.target.wants/fedora-startup.service");
             system("chmod 755 {$script_dir}/hypervm-runonce.sh");
         }
     }
     if ($this->main->nameserver) {
         $nlist = explode(" ", $this->main->nameserver);
         $nstring = null;
         foreach ($nlist as $l) {
             $nstring .= "nameserver {$l}\n";
         }
         lfile_put_contents("{$mountpoint}/etc/resolv.conf", $nstring);
     }
     if ($this->main->timezone) {
         lxfile_rm("{$mountpoint}/etc/localtime");
         $cmdstring = "ln -sf ../usr/share/zoneinfo/{$this->main->timezone} {$mountpoint}/etc/localtime";
         log_log("localtime", $cmdstring);
         do_exec_system('__system__', "/", $cmdstring, $out, $err, $ret, null);
         //lxfile_cp("/usr/share/zoneinfo/{$this->main->timezone}", "$mountpoint/etc/localtime");
     }
     lunlink("{$mountpoint}/etc/sysconfig/network-scripts/ifcfg-venet0");
     lunlink("{$mountpoint}/etc/sysconfig/network-scripts/ifcfg-venet0:0");
     $this->main->doKloxoInit($mountpoint);
 }
コード例 #5
0
ファイル: lxclass.php プロジェクト: hypervm-ng/hypervm-ng
 function top_level_simple_backup()
 {
     global $gbl, $sgbl, $login, $ghtml;
     $progname = $sgbl->__var_program_name;
     $dir = dirname($this->main->__var_bc_filename);
     $name = basename($this->main->__var_bc_filename);
     $firstname = strtil($name, "-");
     lxfile_mkdir($dir);
     $list = lscandir_without_dot($dir);
     $bc = $this->do_backup();
     $tmpdir = createTempDir("{$sgbl->__path_tmp}", "backupfile");
     lfile_put_contents("{$tmpdir}/{$progname}.file", $this->main->__var_bc_metafile);
     lfile_put_contents("{$tmpdir}/{$progname}.metadata", $this->main->__var_bc_metadata);
     $newarray = lx_array_merge(array($bc[1], array("{$tmpdir}/{$progname}.file", "{$tmpdir}/{$progname}.metadata")));
     if ($this->main->getZiptype() === 'zip') {
         lxshell_zip($bc[0], $this->main->__var_bc_filename, $newarray);
     } else {
         if ($this->main->getZiptype() === 'tar') {
             lxshell_tar($bc[0], $this->main->__var_bc_filename, $newarray);
         } else {
             lxshell_tgz($bc[0], $this->main->__var_bc_filename, $newarray);
         }
     }
     print_time("cpzip", "Copy and Zip");
     lxfile_tmp_rm_rec("{$tmpdir}");
     $this->do_backup_cleanup($bc);
 }
コード例 #6
0
ファイル: am_client.php プロジェクト: ahelsing/geni-portal
function invoke_omni_function($am_urls, $user, $args, $slice_users = array(), $bound_rspec = 0, $stitch_rspec = 0, $fork = false, $omni_invocation_dir = NULL, $api_version = "2")
{
    global $portal_gcf_dir;
    /* $file_manager only holds on to non-critical files (i.e., those
       that can be deleted regardless of whether the call was successful
       or not). */
    $file_manager = new FileManager();
    //  error_log("INVOKE : " . print_r($am_urls, true));
    // If we get a single URL, make it an array (handle the general case)
    if ($am_urls && !is_array($am_urls)) {
        $am_urls = array($am_urls);
    }
    /* Does each given URL handle speaks-for?
            If one or more AM URLs are given, check the SR for whether SF is enabled.
            If no AM URL is given but it's for stitching, just assume for now
                that all AMs handle SpeaksFor and see what happens.
      */
    if ($am_urls) {
        $handles_speaks_for = True;
        foreach ($am_urls as $am_url) {
            $am_handles_speaks_for = lookup_attribute($am_url, SERVICE_ATTRIBUTE_SPEAKS_FOR) == 't';
            if (!$am_handles_speaks_for) {
                $handles_speaks_for = False;
                break;
            }
        }
    } else {
        $handles_speaks_for = True;
    }
    /*
     If an aggregate doesn't handle speaks-for, 
     we use the inside cert and key of the user
     If an aggregate DOES handle speaks-for and the
     user has a speaks-for credential, 
     portal's cert and key and pass along the geni_speaking_for option
    */
    $speaks_for_invocation = false;
    $cert = $user->insideCertificate();
    $private_key = $user->insidePrivateKey();
    $speaks_for_cred = $user->speaksForCred();
    if ($handles_speaks_for and $speaks_for_cred) {
        $speaks_for_invocation = true;
        $cert = $user->certificate();
        $private_key = $user->privateKey();
    }
    $username = $user->username;
    $urn = $user->urn();
    // Get the authority from the user's URN
    parse_urn($urn, $authority, $type, $name);
    $aggregates = "aggregates=";
    $first = True;
    // get AMs if non-stitchable
    if (!$stitch_rspec) {
        if (is_array($am_urls)) {
            if (count($am_urls) == 0) {
                error_log("am_client Got non stitching RSpec and 0 AM URLs");
                // Careful: Are all RSpecs that stitcher can handle marked as stitch_rspecs properly?
                // return("Invalid AM URL");
            }
            foreach ($am_urls as $single) {
                if (!isset($single) || is_null($single) || $single == '') {
                    error_log("am_client cannot invoke Omni with invalid AM URL");
                    return "Invalid AM URL";
                }
                if ($first) {
                    $first = False;
                } else {
                    $aggregates = $aggregates . ", ";
                }
                $aggregates = $aggregates . $single;
            }
            $aggregates = $aggregates . "\n";
        } elseif (!isset($am_url) || is_null($am_url) || $am_url == '') {
            error_log("am_client cannot invoke Omni without an AM URL");
            return "Missing AM URL";
        }
    }
    /* Create a directory to store all temp files, including logs and error
          messages *if one doesn't exist already*. Let the prefix be the username.
          An "omni invocation ID" is created.
       
          Returns something like: /tmp/omni-invoke-myuser-RKvQ1Z
       */
    if (is_null($omni_invocation_dir)) {
        $omni_invocation_dir = createTempDir($username);
    }
    /* Write key and credential files */
    $tmp_version_cache = "{$omni_invocation_dir}/omniVersionCache";
    $tmp_agg_cache = "{$omni_invocation_dir}/omniAggCache";
    $file_manager->add($tmp_version_cache);
    $file_manager->add($tmp_agg_cache);
    $cert_file = writeDataToTempDir($omni_invocation_dir, $cert, OMNI_INVOCATION_FILE::CERTIFICATE_FILE);
    $file_manager->add($cert_file);
    $key_file = writeDataToTempDir($omni_invocation_dir, $private_key, OMNI_INVOCATION_FILE::PRIVATE_KEY_FILE);
    $file_manager->add($key_file);
    $slice_users = $slice_users + array($user);
    $username_array = array();
    $all_ssh_key_files = array();
    $ssh_key_files_by_user = array();
    foreach ($slice_users as $slice_user) {
        $slice_urn = $slice_user->urn();
        $ssh_key_files = write_ssh_keys($slice_user, $user, $omni_invocation_dir);
        // Skip from omni_config any user with no public SSH keys
        if (count($ssh_key_files) == 0) {
            continue;
        }
        $all_ssh_key_files = array_merge($all_ssh_key_files, $ssh_key_files);
        $ssh_key_files_by_user[$slice_urn] = $ssh_key_files;
        $username_array[] = $slice_user->username;
    }
    /* Create OMNI config file */
    if (!isset($sa_url)) {
        $sa_url = get_first_service_of_type(SR_SERVICE_TYPE::SLICE_AUTHORITY);
    }
    if (!isset($ma_url)) {
        $ma_url = get_first_service_of_type(SR_SERVICE_TYPE::MEMBER_AUTHORITY);
    }
    $omni_config = "[omni]\n" . "default_cf = my_chapi\n" . "users = " . implode(", ", $username_array) . "\n";
    // As of omni 2.7, by default omni queries the CH to get slice members
    // We pass those in explicitly and don't want the extra query
    $omni_config .= "useslicemembers = False\n";
    // specify AM for non-stitchable RSpecs
    if (!$stitch_rspec) {
        if (is_array($am_urls)) {
            $omni_config = $omni_config . $aggregates . "\n";
        }
    }
    # Create the aggregate nickname cache file
    if (!write_agg_nick_cache($tmp_agg_cache)) {
        error_log("Failed to write the aggregate nickname cache.");
        // Now what? Continue?
    }
    // FIXME: Get the /CH URL from a portal/www/portal/settings.php entry?
    $omni_config = $omni_config . "[my_chapi]\n" . "type=chapi\n" . "authority={$authority}\n" . "ch=https://{$authority}:8444/CH\n" . "sa={$sa_url}\n" . "ma={$ma_url}\n" . "cert={$cert_file}\n" . "key={$key_file}\n";
    foreach ($slice_users as $slice_user) {
        $slice_username = $slice_user->username;
        $slice_urn = $slice_user->urn();
        if (!array_key_exists($slice_urn, $ssh_key_files_by_user)) {
            // This user had no SSH keys
            continue;
        }
        $all_key_files = implode(',', $ssh_key_files_by_user[$slice_urn]);
        $omni_config = $omni_config . "[{$slice_username}]\n" . "urn={$slice_urn}\n" . "keys={$all_key_files}\n";
    }
    foreach ($all_ssh_key_files as $ssh_key_file) {
        $file_manager->add($ssh_key_file);
    }
    $omni_file = writeDataToTempDir($omni_invocation_dir, $omni_config, OMNI_INVOCATION_FILE::OMNI_CONFIGURATION_FILE);
    $file_manager->add($omni_file);
    /* Call OMNI */
    $omni_log_file = "{$omni_invocation_dir}/" . OMNI_INVOCATION_FILE::DEBUG_LOG_FILE;
    $omni_stderr_file = "{$omni_invocation_dir}/" . OMNI_INVOCATION_FILE::ERROR_LOG_FILE;
    $omni_stdout_file = "{$omni_invocation_dir}/" . OMNI_INVOCATION_FILE::CALL_RESULTS_FILE;
    $omni_command_file = "{$omni_invocation_dir}/" . OMNI_INVOCATION_FILE::COMMAND_FILE;
    $omni_pid_file = "{$omni_invocation_dir}/" . OMNI_INVOCATION_FILE::PID_FILE;
    /*    $cmd_array = array($portal_gcf_dir . '/src/omni.py', */
    $cmd_array = array($portal_gcf_dir . '/src/stitcher_php.py', '-c', $omni_file, '-l', write_logger_configuration_file($omni_invocation_dir), '--logoutput', $omni_log_file, '--timeout', '45', '--api-version', $api_version, "--GetVersionCacheName", $tmp_version_cache, "--ForceUseAggNickCache", "--AggNickCacheName", $tmp_agg_cache);
    $descriptor_spec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("file", $omni_stderr_file, "a"));
    /* stitcher.py: specify fileDir */
    $cmd_array[] = '--fileDir';
    $cmd_array[] = $omni_invocation_dir;
    // specify AM for non-stitchable RSpecs
    if (!$stitch_rspec) {
        foreach ($am_urls as $am_url) {
            $cmd_array[] = '-a';
            $cmd_array[] = $am_url;
        }
    }
    if ($speaks_for_invocation) {
        $cmd_array[] = "--speaksfor=" . $user->urn;
        $speaks_for_cred_filename = writeDataToTempDir($omni_invocation_dir, $speaks_for_cred->credential(), OMNI_INVOCATION_FILE::SPEAKSFOR_CREDENTIAL_FILE);
        $file_manager->add($speaks_for_cred_filename);
        $cmd_array[] = "--cred=" . $speaks_for_cred_filename;
    }
    for ($i = 0; $i < count($args); $i++) {
        $cmd_array[] = $args[$i];
    }
    $command = implode(" ", $cmd_array);
    // save command that was run
    $cmd_file = fopen($omni_command_file, "a");
    fwrite($cmd_file, $command);
    fclose($cmd_file);
    /* forked omni call */
    if ($fork) {
        // define how to handle streams
        $stdout_redirect = " > " . $omni_stdout_file;
        $stderr_redirect = " 2> " . $omni_stderr_file;
        $stdin_redirect = " < /dev/null";
        // set up call via nohup and grab its PID
        $fork_call = 'nohup ' . $command . $stdout_redirect . $stderr_redirect . $stdin_redirect . ' & echo $!';
        error_log("am_client invoke_omni_function COMMAND = " . $fork_call);
        exec($fork_call, $op);
        // assuming success, $op will be a non-empty array
        if ($op) {
            // nohup should return an array with one line containing the PID
            $pid = $op[0];
            // write PID to a file
            $pid_file = fopen($omni_pid_file, "a");
            fwrite($pid_file, $pid);
            fclose($pid_file);
            // FIXME: Should we wait around to do 'ps -p <pid>' to make sure
            // process didn't quickly die?
            return $pid;
        } else {
            return NULL;
        }
    } else {
        error_log("am_client invoke_omni_function COMMAND = " . $command);
        $handle = proc_open($command, $descriptor_spec, $pipes);
        stream_set_blocking($pipes[1], 0);
        // 1 MB
        $bufsiz = 1024 * 1024;
        $output = '';
        $outchunk = null;
        //time to terminate omni process
        $now = time();
        $kill_time = $now + AM_CLIENT_OMNI_KILL_TIME;
        while ($outchunk !== FALSE && !feof($pipes[1]) && $now < $kill_time) {
            $outchunk = fread($pipes[1], $bufsiz);
            if ($outchunk != null && $outchunk !== FALSE) {
                $output = $output . $outchunk;
                $usleep = 0;
            } else {
                // 0.25 seconds
                $usleep = 250000;
            }
            // If we got data, don't sleep, see if there's more ($usleep = 0)
            // If no data, sleep for a little while then check again.
            usleep($usleep);
            $now = time();
        }
        // Catch any final output after timeout
        $outchunk = fread($pipes[1], $bufsiz);
        if ($outchunk != null && $outchunk !== FALSE) {
            $output = $output . $outchunk;
        }
        //fclose($pipes[0]);
        //fclose($pipes[1]);
        //proc_close($handle);
        $status = proc_get_status($handle);
        if (!$status['running']) {
            fclose($pipes[0]);
            fclose($pipes[1]);
            $return_value = $status['exitcode'];
            proc_close($handle);
        } else {
            // Still running, terminate it.
            // See https://bugs.php.net/bug.php?id=39992, for problems
            // terminating child processes and a workaround involving posix_setpgid()
            fclose($pipes[0]);
            fclose($pipes[1]);
            $term_result = proc_terminate($handle);
            // Omni is taking too long to respond so
            // assign Timeout error message to output and this message may show up in UI
            //msg constant defined above
            $output = AM_CLIENT_TIMED_OUT_MSG;
        }
        /*
        unlink($cert_file);
        unlink($key_file);
        unlink($omni_file);
        unlink($tmp_version_cache);
        unlink($tmp_agg_cache);
        foreach ($all_ssh_key_files as $tmpfile) {
          unlink($tmpfile);
        }
        if ($speaks_for_invocation) {
          unlink($speaks_for_cred_filename);
        }
        */
        // Good for debugging but verbose
        //     error_log("am_client output " .  print_r($output, True));
        // FIXME: Write stdout's contents to omni_stdout_file for now to capture
        //  stitcher output. This will be changed when assigning descriptor_spec
        //  to send to a file rather than a pipe.
        $stdout_file = fopen($omni_stdout_file, "a");
        fwrite($stdout_file, $output);
        fclose($stdout_file);
        $output2 = json_decode($output, True);
        if (is_null($output2)) {
            // this is probably a traceback from python
            // return it as a string
            // but see if omni-stderr exists, and pass back its information
            // in addition to output to get a better traceback
            $error_file = fopen($omni_stderr_file, "r");
            // only try to read if fopen was successful and if the error file
            // contains something (i.e. more than 0 bytes)
            if ($error_file && filesize($omni_stderr_file)) {
                $error_file_contents = fread($error_file, filesize($omni_stderr_file));
                if ($error_file_contents) {
                    $substr = $error_file_contents;
                    if (strlen($substr) > 120) {
                        // Pull out just the interesting bits: match on either OmniError or StitchingError
                        $substr = trim(preg_replace("/Traceback(.*)OmniError\\:/s", "", $substr, -1));
                        $substr = trim(preg_replace("/Traceback(.*)StitchingError\\:/s", "", $substr, -1));
                        $substr = "..." . $substr;
                    }
                    error_log("am_client invoke_omni_function: " . "stderr file non-empty: '" . $substr . "'. Check " . $omni_stderr_file . " for more information");
                    // uncomment the next line to append stderr contents to what
                    // users will see. But this has been fixed elsewhere under ticket 1086.
                    //$output .= $error_file_contents;
                }
                fclose($error_file);
            }
            error_log("am_client invoke_omni_function:" . "JSON result is not parseable: \"{$output}\"");
            return $output;
        }
        /* Clean out $file_manager's directory 
              This does NOT include log/error files or any additional files that
              stitching requests may make.
           */
        $file_manager->destruct();
        /* Delete the remaining temp files only if the decoded output is an array
             and its length is 2 and the second value (index 1) is boolean true
             (not null or empty string).
           */
        if (is_array($output2) && count($output2) == 2 && $output2[1]) {
            clean_directory($omni_invocation_dir);
            rmdir($omni_invocation_dir);
            //unlink($omni_log_file);
            //unlink($omni_stderr_file);
        }
        //error_log("Returning output2 : " . print_r($output2, True));
        return $output2;
    }
}