def test_install(self, app): conflictedapps = set() apps_cache = Apps() # check ConflictedApps for _app in apps_cache.get_all_apps(): if not _app._allowed_on_local_server(): # cannot be installed, continue continue if _app.id in app.conflicted_apps or app.id in _app.conflicted_apps: if _app.is_installed(): conflictedapps.add(_app.id) elif _app in self.other_apps(app): conflictedapps.add(_app.id) # check port conflicts ports = [] for i in app.ports_exclusive: ports.append(i) for i in app.ports_redirection: ports.append(i.split(':', 1)[0]) for app_id, container_port, host_port in app_ports(): if app_id != app.id and str(host_port) in ports: conflictedapps.add(app_id) for _app in self.other_apps(app): other_ports = set() for i in _app.ports_exclusive: other_ports.add(i) for i in _app.ports_redirection: other_ports.add(i.split(':', 1)[0]) if other_ports.intersection(ports): conflictedapps.add(_app.id) if conflictedapps: conflictedapps = [ apps_cache.find(app_id) for app_id in conflictedapps ] return [{ 'id': _app.id, 'name': _app.name } for _app in conflictedapps if _app]
def _register_ports(self, app): updates = {} current_port_config = {} for app_id, container_port, host_port in app_ports(): if app_id == app.id: current_port_config[app.ucr_ports_key % container_port] = str(host_port) updates[app.ucr_ports_key % container_port] = None updates[app.ucr_ports_key % container_port + '/protocol'] = None if app.docker and app.plugin_of: # handling for plugins of Docker Apps: copy ports of base App for app_id, container_port, host_port, proto in app_ports_with_protocol(): if app_id == app.plugin_of: updates[app.ucr_ports_key % container_port] = str(host_port) updates[app.ucr_ports_key % container_port + '/protocol'] = proto ucr_save(updates) return for port in app.ports_exclusive: updates[app.ucr_ports_key % port] = str(port) redirection_ports = [] for port in app.ports_redirection: redirection_ports.append((port, 'tcp')) for port in app.ports_redirection_udp: redirection_ports.append((port, 'udp')) for port, protocol in redirection_ports: host_port, container_port = port.split(':') protocol_key = app.ucr_ports_key % container_port + '/protocol' protocol_value = updates.get(protocol_key) if protocol_value: protocol_value = '%s, %s' % (protocol_value, protocol) else: protocol_value = protocol updates[protocol_key] = protocol_value updates[app.ucr_ports_key % container_port] = str(host_port) if app.auto_mod_proxy and app.has_local_web_interface(): self.log('Setting ports for apache proxy') try: min_port = int(ucr_get('appcenter/ports/min')) except (TypeError, ValueError): min_port = 40000 try: max_port = int(ucr_get('appcenter/ports/max')) except (TypeError, ValueError): max_port = 41000 ports_taken = set() for app_id, container_port, host_port in app_ports(): if host_port < max_port: ports_taken.add(host_port) if app.web_interface_port_http: key = app.ucr_ports_key % app.web_interface_port_http if key in current_port_config: value = current_port_config[key] else: next_port = currently_free_port_in_range(min_port, max_port, ports_taken) ports_taken.add(next_port) value = str(next_port) updates[key] = value if app.web_interface_port_https: key = app.ucr_ports_key % app.web_interface_port_https if key in current_port_config: value = current_port_config[key] else: next_port = currently_free_port_in_range(min_port, max_port, ports_taken) ports_taken.add(next_port) value = str(next_port) updates[key] = value for container_port, host_port in current_port_config.iteritems(): if container_port in updates: if updates[container_port] == host_port: updates.pop(container_port) if updates: # save immediately, no delay: next call needs to know # about the (to be) registered ports ucr_save(updates)
def _setup_yml(self, recreate, env=None): env = env or {} yml_file = self.app.get_compose_file('docker-compose.yml') yml_run_file = '%s.run' % yml_file if not recreate: if os.path.exists(yml_file): return elif os.path.exists(yml_run_file): shutil.move(yml_run_file, yml_file) return template_file = '%s.template' % yml_file mkdir(self.app.get_compose_dir()) shutil.copy2(self.app.get_cache_file('compose'), template_file) with open(template_file) as fd: template = fd.read() content = ucr_run_filter(template) with open(yml_file, 'wb') as fd: os.chmod(yml_file, 0600) fd.write(content) content = yaml.load(open(yml_file), yaml.RoundTripLoader, preserve_quotes=True) container_def = content['services'][self.app.docker_main_service] volumes = container_def.get('volumes', []) for volume in self._app_volumes(): if volume not in volumes: volumes.append(volume) container_def['volumes'] = volumes exposed_ports = {} used_ports = {} ip_addresses = None if 'networks' not in content: network = self._get_app_network() if network: content['networks'] = { 'appcenter_net': { 'ipam': { 'driver': 'default', 'config': [{ 'subnet': network.compressed }] } } } ucr_save({self.app.ucr_ip_key: str(network)}) ip_addresses = network.iterhosts() # iterator! ip_addresses.next() # first one for docker gateway for service_name, service in content['services'].iteritems(): exposed_ports[service_name] = ( int(port) for port in service.get('expose', [])) used_ports[service_name] = {} for port in service.get('ports', []): try: _port = int(port) except ValueError: host_port, container_port = (int(_port) for _port in port.split(':')) used_ports[service_name][container_port] = host_port else: used_ports[service_name][_port] = _port if ip_addresses and not service.get( 'networks') and service.get('network_mode') != 'bridge': service['networks'] = { 'appcenter_net': { 'ipv4_address': str(ip_addresses.next()) } } if 'environment' not in container_def: container_def['environment'] = {} if isinstance(container_def['environment'], list): for key, val in env.iteritems(): container_def['environment'].append('{}={}'.format(key, val)) else: container_def['environment'].update(env) for app_id, container_port, host_port in app_ports(): if app_id != self.app.id: continue for service_name, ports in exposed_ports.iteritems(): if container_port in ports: used_ports[service_name][container_port] = host_port break else: for service_name, ports in used_ports.iteritems(): if container_port in ports: used_ports[service_name][container_port] = host_port break else: used_ports[self.app. docker_main_service][container_port] = host_port for service_name, ports in used_ports.iteritems(): content['services'][service_name]['ports'] = [ '%s:%s' % (host_port, container_port) for container_port, host_port in ports.iteritems() ] with open(yml_file, 'wb') as fd: yaml.dump(content, fd, Dumper=yaml.RoundTripDumper, encoding='utf-8', allow_unicode=True) shutil.copy2(yml_file, yml_run_file) # "backup"
def _setup_yml(self, recreate, env=None): env = env or {} yml_file = self.app.get_compose_file('docker-compose.yml') yml_run_file = '%s.run' % yml_file if not recreate: if os.path.exists(yml_file): return elif os.path.exists(yml_run_file): shutil.move(yml_run_file, yml_file) return template_file = '%s.template' % yml_file mkdir(self.app.get_compose_dir()) shutil.copy2(self.app.get_cache_file('compose'), template_file) os.chmod(yml_file, 0600) with open(template_file) as fd: template = fd.read() content = ucr_run_filter(template) with open(yml_file, 'wb') as fd: fd.write(content) content = yaml.load(open(yml_file), yaml.RoundTripLoader, preserve_quotes=True) container_def = content['services'][self.app.docker_main_service] volumes = container_def.get('volumes', []) for volume in self._app_volumes(): if volume not in volumes: volumes.append(volume) container_def['volumes'] = volumes exposed_ports = {} used_ports = {} for service_name, service in content['services'].iteritems(): exposed_ports[service_name] = (int(port) for port in service.get('expose', [])) used_ports[service_name] = {} for port in service.get('ports', []): try: _port = int(port) except ValueError: host_port, container_port = (int(_port) for _port in port.split(':')) used_ports[service_name][container_port] = host_port else: used_ports[service_name][_port] = _port service_env = service.get('environment') if service_env: if isinstance(service_env, list): service_env = {k: None for k in service_env} for k in env.copy(): if k in service_env: service_env[k] = env.pop(k) service['environment'] = service_env if 'environment' not in container_def: container_def['environment'] = {} container_def['environment'].update(env) for app_id, container_port, host_port in app_ports(): if app_id != self.app.id: continue for service_name, ports in exposed_ports.iteritems(): if container_port in ports: used_ports[service_name][container_port] = host_port break else: for service_name, ports in used_ports.iteritems(): if container_port in ports: used_ports[service_name][container_port] = host_port break else: used_ports[self.app.docker_main_service][container_port] = host_port for service_name, ports in used_ports.iteritems(): content['services'][service_name]['ports'] = ['%s:%s' % (host_port, container_port) for container_port, host_port in ports.iteritems()] with open(yml_file, 'wb') as fd: yaml.dump(content, fd, Dumper=yaml.RoundTripDumper, encoding='utf-8', allow_unicode=True) shutil.copy2(yml_file, yml_run_file) # "backup"