示例#1
0
function deactivate_user($username)
{
    global $users, $is_control_node, $is_compute_node, $conf_base_path, $is_svn_node, $svn_node_addr, $conf_svn_problems_log, $conf_ssh_tunneling;
    $userdata = setup_paths($username);
    // If this is a simple compute node, just kill nodejs
    if ($is_compute_node && !$is_control_node) {
        stop_node($username, true);
        // $cleanup=true -- kill everything owned by user
        $users[$username]['status'] = "inactive";
        unset($users[$username]['collaborate']);
        unset($users[$username]['server']);
        unset($users[$username]['port']);
        write_files();
    } else {
        if ($is_control_node) {
            debug_log("deactivate_user {$username}");
            // Update logout file
            $script = "date > " . $userdata['workspace'] . "/.logout";
            run_as($username, $script);
            // Remove user from nginx - this will inform user that they are logged out
            $server = $users[$username]['server'];
            $users[$username]['status'] = "inactive";
            $port = $users[$username]['port'];
            unset($users[$username]['collaborate']);
            unset($users[$username]['server']);
            unset($users[$username]['port']);
            write_nginx_config();
            // Stop nodejs on server where user is running
            if (is_local($server) || empty($server)) {
                stop_node($username, false);
            } else {
                run_on($server, "{$conf_base_path}/bin/webidectl logout " . $userdata['esa']);
                if ($conf_ssh_tunneling) {
                    foreach (ps_ax("localhost") as $process) {
                        if (strstr($process['cmd'], "ssh -N -L {$port}")) {
                            exec("kill " . $process['pid']);
                        }
                    }
                }
            }
            if (!$is_svn_node) {
                proc_close(proc_open("ssh {$svn_node_addr} \"{$conf_base_path}/bin/webidectl logout " . $userdata['esa'] . "\" 2>&1 &", array(), $foo));
            }
        }
    }
    if ($is_svn_node) {
        $users[$username]['status'] = "inactive";
        write_files();
        // Syncsvn deactivate
        sleep(1);
        // Give some time for syncsvn to sync .logout
        if (file_exists($userdata['svn_watch'])) {
            $pid = trim(file_get_contents($userdata['svn_watch']));
            if (file_exists("/proc/{$pid}")) {
                exec("kill {$pid}");
            }
            unlink($userdata['svn_watch']);
        }
        stop_inotify($username);
        // Commit remaining stuff to svn
        $script = "cd " . $userdata['workspace'] . "; ";
        $script .= "echo USER: {$username} >> {$conf_svn_problems_log}; ";
        $script .= "svn ci -m deactivate_user . 2>&1 >> {$conf_svn_problems_log}";
        run_as($username, $script);
        fixsvn($username);
    } else {
        if ($is_control_node) {
            //		run_on($svn_node_addr, "$conf_base_path/bin/webidectl logout " . $userdata['esa']);
        }
    }
    if ($is_control_node) {
        // Users file is updated only now, to prevent user from logging back in during other procedures
        // (BFL should prevent it but alas...)
        write_files();
    }
}
示例#2
0
function fixsvn($command)
{
    global $username, $userdata, $debug, $sleep, $conf_base_path, $conf_c9_group;
    if ($debug) {
        print "Command: {$command}\n";
    }
    $output = run_as($username, "cd " . $userdata['workspace'] . "; {$command} 2>&1");
    if ($debug) {
        print "Result: \n";
    }
    $ok = false;
    if (empty($output)) {
        $ok = true;
    }
    foreach (explode("\n", $output) as $line) {
        if ($debug) {
            print "{$line}\n";
        }
        $matches = array();
        if (strstr($line, "Committed revision")) {
            $ok = true;
            break;
        } else {
            if (strstr($line, "Previous operation has not finished")) {
                fixsvn("svn cleanup");
                fixsvn($command);
                $ok = true;
                break;
            } else {
                if (strstr($line, "is already locked")) {
                    fixsvn("svn cleanup");
                    fixsvn($command);
                    $ok = true;
                    break;
                } else {
                    if (preg_match("/File '(.*?)' is out of date/", $line, $matches) || preg_match("/Base checksum mismatch on '(.*?)'/", $line, $matches)) {
                        $filename = basename($matches[1]);
                        $wsname = substr($matches[1], strlen($userdata['workspace']) + 1);
                        unlink("/tmp/{$filename}");
                        fixsvn("cp \"" . $matches[1] . "\" \"/tmp/{$filename}\"");
                        unlink($matches[1]);
                        fixsvn("svn update --accept mine-full \"{$wsname}\"");
                        fixsvn("cp \"/tmp/{$filename}\" \"{$wsname}\"");
                        unlink("/tmp/{$filename}");
                        fixsvn("svn ci -m fixsvn \"{$wsname}\"");
                        fixsvn($command);
                        $ok = true;
                        break;
                    } else {
                        if (preg_match("/Directory '(.*?)' is out of date/", $line, $matches)) {
                            // Let's hope there are no local changes to files...
                            $filename = basename($matches[1]);
                            $wsname = substr($matches[1], strlen($userdata['workspace']) + 1);
                            fixsvn("svn update --accept mine-full \"{$wsname}\"");
                            fixsvn($command);
                            $ok = true;
                            break;
                        } else {
                            if (preg_match("/Aborting commit: '(.*?)' remains in conflict/", $line, $matches) || preg_match("/Tree conflict can only be resolved to 'working' state: '(.*?)' not resolved/", $line, $matches)) {
                                $filename = basename($matches[1]);
                                $wsname = substr($matches[1], strlen($userdata['workspace']) + 1);
                                fixsvn("svn resolve --accept mine-full \"{$wsname}\"");
                                fixsvn($command);
                                $ok = true;
                                break;
                            } else {
                                if (preg_match("/Can't change perms of file '(.*?)': No such file or directory/", $line, $matches) || preg_match("/'(.*?)' is scheduled for addition, but is missing/", $line, $matches)) {
                                    $filename = basename($matches[1]);
                                    $wsname = substr($matches[1], strlen($userdata['workspace']) + 1);
                                    run_as($username, "cd " . $userdata['workspace'] . "; touch \"{$wsname}\"");
                                    fixsvn($command);
                                    $ok = true;
                                    break;
                                } else {
                                    if (preg_match("/Node '(.*?)' has unexpectedly changed kind/", $line, $matches)) {
                                        $filename = basename($matches[1]);
                                        $wsname = substr($matches[1], strlen($userdata['workspace']) + 1);
                                        if (is_dir($matches[1])) {
                                            $files = scandir($matches[1]);
                                            if (count($files) == 2) {
                                                // Directory empty, add an empty file instead
                                                rmdir($matches[1]);
                                                run_as($username, "cd " . $userdata['workspace'] . "; touch \"{$wsname}\"");
                                                fixsvn($command);
                                                $ok = true;
                                            } else {
                                                // Directory not empty
                                                // Copy to tmp, commit file, readd
                                                `rm -fr /tmp/{$filename}`;
                                                run_as($username, "mv \"" . $matches[1] . "\" /tmp/{$filename}");
                                                run_as($username, "cd " . $userdata['workspace'] . "; touch \"{$wsname}\"");
                                                fixsvn("svn ci -m fixsvn \"{$wsname}\"");
                                                fixsvn("svn remove \"{$wsname}\"");
                                                fixsvn("svn ci -m fixsvn \"{$wsname}\"");
                                                run_as($username, "mv /tmp/{$filename} \"" . $matches[1] . "\"");
                                                fixsvn("svn add \"{$wsname}\"");
                                                fixsvn("svn ci -m fixsvn \"{$wsname}\"");
                                            }
                                        } else {
                                            $contents = file_get_contents($matches[1]);
                                            unlink($matches[1]);
                                            run_as($username, "cd " . $userdata['workspace'] . "; mkdir \"{$wsname}\"");
                                            fixsvn($command);
                                            if (!empty($contents)) {
                                                // After $command directory may become file again!
                                                if (is_dir($matches[1])) {
                                                    $newname = $matches[1] . "/" . $filename;
                                                    file_put_contents($newname, $contents);
                                                    exec("chown {$username}:{$conf_c9_group} \"{$newname}\"");
                                                } else {
                                                    file_put_contents($matches[1], $contents);
                                                    fixsvn("svn add \"{$wsname}\"");
                                                    fixsvn("svn ci -m fixsvn \"{$wsname}\"");
                                                }
                                            }
                                            $ok = true;
                                        }
                                        break;
                                    } else {
                                        if (preg_match("/Invalid control character '.*?' in path '(.*?)'/", $line, $matches) || preg_match("/Error converting entry in directory '(.*?)' to/", $line, $matches) || preg_match("/'(.*?)': a peg revision is not allowed here/", $line, $matches)) {
                                            $basedir = $matches[1];
                                            if (strstr($line, "Invalid control") || strstr($line, "a peg revision")) {
                                                $basedir = dirname($basedir);
                                            }
                                            if (strstr($line, "a peg revision")) {
                                                $basedir = $userdata['workspace'] . "/" . $basedir;
                                            }
                                            $dh = opendir($basedir);
                                            while ($filename = readdir($dh)) {
                                                //print "Filename: $filename\n";
                                                if (preg_match('/[[:^print:]]/', $filename) || strstr($filename, "@")) {
                                                    $new_filename = preg_replace('/[[:^print:]]/', '?', $filename);
                                                    $new_filename = str_replace('@', '?', $new_filename);
                                                    print "Renaming {$filename} to {$new_filename}\n";
                                                    rename($basedir . "/" . $filename, $basedir . "/" . $new_filename);
                                                }
                                            }
                                            fixsvn($command);
                                            $ok = true;
                                            break;
                                        } else {
                                            if (preg_match("/Can't move '.*?' to '(.*?)': Permission denied/", $line, $matches)) {
                                                $path = dirname($matches[1]);
                                                exec("chown -R {$username}:{$conf_c9_group} " . escapeshellarg($path));
                                                fixsvn($command);
                                                $ok = true;
                                                break;
                                            } else {
                                                if (strstr($line, "Directory '/' is out of date")) {
                                                    fixsvn("svn update .");
                                                    fixsvn($command);
                                                    $ok = true;
                                                    break;
                                                } else {
                                                    if (strstr($line, "Could not add all targets because some targets are already versioned") || strstr($line, "Could not add all targets because some targets don't exist")) {
                                                        $ok = true;
                                                    } else {
                                                        if (strstr($line, "Resolved conflicted state of")) {
                                                            $ok = true;
                                                        } else {
                                                            if (strstr($line, "Updated to revision") || strstr($line, "At revision") || strstr($line, "Committed revision")) {
                                                                $ok = true;
                                                            } else {
                                                                if (strstr($line, "D      ") || strstr($line, "A      ")) {
                                                                    $ok = true;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (!$ok) {
        print "Unkown error!\n\n";
        $sleep += 5;
        exec("php {$conf_base_path}/bin/fixsvn.php " . $userdata['esa'] . " {$sleep} &");
        exit(1);
    }
}