Esempio n. 1
0
def launch_gdb_sl(tsuite, sock_name, sl2objects, res_bin_type, gdbcmd_path):
    """Generic slash2 launch service in screen+gdb. Will also copy over authbuf keys.

  Args:
    tsuite: tsuite runtime.
    sock_name: name of sl2 sock.
    sl2objects: list of objects to be launched.
    res_bin_type: key to bin path in src_dirs.
    gdbcmd_path: path to gdbcmd file."""

    # res_bin_type NEEDS to be a path in src_dirs
    assert res_bin_type in tsuite.src_dirs

    for sl2object in sl2objects:
        log.debug("Initializing environment > {0} @ {1}".format(sl2object["name"], sl2object["host"]))

        # Remote connection
        user, host = tsuite.user, sl2object["host"]
        log.debug("Connecting to {0}@{1}".format(user, host))
        ssh = SSH(user, host, "")

        # Acquire and deploy authbuf key
        need_authbuf = handle_authbuf(tsuite, ssh, sl2object["type"])

        ls_cmd = "ls {0}/".format(tsuite.build_dirs["ctl"])
        result = ssh.run(ls_cmd)

        present_socks = [res_bin_type in sock for sock in result["out"]].count(True)

        # Create monolithic reference/replace dict
        repl_dict = dict(tsuite.src_dirs, **tsuite.build_dirs)
        repl_dict = dict(repl_dict, **sl2object)

        if "id" not in sl2object.keys():
            sl2object["id"] = 0

        # Create gdbcmd from template
        gdbcmd_build_path = path.join(
            tsuite.build_dirs["base"], "{0}_{1}".format(sl2object["id"], path.basename(gdbcmd_path))
        )

        new_gdbcmd = repl_file(repl_dict, gdbcmd_path)

        if new_gdbcmd:
            with open(gdbcmd_build_path, "w") as f:
                f.write(new_gdbcmd)
                f.close()
                log.debug("Wrote gdb cmd to {0}".format(gdbcmd_build_path))
                log.debug("Remote copying gdbcmd.")
                ssh.copy_file(gdbcmd_build_path, gdbcmd_build_path)
        else:
            log.fatal("Unable to parse gdb cmd at {0}!".format(gdbcmd_path))
            tsuite.shutdown()

        cmd = "sudo gdb -f -x {0} {1}".format(gdbcmd_build_path, tsuite.src_dirs[res_bin_type])
        screen_sock_name = "sl.{0}.{1}".format(sock_name, sl2object["id"])

        # Launch slash2 in gdb within a screen session
        ssh.run_screen(cmd, screen_sock_name)

        # Wait two seconds to make sure slash2 launched without errors
        time.sleep(2)

        screen_socks = ssh.list_screen_socks()
        if screen_sock_name + "-error" in screen_socks or screen_sock_name not in screen_socks:
            log.fatal(
                "sl2object {0}:{1} launched with an error. Resume to {2} and resolve it.".format(
                    sl2object["name"], sl2object["id"], screen_sock_name + "-error"
                )
            )
            tsuite.shutdown(ignore=sock_name)

        log.debug("Waiting for {0} sock on {1} to appear.".format(sock_name, host))
        count = 0
        while True:
            result = ssh.run(ls_cmd, quiet=True)
            if not all(res_bin_type not in sock for sock in result["out"]):
                break
            time.sleep(1)
            count += 1
            if count == int(tsuite.conf["slash2"]["timeout"]):
                log.fatal(
                    "Cannot find {0} sock on {1}. Resume to {2} and resolve it. ".format(
                        res_bin_type, sl2object["id"], screen_sock_name
                    )
                )
                tsuite.shutdown(ignore=sock_name)

        # grab pid for resouce querying later
        # TODO: do not grab other running instances
        sl2object["pid"] = ssh.run("pgrep {0}".format(res_bin_type))["out"][0].strip()
        log.debug("Found {0} pid on {1} : {2}".format(res_bin_type, host, sl2object["pid"]))

        if need_authbuf:
            pull_authbuf(tsuite, ssh)

        ssh.close()
Esempio n. 2
0
def launch_gdb_sl(tsuite, sock_name, sl2objects, res_bin_type, gdbcmd_path):
    """Generic slash2 launch service in screen+gdb. Will also copy over authbuf keys.

  Args:
    tsuite: tsuite runtime.
    sock_name: name of sl2 sock.
    sl2objects: list of objects to be launched.
    res_bin_type: key to bin path in src_dirs.
    gdbcmd_path: path to gdbcmd file."""

    #res_bin_type NEEDS to be a path in src_dirs
    assert (res_bin_type in tsuite.src_dirs)

    for sl2object in sl2objects:
        log.debug("Initializing environment > {0} @ {1}".format(
            sl2object["name"], sl2object["host"]))

        #Remote connection
        user, host = tsuite.user, sl2object["host"]
        log.debug("Connecting to {0}@{1}".format(user, host))
        ssh = SSH(user, host, '')

        #Acquire and deploy authbuf key
        need_authbuf = handle_authbuf(tsuite, ssh, sl2object["type"])

        ls_cmd = "ls {0}/".format(tsuite.build_dirs["ctl"])
        result = ssh.run(ls_cmd)

        present_socks = [res_bin_type in sock
                         for sock in result["out"]].count(True)

        #Create monolithic reference/replace dict
        repl_dict = dict(tsuite.src_dirs, **tsuite.build_dirs)
        repl_dict = dict(repl_dict, **sl2object)

        if "id" not in sl2object.keys():
            sl2object["id"] = 0

        #Create gdbcmd from template
        gdbcmd_build_path = path.join(
            tsuite.build_dirs["base"],
            "{0}_{1}".format(sl2object["id"], path.basename(gdbcmd_path)))

        new_gdbcmd = repl_file(repl_dict, gdbcmd_path)

        if new_gdbcmd:
            with open(gdbcmd_build_path, "w") as f:
                f.write(new_gdbcmd)
                f.close()
                log.debug("Wrote gdb cmd to {0}".format(gdbcmd_build_path))
                log.debug("Remote copying gdbcmd.")
                ssh.copy_file(gdbcmd_build_path, gdbcmd_build_path)
        else:
            log.fatal("Unable to parse gdb cmd at {0}!".format(gdbcmd_path))
            tsuite.shutdown()

        cmd = "sudo gdb -f -x {0} {1}".format(gdbcmd_build_path,
                                              tsuite.src_dirs[res_bin_type])
        screen_sock_name = "sl.{0}.{1}".format(sock_name, sl2object["id"])

        #Launch slash2 in gdb within a screen session
        ssh.run_screen(cmd, screen_sock_name)

        #Wait two seconds to make sure slash2 launched without errors
        time.sleep(2)

        screen_socks = ssh.list_screen_socks()
        if screen_sock_name + "-error" in screen_socks or screen_sock_name not in screen_socks:
            log.fatal("sl2object {0}:{1} launched with an error. Resume to {2} and resolve it."\
                .format(sl2object["name"], sl2object["id"], screen_sock_name+"-error"))
            tsuite.shutdown(ignore=sock_name)

        log.debug("Waiting for {0} sock on {1} to appear.".format(
            sock_name, host))
        count = 0
        while True:
            result = ssh.run(ls_cmd, quiet=True)
            if not all(res_bin_type not in sock for sock in result["out"]):
                break
            time.sleep(1)
            count += 1
            if count == int(tsuite.conf["slash2"]["timeout"]):
                log.fatal("Cannot find {0} sock on {1}. Resume to {2} and resolve it. "\
                  .format(res_bin_type, sl2object["id"], screen_sock_name))
                tsuite.shutdown(ignore=sock_name)

        #grab pid for resouce querying later
        #TODO: do not grab other running instances
        sl2object["pid"] = ssh.run(
            "pgrep {0}".format(res_bin_type))['out'][0].strip()
        log.debug("Found {0} pid on {1} : {2}".format(res_bin_type, host,
                                                      sl2object["pid"]))

        if need_authbuf:
            pull_authbuf(tsuite, ssh)

        ssh.close()
Esempio n. 3
0
    def parse_slash2_conf(self):
        """Reads and parses slash2 conf for tokens.
    Writes to the base directory; updates slash2 objects in the tsuite."""

        try:
            with open(self.conf["slash2"]["conf"]) as conf:
                new_conf = "#TSuite Slash2 Conf\n"

                res, site_name = None, None
                in_site = False
                site_id, fsuuid = -1, -1
                client = None

                #Regex config parsing for sl2objects
                reg = {
                    "clients":
                    re.compile("^\s*?#\s*clients\s*=\s*(.+?)\s*;\s*$"),
                    "type":
                    re.compile("^\s*?type\s*?=\s*?(\S+?)\s*?;\s*$"),
                    "id":
                    re.compile("^\s*id\s*=\s*(\d+)\s*;\s*$"),
                    "zpool":
                    re.compile(
                        r"^\s*?#\s*?zfspool\s*?=\s*?(\w+?)\s+?(.*?)\s*$"),
                    "zpool_path":
                    re.compile(r"^\s*?#\s*?zfspath\s*?=\s*?(.+?)\s*$"),
                    "prefmds":
                    re.compile(r"\s*?#\s*?prefmds\s*?=\s*?(\w+?@\w+?)\s*$"),
                    "fsuuid":
                    re.compile(
                        r"^\s*set\s*fsuuid\s*=\s*\"?(0x[a-fA-F\d]+|\d+)\"?\s*;\s*$"
                    ),
                    "fsroot":
                    re.compile("^\s*?fsroot\s*?=\s*?(\S+?)\s*?;\s*$"),
                    "nids":
                    re.compile("^\s*?nids\s*?=\s*?(.*)$"),
                    "new_res":
                    re.compile("^\s*resource\s+(\w+)\s*{\s*$"),
                    "fin_res":
                    re.compile("^\s*?}\s*$"),
                    "site":
                    re.compile("^\s*?site\s*?@(\w+).*?"),
                    "site_id":
                    re.compile(
                        "^\s*site_id\s*=\s*(0x[a-fA-F\d]+|\d+)\s*;\s*$"),
                    "jrnldev":
                    re.compile("^\s*jrnldev\s*=\s*([/\w]+)\s*;\s*$")
                }

                line = conf.readline()

                while line:
                    #Replace keywords and append to new conf

                    new_conf += repl(self.build_dirs, line)

                    #Iterate through the regexes and return a tuple of
                    #(name, [\1, \2, \3, ...]) for successful matches

                    matches = [
                      (k, reg[k].match(line).groups()) for k in reg\
                      if reg[k].match(line)
                    ]

                    #Should not be possible to have more than one
                    assert (len(matches) <= 1)

                    #log.debug("%s %s %s\n->%s" % (matches, in_site, res, line))
                    if matches:
                        (name, groups) = matches[0]

                        if in_site:

                            if name == "site_id":
                                site_id = groups[0]

                            elif res:
                                if name == "type":
                                    res["type"] = groups[0]

                                elif name == "id":
                                    res["id"] = groups[0]

                                elif name == "zpool_path":
                                    res["zpool_path"] = groups[0].strip()

                                elif name == "jrnldev":
                                    res["jrnldev"] = groups[0]

                                elif name == "zpool":
                                    res["zpool_name"] = groups[0]
                                    res["zpool_cache"] = path.join(
                                        self.build_dirs["base"],
                                        "{0}.zcf".format(groups[0]))
                                    res["zpool_args"] = groups[1]

                                elif name == "prefmds":
                                    res["prefmds"] = groups[0]

                                elif name == "fsroot":
                                    res["fsroot"] = groups[0].strip('"')

                                elif name == "nids":
                                    #Read subsequent lines and get the first host

                                    tmp = groups[0]
                                    while line and ";" not in line:
                                        tmp += line
                                        line = conf.readline()
                                    tmp = re.sub(";\s*$", "", tmp)
                                    res["host"] = re.split("\s*,\s*", tmp,
                                                           1)[0].strip(" ")

                                elif name == "fin_res":
                                    #Check for errors finalizing object
                                    res["site_id"] = site_id
                                    res["fsuuid"] = fsuuid

                                    if not res.finalize(self.sl2objects):
                                        self.shutdown()
                                    res = None
                            else:
                                if name == "new_res":
                                    res = SL2Res(groups[0], site_name)
                        else:
                            if name == "clients":
                                for client in [
                                        g.strip() for g in groups[0].split(",")
                                ]:
                                    client_res = SL2Res(client, None)
                                    client_res["type"] = "client"
                                    client_res["host"] = client
                                    client_res.finalize(self.sl2objects)
                            elif name == "site":
                                site_name = groups[0]
                                in_site = True
                            elif name == "fsuuid":
                                fsuuid = groups[0]

                    line = conf.readline()

                new_conf_path = path.join(self.build_dirs["base"],
                                          "slash.conf")

                try:
                    with open(new_conf_path, "w") as new_conf_file:
                        new_conf_file.write(new_conf)
                        log.debug("Successfully wrote build slash2 conf at {0}"\
                            .format(new_conf_path))
                        for sl2_obj in self.all_objects():
                            try:
                                ssh = SSH(self.user, sl2_obj["host"], "")
                                log.debug("Copying new config to {0}".format(
                                    sl2_obj["host"]))
                                try:
                                    ssh.copy_file(new_conf_path, new_conf_path)
                                except IOError:
                                    log.critical(
                                        "Error copying config file to {0}".
                                        format(ssh.host))
                                    self.shutdown()
                                ssh.close()
                            except SSHException:
                                log.error("Unable to copy config file to {0}!".
                                          format(sl2_obj["host"]))
                except IOError, e:
                    log.fatal("Unable to write new conf to build directory!")
                    log.fatal(new_conf_path)
                    log.fatal(e)
                    return False
        except IOError, e:
            log.fatal("Unable to read conf file at {0}"\
                .format(self.conf["slash2"]["conf"]))
            log.fatal(e)
            return False
Esempio n. 4
0
    def parse_slash2_conf(self):
        """Reads and parses slash2 conf for tokens.
    Writes to the base directory; updates slash2 objects in the tsuite."""

        try:
            with open(self.conf["slash2"]["conf"]) as conf:
                new_conf = "#TSuite Slash2 Conf\n"

                res, site_name = None, None
                in_site = False
                site_id, fsuuid = -1, -1
                client = None

                # Regex config parsing for sl2objects
                reg = {
                    "clients": re.compile("^\s*?#\s*clients\s*=\s*(.+?)\s*;\s*$"),
                    "type": re.compile("^\s*?type\s*?=\s*?(\S+?)\s*?;\s*$"),
                    "id": re.compile("^\s*id\s*=\s*(\d+)\s*;\s*$"),
                    "zpool": re.compile(r"^\s*?#\s*?zfspool\s*?=\s*?(\w+?)\s+?(.*?)\s*$"),
                    "zpool_path": re.compile(r"^\s*?#\s*?zfspath\s*?=\s*?(.+?)\s*$"),
                    "prefmds": re.compile(r"\s*?#\s*?prefmds\s*?=\s*?(\w+?@\w+?)\s*$"),
                    "fsuuid": re.compile(r"^\s*set\s*fsuuid\s*=\s*\"?(0x[a-fA-F\d]+|\d+)\"?\s*;\s*$"),
                    "fsroot": re.compile("^\s*?fsroot\s*?=\s*?(\S+?)\s*?;\s*$"),
                    "nids": re.compile("^\s*?nids\s*?=\s*?(.*)$"),
                    "new_res": re.compile("^\s*resource\s+(\w+)\s*{\s*$"),
                    "fin_res": re.compile("^\s*?}\s*$"),
                    "site": re.compile("^\s*?site\s*?@(\w+).*?"),
                    "site_id": re.compile("^\s*site_id\s*=\s*(0x[a-fA-F\d]+|\d+)\s*;\s*$"),
                    "jrnldev": re.compile("^\s*jrnldev\s*=\s*([/\w]+)\s*;\s*$"),
                }

                line = conf.readline()

                while line:
                    # Replace keywords and append to new conf

                    new_conf += repl(self.build_dirs, line)

                    # Iterate through the regexes and return a tuple of
                    # (name, [\1, \2, \3, ...]) for successful matches

                    matches = [(k, reg[k].match(line).groups()) for k in reg if reg[k].match(line)]

                    # Should not be possible to have more than one
                    assert len(matches) <= 1

                    # log.debug("%s %s %s\n->%s" % (matches, in_site, res, line))
                    if matches:
                        (name, groups) = matches[0]

                        if in_site:

                            if name == "site_id":
                                site_id = groups[0]

                            elif res:
                                if name == "type":
                                    res["type"] = groups[0]

                                elif name == "id":
                                    res["id"] = groups[0]

                                elif name == "zpool_path":
                                    res["zpool_path"] = groups[0].strip()

                                elif name == "jrnldev":
                                    res["jrnldev"] = groups[0]

                                elif name == "zpool":
                                    res["zpool_name"] = groups[0]
                                    res["zpool_cache"] = path.join(self.build_dirs["base"], "{0}.zcf".format(groups[0]))
                                    res["zpool_args"] = groups[1]

                                elif name == "prefmds":
                                    res["prefmds"] = groups[0]

                                elif name == "fsroot":
                                    res["fsroot"] = groups[0].strip('"')

                                elif name == "nids":
                                    # Read subsequent lines and get the first host

                                    tmp = groups[0]
                                    while line and ";" not in line:
                                        tmp += line
                                        line = conf.readline()
                                    tmp = re.sub(";\s*$", "", tmp)
                                    res["host"] = re.split("\s*,\s*", tmp, 1)[0].strip(" ")

                                elif name == "fin_res":
                                    # Check for errors finalizing object
                                    res["site_id"] = site_id
                                    res["fsuuid"] = fsuuid

                                    if not res.finalize(self.sl2objects):
                                        self.shutdown()
                                    res = None
                            else:
                                if name == "new_res":
                                    res = SL2Res(groups[0], site_name)
                        else:
                            if name == "clients":
                                for client in [g.strip() for g in groups[0].split(",")]:
                                    client_res = SL2Res(client, None)
                                    client_res["type"] = "client"
                                    client_res["host"] = client
                                    client_res.finalize(self.sl2objects)
                            elif name == "site":
                                site_name = groups[0]
                                in_site = True
                            elif name == "fsuuid":
                                fsuuid = groups[0]

                    line = conf.readline()

                new_conf_path = path.join(self.build_dirs["base"], "slash.conf")

                try:
                    with open(new_conf_path, "w") as new_conf_file:
                        new_conf_file.write(new_conf)
                        log.debug("Successfully wrote build slash2 conf at {0}".format(new_conf_path))
                        for sl2_obj in self.all_objects():
                            try:
                                ssh = SSH(self.user, sl2_obj["host"], "")
                                log.debug("Copying new config to {0}".format(sl2_obj["host"]))
                                try:
                                    ssh.copy_file(new_conf_path, new_conf_path)
                                except IOError:
                                    log.critical("Error copying config file to {0}".format(ssh.host))
                                    self.shutdown()
                                ssh.close()
                            except SSHException:
                                log.error("Unable to copy config file to {0}!".format(sl2_obj["host"]))
                except IOError, e:
                    log.fatal("Unable to write new conf to build directory!")
                    log.fatal(new_conf_path)
                    log.fatal(e)
                    return False
        except IOError, e:
            log.fatal("Unable to read conf file at {0}".format(self.conf["slash2"]["conf"]))
            log.fatal(e)
            return False