コード例 #1
0
ファイル: ML_build.py プロジェクト: Annakan/python_api
def build_cluster(host, adminuser, adminpass, couple_user, couple_pass, cluster_host_list):
    conn = Connection(host, HTTPDigestAuth(adminuser, adminpass))
    marklogic = MarkLogic(conn)

    if cluster_host_list is not None:
        for couple in cluster_host_list:
            print("{0}: couple with {1}...".format(host, couple))
            altconn = Connection(couple,
                                 HTTPDigestAuth(couple_user,
                                                couple_pass))
            altml = MarkLogic(altconn)
            altcluster = altml.cluster()
            cluster = marklogic.cluster()
            cluster.couple(altcluster)

    print("Finished")
コード例 #2
0
    def couple_cluster(self):
        conn = Connection(self.host,
                          HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.host, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #3
0
ファイル: couple.py プロジェクト: JamFuller/python_api
    def couple_cluster(self):
        conn = Connection(self.host, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.host,couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #4
0
class Couple:
    def __init__(self):
        self.marklogic = None
        self.adminuser = "******"
        self.adminpass = "******"
        self.host = "localhost"
        self.couple = None
        self.couple_user = None
        self.couple_pass = None

    def set_credentials(self, user, password):
        self.adminuser = user
        self.adminpass = password

    def set_host(self, host):
        self.host = host

    def set_couple(self, couple):
        self.couple = couple

    def set_couple_credentials(self, user, password):
        self.couple_user = user
        self.couple_pass = password

    def couple_cluster(self):
        conn = Connection(self.host,
                          HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.host, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #5
0
ファイル: couple.py プロジェクト: JamFuller/python_api
class Couple:
    def __init__(self):
        self.marklogic = None
        self.adminuser="******"
        self.adminpass="******"
        self.host="localhost"
        self.couple=None
        self.couple_user=None
        self.couple_pass=None

    def set_credentials(self,user,password):
        self.adminuser = user
        self.adminpass = password

    def set_host(self,host):
        self.host = host

    def set_couple(self,couple):
        self.couple = couple

    def set_couple_credentials(self,user,password):
        self.couple_user = user
        self.couple_pass = password

    def couple_cluster(self):
        conn = Connection(self.host, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.host,couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #6
0
    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        if self.boothost is None:
            self.boothost = self.host[0]
            self.host.remove(self.boothost)

        if self.ml_init(self.boothost):
            self.ml_security(self.boothost)

        conn = Connection(self.boothost,
                          HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for hostname in self.host:
            self.ml_init(hostname)
            self.ml_join(self.boothost, hostname)

        if self.name is not None:
            print("{0}: rename cluster...".format(self.boothost))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.boothost, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #7
0
ファイル: make-cluster.py プロジェクト: DALDEI/ml-docker
    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        if self.boothost is None:
            self.boothost = self.host[0]
            self.host.remove(self.boothost)

        if self.ml_init(self.boothost):
            self.ml_security(self.boothost)

        conn = Connection(self.boothost, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for hostname in self.host:
            self.ml_init(hostname)
            self.ml_join(self.boothost, hostname)

        if self.name is not None:
            print("{0}: rename cluster...".format(self.boothost))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.boothost, couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #8
0
class App:
    def __init__(self):
        self.marklogic = None
        self.uname = pwd.getpwuid(os.getuid()).pw_name
        self.adminuser = "******"
        self.adminpass = "******"
        self.realm = "public"
        self.host = None
        self.boothost = None
        self.couple = None
        self.couple_user = None
        self.couple_pass = None
        self.name = None

    def set_credentials(self, user, password):
        self.adminuser = user
        self.adminpass = password

    def set_realm(self, realm):
        self.realm = realm

    def set_boot_host(self, host):
        self.boothost = host

    def set_host(self, name):
        self.host = name

    def set_couple(self, couple):
        self.couple = couple

    def set_couple_credentials(self, user, password):
        self.couple_user = user
        self.couple_pass = password

    def set_name(self, name):
        self.name = name

    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        if self.boothost is None:
            self.boothost = self.host[0]
            self.host.remove(self.boothost)

        if self.ml_init(self.boothost):
            self.ml_security(self.boothost)

        conn = Connection(self.boothost,
                          HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for hostname in self.host:
            self.ml_init(hostname)
            self.ml_join(self.boothost, hostname)

        if self.name is not None:
            print("{0}: rename cluster...".format(self.boothost))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.boothost, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")

    def ml_init(self, hostname):
        print("{0}: initialize host...".format(hostname))
        try:
            host = MarkLogic.instance_init(hostname)
        except UnauthorizedAPIRequest:
            # Assume that this happened because the host is already initialized
            host = Host(hostname)

        return host.just_initialized()

    def ml_join(self, boothost, hostname):
        print("{0}: join cluster with {1}...".format(hostname, boothost))
        cluster = self.marklogic.cluster()
        host = Host(hostname)
        cluster.add_host(host)

    def ml_security(self, hostname):
        print("{0}: initialize security...".format(hostname))
        MarkLogic.instance_admin(hostname, self.realm, self.adminuser,
                                 self.adminpass)
コード例 #9
0
ファイル: docker-cluster.py プロジェクト: ndw/python_api_TEMP
    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        self.load_blacklist()
        self.find_containers()

        if not self.container_list:
            print("There must be at least one unused container running.")
            sys.exit(1)

        if self.localimage:
            ps = os.popen("docker exec " + self.container_list[0] + " ip route")
            for line in ps.readlines():
                match = re.match("^default via (\S+)", line)
                if match:
                    self.localip = match.group(1)
            if self.localip is None:
                print("Cannot find IP address of localhost!?")
                sys.exit(1)

        # Find the bootstrap image

        if self.localimage:
            pass
        else:
            self.bootimage = self.pick_image(self.bootimage)
            self.container_list.remove(self.bootimage)

        self.cluster_list = self.pick_containers()

        self.display_info()
        #sys.exit(1)

        # Initialize the bootstrap image, if necessary

        if self.localimage:
            bootip = self.localip
        else:
            bootip = self.ipaddr[self.bootimage]

        if self.ml_init(bootip, self.bootimage):
            self.ml_security(bootip, self.bootimage)

        conn = Connection(bootip, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for container in self.cluster_list:
            if container == self.bootimage:
                continue
            ip = self.ipaddr[container]
            self.ml_init(ip, container)
            self.ml_join(bootip, ip)

        if self.name is not None:
            print("{0}: rename cluster...".format(bootip))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(bootip,couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #10
0
ファイル: docker-cluster.py プロジェクト: ndw/python_api_TEMP
class Docker:
    def __init__(self):
        self.marklogic = None
        self.uname=pwd.getpwuid(os.getuid()).pw_name
        self.adminuser="******"
        self.adminpass="******"
        self.realm="public"
        self.imatch="ml[0-9]"
        self.bootimage=None
        self.localimage=False
        self.count=None
        self.couple=None
        self.couple_user=None
        self.couple_pass=None
        self.name=None
        self.blacklist_file="/tmp/{0}.docker.skip".format(self.uname)
        self.blacklist={}
        self.container_list=[]
        self.cluster_list=[]
        self.containers={}
        self.localip=None
        self.ipaddr={}
        self.hostname={}

    def set_credentials(self,user,password):
        self.adminuser = user
        self.adminpass = password

    def set_realm(self,realm):
        self.realm = realm

    def set_image_match(self,match):
        self.imatch = match

    def set_boot_image(self,image):
        self.bootimage = image
        self.localimage = (image == "localhost")

    def set_count(self,count):
        self.count = count

    def set_couple(self,couple):
        self.couple = couple

    def set_couple_credentials(self,user,password):
        self.couple_user = user
        self.couple_pass = password

    def set_name(self,name):
        self.name = name

    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        self.load_blacklist()
        self.find_containers()

        if not self.container_list:
            print("There must be at least one unused container running.")
            sys.exit(1)

        if self.localimage:
            ps = os.popen("docker exec " + self.container_list[0] + " ip route")
            for line in ps.readlines():
                match = re.match("^default via (\S+)", line)
                if match:
                    self.localip = match.group(1)
            if self.localip is None:
                print("Cannot find IP address of localhost!?")
                sys.exit(1)

        # Find the bootstrap image

        if self.localimage:
            pass
        else:
            self.bootimage = self.pick_image(self.bootimage)
            self.container_list.remove(self.bootimage)

        self.cluster_list = self.pick_containers()

        self.display_info()
        #sys.exit(1)

        # Initialize the bootstrap image, if necessary

        if self.localimage:
            bootip = self.localip
        else:
            bootip = self.ipaddr[self.bootimage]

        if self.ml_init(bootip, self.bootimage):
            self.ml_security(bootip, self.bootimage)

        conn = Connection(bootip, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for container in self.cluster_list:
            if container == self.bootimage:
                continue
            ip = self.ipaddr[container]
            self.ml_init(ip, container)
            self.ml_join(bootip, ip)

        if self.name is not None:
            print("{0}: rename cluster...".format(bootip))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(bootip,couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")

    def ml_init(self, ip, container):
        if container in self.hostname:
            hostname = self.hostname[container]
        else:
            hostname = container
        print("{0}: initialize host {1}...".format(ip,hostname))
        try:
            host = MarkLogic.instance_init(ip)
        except UnauthorizedAPIRequest:
            # Assume that this happened because the host is already initialized
            host = Host(ip)

        self.blacklist[container] = "used"
        self.save_blacklist()
        return host.just_initialized()

    def ml_join(self, bootip, ip):
        print("{0}: join cluster with {1}...".format(ip,bootip))
        cluster = self.marklogic.cluster()
        host = Host(ip)
        cluster.add_host(host)

    def ml_security(self, ip, container):
        print("{0}: initialize security...".format(ip))
        MarkLogic.instance_admin(ip,self.realm,self.adminuser,self.adminpass)
        self.blacklist[container] = "boot"
        self.save_blacklist()

    def pick_image(self, name):
        if name is None:
            for container in self.container_list:
                if not container in self.blacklist:
                    return container
            print("Cannot find unused container")
            sys.exit(1)

        for key in self.hostname:
            if name == self.hostname[key]:
                return key

        count = 0
        container = None
        for key in self.ipaddr:
            if name == self.ipaddr[key]:
                return key
            if re.match("^"+name, key):
                count += 1
                container = key
        if count == 1:
            return container
        if count > 1:
            print("Ambiguous container id:", name)
            sys.exit(1)

        for key in self.containers:
            image = self.containers[key]
            if (key == self.bootimage or re.match(self.bootimage, image)):
                return key

        print("Cannot find container \"{0}\".".format(name))
        sys.exit(1)

    def pick_containers(self):
        if self.count is None:
            count = -1
        else:
            count = self.count - 1

        cset = set()

        if not self.localimage:
            cset.add(self.bootimage)

        for container in self.container_list:
            if container == self.bootimage or container in self.blacklist:
                continue
            if count == 0:
                continue
            cset.add(container)
            count -= 1

        containers = []
        for key in cset:
            containers.append(key)
        return containers

    def load_blacklist(self):
        try:
            f = open(self.blacklist_file, "r")
            for line in f.readlines():
                (container, flag) = line.strip().split(" ")
                self.blacklist[container] = flag
            f.close()
        except FileNotFoundError:
            pass

    def save_blacklist(self):
        f = open(self.blacklist_file, "w")
        for key in self.blacklist:
            if self.blacklist[key] != "gone":
                f.write("{0} {1}\n".format(key,self.blacklist[key]))
        f.close()

    def find_containers(self):
        self.load_blacklist()

        ps = os.popen("docker ps")
        for line in ps.readlines():
            match = re.match("([0-9a-f]+)\s+(\S+)", line)
            if match:
                container = match.group(1)
                image = match.group(2)

                ipx = os.popen("docker inspect {0}".format(container))
                ip = None
                hostname = None
                for line in ipx.readlines():
                    match = re.match('\s+"IPAddress": "([^"]+)"', line)
                    if match:
                        ip = match.group(1)
                    match = re.match('\s+"Hostname": "([^"]+)"', line)
                    if match:
                        hostname = match.group(1)
                if ip is None:
                    print("Cannot read IP address of container {0}"
                          .format(container))
                else:
                    self.ipaddr[container] = ip

                if hostname is None:
                    print("Cannot read hostname of container {0}"
                          .format(container))
                else:
                    self.hostname[container] = hostname

                if re.match(self.imatch, image):
                    self.container_list = [container] + self.container_list
                    self.containers[container] = image

        for container in self.blacklist:
            if not container in self.containers:
                self.blacklist[container] = "gone"

    def display_info(self):
        # Display information about docker containers
        # Sigh. Report formatting is such a drag...
        dinfo = []
        ps = os.popen("docker ps")
        for line in ps.readlines():
            match = re.match("([0-9a-f]+)\s+(\S+)", line)
            if match:
                container = match.group(1)
                image = match.group(2)
                ip = self.ipaddr[container]
                hostname = self.hostname[container]
                attr = []
                if container in self.blacklist:
                    attr.append("used")
                    if self.blacklist[container] == "boot":
                        attr.append("boot")
                else:
                    if not container in self.cluster_list:
                        attr.append("skip")
                    else:
                        if re.match(self.imatch, image):
                            attr.append("*")
                            if container == self.bootimage:
                                attr.append("boot")
                        else:
                            attr.append("!~"+self.imatch)

                data = {"container": container,
                        "image": image,
                        "ipaddr": ip,
                        "hostname": hostname,
                        "flags": ", ".join(attr)}
                dinfo = [data] + dinfo

        headers = {"container": "Container",
                   "image": "Image",
                   "hostname": "Hostname",
                   "ipaddr": "IP Addr",
                   "flags": "Flags"}

        maxlen = {}
        for key in dinfo[0]:
            flen = len(headers[key])
            for data in dinfo:
                if len(data[key]) > flen:
                    flen = len(data[key])
            maxlen[key] = flen

        fstr = "%-{0}s  %-{1}s  %-{2}s  %-{3}s  %s".format(
            maxlen['container'], maxlen['image'],
            maxlen['hostname'], maxlen['ipaddr'])

        print(fstr % (headers['container'], headers['image'],
                      headers['hostname'], headers['ipaddr'],
                      headers['flags']))

        for data in dinfo:
            print(fstr % (data['container'], data['image'],
                          data['hostname'], data['ipaddr'], data['flags']))
コード例 #11
0
ファイル: make-cluster.py プロジェクト: DALDEI/ml-docker
class App:
    def __init__(self):
        self.marklogic = None
        self.uname = pwd.getpwuid(os.getuid()).pw_name
        self.adminuser = "******"
        self.adminpass = "******"
        self.realm = "public"
        self.host = None
        self.boothost = None
        self.couple = None
        self.couple_user = None
        self.couple_pass = None
        self.name = None

    def set_credentials(self, user, password):
        self.adminuser = user
        self.adminpass = password

    def set_realm(self, realm):
        self.realm = realm

    def set_boot_host(self, host):
        self.boothost = host

    def set_host(self, name):
        self.host = name

    def set_couple(self, couple):
        self.couple = couple

    def set_couple_credentials(self, user, password):
        self.couple_user = user
        self.couple_pass = password

    def set_name(self, name):
        self.name = name

    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        if self.boothost is None:
            self.boothost = self.host[0]
            self.host.remove(self.boothost)

        if self.ml_init(self.boothost):
            self.ml_security(self.boothost)

        conn = Connection(self.boothost, HTTPDigestAuth(self.adminuser, self.adminpass))
        self.marklogic = MarkLogic(conn)

        for hostname in self.host:
            self.ml_init(hostname)
            self.ml_join(self.boothost, hostname)

        if self.name is not None:
            print("{0}: rename cluster...".format(self.boothost))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(self.boothost, couple))
                altconn = Connection(couple,
                                     HTTPDigestAuth(self.couple_user,
                                                    self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")

    def ml_init(self, hostname):
        print("{0}: initialize host...".format(hostname))
        try:
            host = MarkLogic.instance_init(hostname)
        except UnauthorizedAPIRequest:
            # Assume that this happened because the host is already initialized
            host = Host(hostname)

        return host.just_initialized()

    def ml_join(self, boothost, hostname):
        print("{0}: join cluster with {1}...".format(hostname, boothost))
        cluster = self.marklogic.cluster()
        host = Host(hostname)
        cluster.add_host(host)

    def ml_security(self, hostname):
        print("{0}: initialize security...".format(hostname))
        MarkLogic.instance_admin(hostname, self.realm, self.adminuser, self.adminpass)
コード例 #12
0
    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        self.load_blacklist()
        self.find_containers()

        if not self.container_list:
            print("There must be at least one unused container running.")
            sys.exit(1)

        if self.localimage:
            ps = os.popen("docker exec " + self.container_list[0] +
                          " ip route")
            for line in ps.readlines():
                match = re.match("^default via (\S+)", line)
                if match:
                    self.localip = match.group(1)
            if self.localip is None:
                print("Cannot find IP address of localhost!?")
                sys.exit(1)

        # Find the bootstrap image

        if self.localimage:
            pass
        else:
            self.bootimage = self.pick_image(self.bootimage)
            if self.bootimage in self.container_list:
                self.container_list.remove(self.bootimage)

        self.cluster_list = self.pick_containers()

        self.display_info()
        #sys.exit(1)

        # Initialize the bootstrap image, if necessary

        if self.localimage:
            bootip = self.localip
        else:
            bootip = self.ipaddr[self.bootimage]

        if self.ml_init(bootip, self.bootimage):
            self.ml_security(bootip, self.bootimage)

        conn = Connection(bootip, HTTPDigestAuth(self.adminuser,
                                                 self.adminpass))
        self.marklogic = MarkLogic(conn)

        for container in self.cluster_list:
            if container == self.bootimage:
                continue
            ip = self.ipaddr[container]
            self.ml_init(ip, container)
            self.ml_join(bootip, ip)

        if self.name is not None:
            print("{0}: rename cluster...".format(bootip))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(bootip, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")
コード例 #13
0
class Docker:
    def __init__(self):
        self.marklogic = None
        self.uname = pwd.getpwuid(os.getuid()).pw_name
        self.adminuser = "******"
        self.adminpass = "******"
        self.realm = "public"
        self.imatch = "ml[0-9]"
        self.bootimage = None
        self.localimage = False
        self.count = None
        self.couple = None
        self.couple_user = None
        self.couple_pass = None
        self.name = None
        self.blacklist_file = "/tmp/{0}.docker.skip".format(self.uname)
        self.blacklist = {}
        self.container_list = []
        self.cluster_list = []
        self.containers = {}
        self.localip = None
        self.ipaddr = {}
        self.hostname = {}

    def set_credentials(self, user, password):
        self.adminuser = user
        self.adminpass = password

    def set_realm(self, realm):
        self.realm = realm

    def set_image_match(self, match):
        self.imatch = match

    def set_boot_image(self, image):
        self.bootimage = image
        self.localimage = (image == "localhost")

    def set_count(self, count):
        self.count = count

    def set_couple(self, couple):
        self.couple = couple

    def set_couple_credentials(self, user, password):
        self.couple_user = user
        self.couple_pass = password

    def set_name(self, name):
        self.name = name

    def setup_cluster(self):
        if self.couple is not None and self.couple_pass is None:
            self.couple_pass = self.adminpass
            self.couple_user = self.adminuser

        self.load_blacklist()
        self.find_containers()

        if not self.container_list:
            print("There must be at least one unused container running.")
            sys.exit(1)

        if self.localimage:
            ps = os.popen("docker exec " + self.container_list[0] +
                          " ip route")
            for line in ps.readlines():
                match = re.match("^default via (\S+)", line)
                if match:
                    self.localip = match.group(1)
            if self.localip is None:
                print("Cannot find IP address of localhost!?")
                sys.exit(1)

        # Find the bootstrap image

        if self.localimage:
            pass
        else:
            self.bootimage = self.pick_image(self.bootimage)
            if self.bootimage in self.container_list:
                self.container_list.remove(self.bootimage)

        self.cluster_list = self.pick_containers()

        self.display_info()
        #sys.exit(1)

        # Initialize the bootstrap image, if necessary

        if self.localimage:
            bootip = self.localip
        else:
            bootip = self.ipaddr[self.bootimage]

        if self.ml_init(bootip, self.bootimage):
            self.ml_security(bootip, self.bootimage)

        conn = Connection(bootip, HTTPDigestAuth(self.adminuser,
                                                 self.adminpass))
        self.marklogic = MarkLogic(conn)

        for container in self.cluster_list:
            if container == self.bootimage:
                continue
            ip = self.ipaddr[container]
            self.ml_init(ip, container)
            self.ml_join(bootip, ip)

        if self.name is not None:
            print("{0}: rename cluster...".format(bootip))
            cluster = self.marklogic.cluster()
            cluster.set_cluster_name(self.name)
            cluster.update()

        if self.couple is not None:
            for couple in self.couple:
                print("{0}: couple with {1}...".format(bootip, couple))
                altconn = Connection(
                    couple, HTTPDigestAuth(self.couple_user, self.couple_pass))
                altml = MarkLogic(altconn)
                altcluster = altml.cluster()
                cluster = self.marklogic.cluster()
                cluster.couple(altcluster)

        print("Finished")

    def ml_init(self, ip, container):
        if container in self.hostname:
            hostname = self.hostname[container]
        else:
            hostname = container
        print("{0}: initialize host {1}...".format(ip, hostname))
        try:
            host = MarkLogic.instance_init(ip)
        except UnauthorizedAPIRequest:
            # Assume that this happened because the host is already initialized
            host = Host(ip)

        self.blacklist[container] = "used"
        self.save_blacklist()
        return host.just_initialized()

    def ml_join(self, bootip, ip):
        print("{0}: join cluster with {1}...".format(ip, bootip))
        cluster = self.marklogic.cluster()
        host = Host(ip)
        cluster.add_host(host)

    def ml_security(self, ip, container):
        print("{0}: initialize security...".format(ip))
        MarkLogic.instance_admin(ip, self.realm, self.adminuser,
                                 self.adminpass)
        self.blacklist[container] = "boot"
        self.save_blacklist()

    def pick_image(self, name):
        if name is None:
            for container in self.container_list:
                if not container in self.blacklist:
                    return container
            print("Cannot find unused container")
            sys.exit(1)

        for key in self.hostname:
            if name == self.hostname[key]:
                return key

        count = 0
        container = None
        for key in self.ipaddr:
            if name == self.ipaddr[key]:
                return key
            if re.match("^" + name, key):
                count += 1
                container = key
        if count == 1:
            return container
        if count > 1:
            print("Ambiguous container id:", name)
            sys.exit(1)

        for key in self.containers:
            image = self.containers[key]
            if (key == self.bootimage or re.match(self.bootimage, image)):
                return key

        print("Cannot find container \"{0}\".".format(name))
        sys.exit(1)

    def pick_containers(self):
        if self.count is None:
            count = -1
        else:
            count = self.count - 1

        cset = set()

        if not self.localimage:
            cset.add(self.bootimage)

        for container in self.container_list:
            if container == self.bootimage or container in self.blacklist:
                continue
            if count == 0:
                continue
            cset.add(container)
            count -= 1

        containers = []
        for key in cset:
            containers.append(key)
        return containers

    def load_blacklist(self):
        try:
            f = open(self.blacklist_file, "r")
            for line in f.readlines():
                (container, flag) = line.strip().split(" ")
                self.blacklist[container] = flag
            f.close()
        except FileNotFoundError:
            pass

    def save_blacklist(self):
        f = open(self.blacklist_file, "w")
        for key in self.blacklist:
            if self.blacklist[key] != "gone":
                f.write("{0} {1}\n".format(key, self.blacklist[key]))
        f.close()

    def find_containers(self):
        self.load_blacklist()

        ps = os.popen("docker ps")
        for line in ps.readlines():
            match = re.match("([0-9a-f]+)\s+(\S+)", line)
            if match:
                container = match.group(1)
                image = match.group(2)

                ipx = os.popen("docker inspect {0}".format(container))
                ip = None
                hostname = None
                for line in ipx.readlines():
                    match = re.match('\s+"IPAddress": "([^"]+)"', line)
                    if match:
                        ip = match.group(1)
                    match = re.match('\s+"Hostname": "([^"]+)"', line)
                    if match:
                        hostname = match.group(1)
                if ip is None:
                    print("Cannot read IP address of container {0}".format(
                        container))
                else:
                    self.ipaddr[container] = ip

                if hostname is None:
                    print("Cannot read hostname of container {0}".format(
                        container))
                else:
                    self.hostname[container] = hostname

                if re.match(self.imatch, image):
                    self.container_list = [container] + self.container_list
                    self.containers[container] = image

        for container in self.blacklist:
            if not container in self.containers:
                self.blacklist[container] = "gone"

    def display_info(self):
        # Display information about docker containers
        # Sigh. Report formatting is such a drag...
        dinfo = []
        ps = os.popen("docker ps")
        for line in ps.readlines():
            match = re.match("([0-9a-f]+)\s+(\S+)", line)
            if match:
                container = match.group(1)
                image = match.group(2)
                ip = self.ipaddr[container]
                hostname = self.hostname[container]
                attr = []
                if container in self.blacklist:
                    attr.append("used")
                    if self.blacklist[container] == "boot":
                        attr.append("boot")
                else:
                    if not container in self.cluster_list:
                        attr.append("skip")
                    else:
                        if re.match(self.imatch, image):
                            attr.append("*")
                            if container == self.bootimage:
                                attr.append("boot")
                        else:
                            attr.append("!~" + self.imatch)

                data = {
                    "container": container,
                    "image": image,
                    "ipaddr": ip,
                    "hostname": hostname,
                    "flags": ", ".join(attr)
                }
                dinfo = [data] + dinfo

        headers = {
            "container": "Container",
            "image": "Image",
            "hostname": "Hostname",
            "ipaddr": "IP Addr",
            "flags": "Flags"
        }

        maxlen = {}
        for key in dinfo[0]:
            flen = len(headers[key])
            for data in dinfo:
                if len(data[key]) > flen:
                    flen = len(data[key])
            maxlen[key] = flen

        fstr = "%-{0}s  %-{1}s  %-{2}s  %-{3}s  %s".format(
            maxlen['container'], maxlen['image'], maxlen['hostname'],
            maxlen['ipaddr'])

        print(fstr %
              (headers['container'], headers['image'], headers['hostname'],
               headers['ipaddr'], headers['flags']))

        for data in dinfo:
            print(fstr % (data['container'], data['image'], data['hostname'],
                          data['ipaddr'], data['flags']))