def _execute_container_script(self, app, interface, args=None, credentials=True, output=False, cmd_args=None, cmd_kwargs=None): cmd_args = cmd_args or [] cmd_kwargs = cmd_kwargs or {} self.log('Executing interface %s for %s' % (interface, app.id)) docker = self._get_docker(app) interface_file = getattr(app, 'docker_script_%s' % interface) if not interface_file: self.log('No interface defined') return None remote_interface_script = app.get_cache_file(interface) container_interface_script = docker.path(interface_file) if os.path.exists(remote_interface_script): self.log('Copying App Center\'s %s to container\'s %s' % (interface, interface_file)) mkdir(os.path.dirname(container_interface_script)) shutil.copy2(remote_interface_script, container_interface_script) os.chmod(container_interface_script, 0o755) # -rwxr-xr-x if not os.path.exists(container_interface_script): self.warn('Interface script %s not found!' % interface_file) return None with docker.tmp_file() as error_file: with docker.tmp_file() as password_file: if credentials: self._get_ldap_connection( args, allow_machine_connection=False, allow_admin_connection=False ) # to get a working username/password username = self._get_username(args) password = self._get_password(args) with open(password_file.name, 'w') as f: f.write(password) cmd_kwargs['username'] = username cmd_kwargs['password_file'] = password_file.container_path cmd_kwargs['error_file'] = error_file.container_path cmd_kwargs['app'] = app.id cmd_kwargs['app_version'] = app.version # locale = get_locale() # if locale: # cmd_kwargs['locale'] = locale cmd_kwargs['_tty'] = False if output: logger = LogCatcher(self.logger) cmd_kwargs['_logger'] = logger process = docker.execute(interface_file, *cmd_args, **cmd_kwargs) if process.returncode != 0: with open(error_file.name, 'r+b') as error_handle: for line in error_handle: self.fatal(line) if output: return process, logger return process
def _get_app_ucr_filename(cls, app): docker = cls._get_docker(app) ucr_file = docker.path('/etc/univention/base.conf') if ucr_file: mkdir(os.path.dirname(ucr_file)) return ucr_file raise NoDatabaseFound()
def get_cache_dir(self): if self._cache_dir is None: server = self.get_server_netloc() self._cache_dir = os.path.join(CACHE_DIR, server, self.get_ucs_version()) mkdir(self._cache_dir) return self._cache_dir
def main(self, args): meta_inf_dir = os.path.join(args.path, 'meta-inf', args.ucs_version) repo_dir = os.path.join(args.path, 'univention-repository', args.ucs_version) if args.revert: try: shutil.rmtree(os.path.dirname(meta_inf_dir)) except OSError as exc: self.warn(exc) try: shutil.rmtree(os.path.dirname(repo_dir)) except OSError as exc: self.warn(exc) use_test_appcenter = get_action('dev-use-test-appcenter') use_test_appcenter.call_safe(revert=True) else: mkdir(meta_inf_dir) mkdir(os.path.join(repo_dir, 'maintained', 'component')) for supra_file in ['categories.ini', 'rating.ini', 'license_types.ini', 'ucs.ini']: with open(os.path.join(meta_inf_dir, '..', supra_file), 'wb') as f: categories = urlopen('%s/meta-inf/%s' % (default_server(), supra_file)).read() f.write(categories) server = 'http://%s' % args.appcenter_host use_test_appcenter = get_action('dev-use-test-appcenter') use_test_appcenter.call_safe(appcenter_host=server) DevRegenerateMetaInf.call_safe(ucs_version=args.ucs_version, path=args.path, appcenter_host=server) self.log('Local App Center server is set up at %s.' % server) self.log('If this server should serve as an App Center server for other computers in the UCS domain, the following command has to be executed on each computer:') self.log(' univention-app dev-use-test-appcenter --appcenter-host="%s"' % server)
def pull(self): mkdir(self.app.get_compose_dir()) yml_file = self.app.get_compose_file('docker-compose.yml') shutil.copy2(self.app.get_cache_file('compose'), yml_file) os.chmod(yml_file, 0600) self.logger.info('Downloading app images') ret, out = call_process2(['docker-compose', '-p', self.app.id, 'pull'], cwd=self.app.get_compose_dir(), logger=_logger) if ret != 0: raise DockerImagePullFailed(self.image, out)
def _execute_container_script(self, _app, _interface, _args=None, _credentials=True, _output=False, **kwargs): self.log('Executing interface %s for %s' % (_interface, _app.id)) docker = self._get_docker(_app) interface = getattr(_app, 'docker_script_%s' % _interface) if not interface: self.log('No interface defined') return None remote_interface_script = _app.get_cache_file(_interface) container_interface_script = docker.path(interface) if os.path.exists(remote_interface_script): self.log('Copying App Center\'s %s to container\'s %s' % (_interface, interface)) mkdir(os.path.dirname(container_interface_script)) shutil.copy2(remote_interface_script, container_interface_script) os.chmod(container_interface_script, 0o755) # -rwxr-xr-x if not os.path.exists(container_interface_script): self.warn('Interface script %s not found!' % interface) return None with docker.tmp_file() as error_file: with docker.tmp_file() as password_file: if _credentials: self._get_ldap_connection( _args) # to get a working username/password username = self._get_username(_args) password = self._get_password(_args) with open(password_file.name, 'w') as f: f.write(password) kwargs['username'] = username kwargs['password_file'] = password_file.container_path kwargs['error_file'] = error_file.container_path kwargs['app'] = _app.id kwargs['app_version'] = _app.version # locale = get_locale() # if locale: # kwargs['locale'] = locale if _output: return docker.execute_with_output(interface, **kwargs) else: process = docker.execute(interface, **kwargs) if process.returncode != 0: with open(error_file.name, 'r+b') as error_handle: for line in error_handle: self.fatal(line) return process
def _build_repo_dir(self, app, component_id, path, ucs_version): repo_dir = os.path.join(path, 'univention-repository', ucs_version, 'maintained', 'component', component_id) mkdir(os.path.join(repo_dir)) if not app.without_repository: mkdir(os.path.join(repo_dir, 'all')) mkdir(os.path.join(repo_dir, 'i386')) mkdir(os.path.join(repo_dir, 'amd64')) return component_id, app.id
def main(self, args): component_id = args.component_id app_id = None if args.new: component_id, app_id = self._create_new_repo(args) meta_inf_dir = os.path.join(args.path, 'meta-inf', args.ucs_version) if LooseVersion(args.ucs_version) >= '4.1': if app_id is None: if args.ini: ini_file = args.ini else: for root, dirnames, filenames in os.walk(meta_inf_dir): for filename in filenames: if filename == '%s.ini' % component_id: ini_file = os.path.join(root, filename) break else: continue break else: raise Abort( 'Could not determine app id. Specify an --ini file!' ) app = App.from_ini(ini_file) app_id = app.id meta_inf_dir = os.path.join(meta_inf_dir, app_id) mkdir(meta_inf_dir) repo_dir = os.path.join(args.path, 'univention-repository', args.ucs_version, 'maintained', 'component', component_id) mkdir(repo_dir) if args.unmaintained: version = ucr_get('version/version') if args.ucs_version != version: self.fatal( 'Cannot easily set up unmaintained packages for %s (need %s). You need to download them into the repository manually. Sorry!' % (args.ucs_version, version)) else: self._copy_unmaintained_packages(repo_dir, args) app = self._copy_meta_files(component_id, meta_inf_dir, repo_dir, args) if app and args.packages: self._handle_packages(app, repo_dir, args) self._generate_repo_index_files(repo_dir) self._generate_meta_index_files(args) self.log('Component is: %s' % component_id)
def _setup_env(self, env=None): if os.path.exists(self.app.get_cache_file( 'env')) and self.app.docker_inject_env_file: mkdir(self.app.get_compose_dir()) env_file_name = '{}.env'.format(self.app.id) env_file = os.path.join(self.app.get_compose_dir(), env_file_name) # remove old env file try: os.remove(env_file) except OSError: pass # create new env file fd = os.open(env_file, os.O_RDWR | os.O_CREAT) os.chmod(env_file, 0o400) with os.fdopen(fd, 'w') as outfile: with open(self.app.get_cache_file('env'), 'r') as infile: outfile.write(ucr_run_filter(infile.read(), env)) outfile.write('\n') self.env_file_created = env_file_name
def main(self, args): something_changed = False for app_cache in self._app_caches(args): # first of all, set up local cache mkdir(app_cache.get_cache_dir()) if self._extract_local_archive(app_cache): something_changed = True for appcenter_cache in self._appcenter_caches(args): # download meta files like index.json mkdir(appcenter_cache.get_cache_dir()) if self._download_supra_files(appcenter_cache): appcenter_cache.clear_cache() something_changed = True for app_cache in self._app_caches(args): # try it one more time (ucs.ini may have changed) mkdir(app_cache.get_cache_dir()) if self._extract_local_archive(app_cache): something_changed = True # download apps based on meta files if self._download_apps(app_cache): app_cache.clear_cache() something_changed = True if something_changed: apps_cache = Apps() for app in apps_cache.get_all_locally_installed_apps(): newest_app = apps_cache.find_candidate(app) or app if app < newest_app: ucr_save({app.ucr_upgrade_key: 'yes'}) self._update_local_files()
def _register_files(self, app): self.log('Creating data directories for %s...' % app.id) mkdir(app.get_data_dir()) mkdir(app.get_conf_dir()) mkdir(app.get_share_dir()) for ext in ['univention-config-registry-variables', 'schema']: fname = app.get_cache_file(ext) if os.path.exists(fname): self.log('Copying %s' % fname) shutil.copy2(fname, app.get_share_file(ext)) else: if ext == 'schema': schema = get_schema(app) if schema: with open(app.get_share_file(ext), 'wb') as fd: fd.write(schema)
def _touch_file(self, filename): if not os.path.exists(filename): mkdir(os.path.dirname(filename)) open(filename, 'wb')
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"