Exemple #1
0
 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"