<?php

require_once("inc/read_conf.php");
require_once("inc/db.php");
require_once("inc/ssh.php");
require_once("inc/idna_convert.class.php");
require_once("inc/validate_param.php");
require_once("inc/slave_actions.php");
require_once("inc/auth.php");
require_once("inc/ipmi_cmds.php");
require_once("inc/hardware_profile.php");
require_once("inc/auto_racking.php");
require_once("inc/plugin_dns.php");
require_once("inc/plugin_monitoring.php");
require_once("inc/plugin_root_pass.php");
require_once("inc/auto_provision.php");

$conf = readmyconf();
$con = connectme($conf);

if(oci_ip_check($con, $conf) === FALSE){
    die("Source IP not in openstack-cluster-installer.conf.");
}

$remote_addr = $_SERVER['REMOTE_ADDR'];

$safe_chassis_serial = safe_serial("chassis-serial");
if($safe_chassis_serial === FALSE){
    $q = "SELECT * FROM machines WHERE dhcp_ip='$remote_addr'";
}else{
    $q = "SELECT * FROM machines WHERE serial='$safe_chassis_serial'";
}

$status = "";
$puppet_status = "";
$update_initial_cluster_setup_var = "no";

$r = mysqli_query($con, $q);
$n = mysqli_num_rows($r);
if($n == 0){
    die();
}else{
    $machine = mysqli_fetch_array($r);

    $id = $machine["id"];
    if( isset($_REQUEST["status"]) ){
        switch($_REQUEST["status"]){
        case "live":
            $status = ", status='live'";
            break;
        case "installing":
            $status = ", status='installing'";
            break;
        case "installed":
            $status = ", status='installed'";
            // Since there can be a host in the between doing SNAT, the REMOTE_ADDR
            // can be wrong, so we fix that by reading the parameter.
            $safe_ipv4 = safe_ipv4("ipaddr");
            if($safe_ipv4 === FALSE){
                error_log("install-status.php: No ipaddr reported after install!");
            }else{
                $remote_addr = $safe_ipv4;
                // As the machine has just booted, we must update its IP,
                // otherwise subsequent calls (ie: machine_gen_root_pass)
                // may fail.
                $machine["ipaddr"] = $safe_ipv4;
                if($safe_chassis_serial === FALSE){
                    die("Machine reports installed, but safe_chassis_serial is FALSE: impossible case, so dying...");
                }
                $q = "UPDATE machines SET ipaddr='$safe_ipv4' WHERE serial='$safe_chassis_serial'";
                $r = mysqli_query($con, $q);
            }
            // Since the machine is booted and installed, we need to sign the puppet cert.
            // We can do it with sudo, as there's a sudoers file installed.
            $cmd = "ls /usr/bin/puppetserver";
            $output = array();
            $return_var = 0;
            exec($cmd, $output, $return_var);
            if($return_var == 0){
                $puppet_master_is_7_or_more = "yes";
            }else{
                $puppet_master_is_7_or_more = "no";
            }

            $output = "";
            $machine_hostname = $machine["hostname"];
            if($puppet_master_is_7_or_more == "yes"){
                $mycmd = "puppetserver ca sign --certname";
            }else{
                $mycmd = "puppet cert sign";
            }
            error_log("install-status.php: sudo /usr/bin/$mycmd $machine_hostname");
            $cmd = "sudo /usr/bin/$mycmd " . $machine_hostname;
            exec($cmd , $output);

            // As the machine is installed, we can setup its root password.
            machine_gen_root_pass($con, $conf, $machine);

            break;
        case "firstboot":
            ipmi_set_boot_device($con, $conf, $id, "disk");
            $status = ", status='firstboot'";
            break;
        case "puppet-running":
            $puppet_status = ", puppet_status='running'";
            break;
        case "puppet-success":
            $puppet_status = ", puppet_status='success'";
            $update_initial_cluster_setup_var = "yes";

            // If puppet is successful, setup the monitoring.
            machine_add_to_monitoring($con, $conf, $machine);

            break;
        case "puppet-failure":
            $puppet_status = ", puppet_status='failure'";
            break;
        default:
            $status = ", status='unkown'";
            break;
        }
    }else{
        $status = ", status='unkown'";
    }
    // We keep the machine id...
    if($safe_chassis_serial === FALSE){
        $req = "UPDATE machines SET lastseen=NOW() $puppet_status $status WHERE ipaddr='$remote_addr'";
    }else{
        if($_REQUEST["status"] == "live"){
            $req = "UPDATE machines SET lastseen=NOW() $puppet_status $status, ipaddr='$remote_addr', dhcp_ip='$remote_addr' WHERE serial='$safe_chassis_serial'";
        }else{
            $req = "UPDATE machines SET lastseen=NOW() $puppet_status $status, ipaddr='$remote_addr' WHERE serial='$safe_chassis_serial'";
        }
    }
    $r = mysqli_query($con, $req);
    if($update_initial_cluster_setup_var == "yes" && $safe_chassis_serial !== FALSE){
        $q = "SELECT cluster,role,id FROM machines WHERE serial='$safe_chassis_serial'";
        $r = mysqli_query($con, $q);
        if($r !== FALSE){
            $n = mysqli_num_rows($r);
            if($n == 1){
                $machine = mysqli_fetch_array($r);
                $machine_id = $machine["id"];
                $clusterid = $machine["cluster"];
                switch($machine["role"]){
                case "controller":
                    $q = "SELECT hostname FROM machines WHERE cluster='$clusterid' AND role='controller' AND puppet_status NOT LIKE 'success'";
                    $r = mysqli_query($con, $q);
                    if($r !== FALSE){
                        $n = mysqli_num_rows($r);
                        if($n == 0){
                            $q = "UPDATE clusters SET initial_cluster_setup='no' WHERE id='$clusterid'";
                            $r = mysqli_query($con, $q);
                            # In this case, we should also (re-)start the puppet setup of nova hyper converged nodes,
                            # so we make sure nova-manage cell_v2 discover_hosts is called.
                            # TODO ...
                            $q = "SELECT ipaddr FROM machines WHERE role='compute' AND compute_is_cephosd='yes' AND cluster='$clusterid'";
                            $r = mysqli_query($con, $q);
                            if($r !== FALSE){
                                $n = mysqli_num_rows($r);
                                for($i=0;$i<$n;$i++){
                                    $compute_machine = mysqli_fetch_array($r);
                                    $compute_machine_ip = $compute_machine["ipaddr"];
                                    # Restart the oci-first-boot, so that the compute hyperconverged machines
                                    # gets installed, this time with nova-compute, not just only with the cephosd role.
                                    $cmd = "touch /var/lib/oci-first-boot";
                                    send_ssh_cmd($conf, $con, $compute_machine_ip, $cmd);
                                    $cmd = "nohup systemctl restart oci-first-boot.service &";
                                    send_ssh_cmd($conf, $con, $compute_machine_ip, $cmd);
                                }
#                            $cmd = "";
#                            send_ssh_cmd($conf, $con, $ip_addr, $cmd);
                            }
                        }
                    }
                    break;
                case "compute":
                    # Since this is a new compute, we must do a nova-manage cell_v2 discover_hosts so that the machine
                    # appears in the hypervisor list.
                    # However, if the compute is hyper-converged, we shall delay this until all controllers are installed,
                    # and the compute gets nova up.
                    $q = "SELECT * FROM clusters WHERE id='$clusterid'";
                    $r = mysqli_query($con, $q);
                    if($r !== FALSE){
                        $n = mysqli_num_rows($r);
                        if($n > 0){
                            $clusterid = $machine["cluster"];
                            $q = "SELECT ipaddr FROM machines WHERE cluster='$clusterid' AND role='controller' AND puppet_status LIKE 'success' LIMIT 1";
                            $r = mysqli_query($con, $q);
                            if($r !== FALSE){
                                $n = mysqli_num_rows($r);
                                if($n > 0){
                                    $controller = mysqli_fetch_array($r);
                                    $ip_addr = $controller["ipaddr"];
                                    $cmd = "su nova -s /bin/sh -c 'nova-manage cell_v2 discover_hosts'";
                                    send_ssh_cmd($conf, $con, $ip_addr, $cmd);
                                }
                            }
                        }
                    }
                    # Set the OSD setup var to no
                    $q = "UPDATE machines SET ceph_osd_initial_setup='no' WHERE id='$machine_id'";
                    $r = mysqli_query($con, $q);
                    break;
                case "billosd":
                case "cephosd":
                    # Set the OSD setup var to no
                    $q = "UPDATE machines SET ceph_osd_initial_setup='no' WHERE id='$machine_id'";
                    $r = mysqli_query($con, $q);
                    break;
                default:
                    break;
                }
                // Apply an eventual command on the controller if it's defined in the hardware-profile.json
                hardware_profile_after_puppet_controller_commands($con, $conf, $machine["id"]);
            }
        }
    }
}

?>
