def disconnect_instance(self, instance_num): blueprint = self.blueprint allocation = self.allocation instance_id = self.group_id + '_' + instance_num addr = blueprint['instances'][instance_num]['addr'] memsize = blueprint['memsize'] network_settings = Sense.network_settings() network_name = network_settings['network_name'] if not network_name: raise RuntimeError("Network name is not specified in settings") docker_host = allocation['instances'][instance_num]['host'] docker_hosts = Sense.docker_hosts() docker_addr = None for host in docker_hosts: if host['addr'].split(':')[0] == docker_host or \ host['consul_host'] == docker_host: docker_addr = host['addr'] if not docker_addr: raise RuntimeError("No such Docker host: '%s'" % docker_host) docker_obj = docker.Client(base_url=docker_addr, tls=global_env.docker_tls_config) try: docker_obj.disconnect_container_from_network(instance_id, network_name, force=True) except: pass
def ensure_network(self, docker_addr): docker_obj = docker.Client(base_url=docker_addr, tls=global_env.docker_tls_config) settings = Sense.network_settings() network_name = settings['network_name'] subnet = settings['subnet'] if not network_name: raise RuntimeError("Network name not specified") network_exists = any([n['Name'] == network_name for n in docker_obj.networks()]) if network_exists: return if not settings['create_automatically']: raise RuntimeError(("No network '%s' exists and automatic creation" + "prohibited") % network_name) ipam_pool = docker.utils.create_ipam_pool( subnet=subnet ) ipam_config = docker.utils.create_ipam_config( pool_configs=[ipam_pool] ) logging.info("Creating network '%s'", network_name) docker_obj.create_network(name=network_name, driver='bridge', ipam=ipam_config)
def allocate_ip(skip=[]): global IP_CACHE global CACHE_LOCK docker_nodes = [h for h in Sense.docker_hosts() if h['status'] == 'passing'] network_settings = Sense.network_settings() subnet = network_settings['subnet'] gateway_ip = network_settings['gateway_ip'] if gateway_ip: skip += [gateway_ip] if not subnet: raise RuntimeError("Subnet is not specified in settings") invalidate_cache() with CACHE_LOCK: allocated_ips = set(IP_CACHE.keys()) # collect instances from blueprints for blueprint in Sense.blueprints().values(): for instance in blueprint['instances'].values(): allocated_ips.add(instance['addr']) net = ipaddress.ip_network(subnet) except_list = allocated_ips.union(set(skip)) for addr in net: if str(addr) not in except_list and\ not str(addr).endswith('.0'): IP_CACHE[str(addr)] = datetime.datetime.now() return str(addr) raise RuntimeError('IP Address range exhausted')
def upgrade_container(self, instance_num): group_id = self.group_id logging.info("Upgrading container '%s'", group_id) blueprint = self.blueprint allocation = self.allocation instance_id = self.group_id + '_' + instance_num addr = blueprint['instances'][instance_num]['addr'] memsize = blueprint['memsize'] network_settings = Sense.network_settings() network_name = network_settings['network_name'] if not network_name: raise RuntimeError("Network name is not specified in settings") docker_host = allocation['instances'][instance_num]['host'] docker_hosts = Sense.docker_hosts() docker_addr = None for host in docker_hosts: if host['addr'].split(':')[0] == docker_host or \ host['consul_host'] == docker_host: docker_addr = host['addr'] if not docker_addr: raise RuntimeError("No such Docker host: '%s'" % docker_host) replica_ip = None if instance_num == '2': replica_ip = blueprint['instances']['1']['addr'] docker_obj = docker.Client(base_url=docker_addr, tls=global_env.docker_tls_config) self.ensure_image(docker_addr) self.ensure_network(docker_addr) mounts = docker_obj.inspect_container(instance_id)["Mounts"] binds = [] for mount in mounts: if mount['Destination'] == '/opt/tarantool': # code should be upgraded along with container continue logging.info("Keeping mount %s:%s", mount["Source"], mount["Destination"]) rw_flag = "rw" if mount['RW'] else "ro" binds.append("%s:%s:%s" % (mount['Source'], mount['Destination'], rw_flag)) docker_obj.stop(container=instance_id) docker_obj.remove_container(container=instance_id) host_config = docker_obj.create_host_config( restart_policy = { "MaximumRetryCount": 0, "Name": "unless-stopped" }, binds = binds ) cmd = 'tarantool /opt/tarantool/app.lua' networking_config = { 'EndpointsConfig': { network_name: { 'IPAMConfig': { "IPv4Address": addr, "IPv6Address": "" }, "Links": [], "Aliases": [] } } } environment = {} environment['TARANTOOL_SLAB_ALLOC_ARENA'] = float(memsize)/1024 if replica_ip: environment['TARANTOOL_REPLICATION_SOURCE'] = replica_ip + ':3301' container = docker_obj.create_container(image='tarantool-cloud-memcached', name=instance_id, command=cmd, host_config=host_config, networking_config=networking_config, environment=environment, labels=['tarantool']) docker_obj.connect_container_to_network(container.get('Id'), network_name, ipv4_address=addr) docker_obj.start(container=container.get('Id'))
def create_container(self, instance_num, other_instance_num, password, password_base64): blueprint = self.blueprint allocation = self.allocation instance_id = self.group_id + '_' + instance_num addr = blueprint['instances'][instance_num]['addr'] memsize = blueprint['memsize'] network_settings = Sense.network_settings() network_name = network_settings['network_name'] if not network_name: raise RuntimeError("Network name is not specified in settings") docker_host = allocation['instances'][instance_num]['host'] docker_hosts = Sense.docker_hosts() docker_addr = None for host in docker_hosts: if host['addr'].split(':')[0] == docker_host or \ host['consul_host'] == docker_host: docker_addr = host['addr'] if not docker_addr: raise RuntimeError("No such Docker host: '%s'" % docker_host) replica_ip = None if other_instance_num is not None: replica_ip = blueprint['instances'][other_instance_num]['addr'] docker_obj = docker.Client(base_url=docker_addr, tls=global_env.docker_tls_config) self.ensure_image(docker_addr) self.ensure_network(docker_addr) if not replica_ip: logging.info("Creating memcached '%s' on '%s' with ip '%s'", instance_id, docker_obj.base_url, addr) else: logging.info("Creating memcached '%s' on '%s' with ip '%s'" + " and replication source: '%s'", instance_id, docker_obj.base_url, addr, replica_ip) host_config = docker_obj.create_host_config( restart_policy = { "MaximumRetryCount": 0, "Name": "unless-stopped" }) cmd = 'tarantool /opt/tarantool/app.lua' networking_config = { 'EndpointsConfig': { network_name: { 'IPAMConfig': { "IPv4Address": addr, "IPv6Address": "" }, "Links": [], "Aliases": [] } } } environment = {} environment['TARANTOOL_SLAB_ALLOC_ARENA'] = float(memsize)/1024 if password: environment['MEMCACHED_PASSWORD'] = password if password_base64: environment['MEMCACHED_PASSWORD_BASE64'] = password_base64 if replica_ip: environment['TARANTOOL_REPLICATION_SOURCE'] = replica_ip + ':3301' container = docker_obj.create_container(image='tarantool-cloud-memcached', name=instance_id, command=cmd, host_config=host_config, networking_config=networking_config, environment=environment, labels=['tarantool']) docker_obj.connect_container_to_network(container.get('Id'), network_name, ipv4_address=addr) docker_obj.start(container=container.get('Id'))
def create_containers(self, password): instance_num = '1' blueprint = self.blueprint allocation = self.allocation instance_id = self.group_id + '_' + instance_num addr = blueprint['instances'][instance_num]['addr'] memsize = blueprint['memsize'] network_settings = Sense.network_settings() network_name = network_settings['network_name'] if not network_name: raise RuntimeError("Network name is not specified in settings") docker_host = allocation['instances'][instance_num]['host'] docker_hosts = Sense.docker_hosts() docker_addr = None for host in docker_hosts: if host['addr'].split(':')[0] == docker_host or \ host['consul_host'] == docker_host: docker_addr = host['addr'] if not docker_addr: raise RuntimeError("No such Docker host: '%s'" % docker_host) replica_ip = None if instance_num == '2': replica_ip = blueprint['instances']['1']['addr'] docker_obj = docker.Client(base_url=docker_addr, tls=global_env.docker_tls_config) self.ensure_image(docker_addr) self.ensure_network(docker_addr) if not replica_ip: logging.info("Creating tarantino '%s' on '%s' with ip '%s'", instance_id, docker_obj.base_url, addr) else: logging.info("Creating tarantino '%s' on '%s' with ip '%s'" + " and replication source: '%s'", instance_id, docker_obj.base_url, addr, replica_ip) host_config = docker_obj.create_host_config( restart_policy = { "MaximumRetryCount": 0, "Name": "unless-stopped" }) networking_config = { 'EndpointsConfig': { network_name: { 'IPAMConfig': { "IPv4Address": addr, "IPv6Address": "" }, "Links": [], "Aliases": [] } } } environment = {} environment['TARANTOOL_SLAB_ALLOC_ARENA'] = float(memsize)/1024 if password: environment['MEMCACHED_PASSWORD'] = password container = docker_obj.create_container(image='tarantool/tarantino', name=instance_id, host_config=host_config, networking_config=networking_config, environment=environment, labels=['tarantool']) docker_obj.connect_container_to_network(container.get('Id'), network_name, ipv4_address=addr) docker_obj.start(container=container.get('Id'))