Exemplo n.º 1
0
	def __init__(self, name, version, container_version=None, app_directory_suffix=None, package_name=None, build_package=True, call_join_scripts=True):
		self.app_name = name
		self.app_version = version
		self.call_join_scripts = call_join_scripts

		if not app_directory_suffix:
			self.app_directory_suffix = random_version()
		else:
			self.app_directory_suffix = app_directory_suffix

		self.app_directory = '%s_%s' % (self.app_name, self.app_directory_suffix)

		if package_name:
			self.package_name = package_name
		else:
			self.package_name = get_app_name()

		self.package_version = '%s.%s' % (version, get_app_version())

		self.ucr = ConfigRegistry()
		self.ucr.load()

		if build_package:
			self.package = DebianPackage(name=self.package_name, version=self.package_version)
			self.package.build()
		else:
			self.package = None

		self.ini = {}

		self.ini['ID'] = self.app_name
		self.ini['Code'] = self.app_name[0:2]
		self.ini['Name'] = self.app_name
		self.ini['Version'] = self.app_version
		self.ini['NotifyVendor'] = False
		self.ini['Categories'] = 'System services'
		self.ini['Logo'] = '%s.svg' % self.app_name
		if self.package:
			self.ini['DefaultPackages'] = self.package_name
		self.ini['ServerRole'] = 'domaincontroller_master,domaincontroller_backup,domaincontroller_slave,memberserver'

		self.scripts = {}

		if not container_version:
			self.ucs_version = self.ucr.get('version/version')
		else:
			self.ucs_version = container_version
			self.ini['SupportedUCSVersions'] = '%s-0,%s-0' % (container_version, self.ucr.get('version/version'))

		self.installed = False

		self.admin_user = self.ucr.get('tests/domainadmin/account').split(',')[0][len('uid='):]
		self.admin_pwdfile = self.ucr.get('tests/domainadmin/pwdfile')

		print repr(self)
Exemplo n.º 2
0
class App(object):
    def __init__(self,
                 name,
                 version,
                 container_version=None,
                 app_directory_suffix=None,
                 package_name=None,
                 build_package=True,
                 call_join_scripts=True):
        self.app_name = name
        self.app_version = version
        self.call_join_scripts = call_join_scripts

        if not app_directory_suffix:
            self.app_directory_suffix = random_version()
        else:
            self.app_directory_suffix = app_directory_suffix

        self.app_directory = '%s_%s' % (self.app_name,
                                        self.app_directory_suffix)

        if package_name:
            self.package_name = package_name
        else:
            self.package_name = get_app_name()

        self.package_version = '%s.%s' % (version, get_app_version())

        self.ucr = ConfigRegistry()
        self.ucr.load()

        if build_package:
            self.package = DebianPackage(name=self.package_name,
                                         version=self.package_version)
            self.package.build()
        else:
            self.package = None

        self.ini = {}

        self.ini['ID'] = self.app_name
        self.ini['Code'] = self.app_name[0:2]
        self.ini['Name'] = self.app_name
        self.ini['Version'] = self.app_version
        self.ini['NotifyVendor'] = False
        self.ini['Categories'] = 'System services'
        self.ini['Logo'] = '%s.svg' % self.app_name
        if self.package:
            self.ini['DefaultPackages'] = self.package_name
        self.ini[
            'ServerRole'] = 'domaincontroller_master,domaincontroller_backup,domaincontroller_slave,memberserver'

        self.scripts = {}

        if not container_version:
            self.ucs_version = self.ucr.get('version/version')
        else:
            self.ucs_version = container_version
            # make sure version of default appbox image is part of SupportedUCSVersions
            self.ini['SupportedUCSVersions'] = '%s-0,4.3-0,%s-0' % (
                container_version, self.ucr.get('version/version'))

        self.installed = False

        self.admin_user = self.ucr.get('tests/domainadmin/account').split(
            ',')[0][len('uid='):]
        self.admin_pwdfile = self.ucr.get('tests/domainadmin/pwdfile')

        print repr(self)

    def __repr__(self):
        return '%s(app_name=%r, app_version=%r)' % (super(
            App, self).__repr__(), self.app_name, self.app_version)

    def set_ini_parameter(self, **kwargs):
        for key, value in kwargs.iteritems():
            print 'set_ini_parameter(%s=%s)' % (key, value)
            self.ini[key] = value

    def add_to_local_appcenter(self):
        self._dump_ini()
        if self.package:
            self._copy_package()
        self._dump_scripts()

    def add_script(self, **kwargs):
        for key, value in kwargs.iteritems():
            self.scripts[key] = value

    def install(self):
        print 'App.install()'
        self._update()
        cmd = ['univention-app', 'install']
        if self.call_join_scripts is False:
            cmd.append('--do-not-call-join-scripts')
        cmd.append('--noninteractive')
        cmd.append('--username=%s' % self.admin_user)
        cmd.append('--pwdfile=%s' % self.admin_pwdfile)
        cmd.append('%s=%s' % (self.app_name, self.app_version))
        print cmd
        ret = subprocess.call(' '.join(cmd), shell=True)
        if ret != 0:
            raise UCSTest_DockerApp_InstallationFailed()

        self.ucr.load()
        self.container_id = self.ucr.get('appcenter/apps/%s/container' %
                                         self.app_name)

        self.installed = True

    def file(self, fname):
        if fname.startswith('/'):
            fname = fname[1:]
        dirname = subprocess.check_output([
            'docker', 'inspect', '--format={{.GraphDriver.Data.MergedDir}}',
            self.container_id
        ]).strip()
        return os.path.join(dirname, fname)

    def configure(self, args):
        set_vars = []
        unset_vars = []
        for key, value in args.iteritems():
            if value is None:
                unset_vars.append(key)
            else:
                set_vars.append('%s=%s' % (key, value))
        cmd = [
            'univention-app', 'configure',
            '%s=%s' % (self.app_name, self.app_version)
        ]
        if set_vars:
            cmd.extend(['--set'] + set_vars)
        if unset_vars:
            cmd.extend(['--unset'] + unset_vars)
        ret = subprocess.call(cmd)
        if ret != 0:
            raise UCSTest_DockerApp_ConfigureFailed()

    def install_via_umc(self):
        def _thread(event, options):
            try:
                client.umc_command("appcenter/keep_alive")
            finally:
                event.set()

        print 'App.umc_install()'
        client = umc.Client.get_test_connection()
        client.umc_get('session-info')

        options = dict(function='install',
                       application=self.app_name,
                       app=self.app_name,
                       force=True)
        resp = client.umc_command('appcenter/docker/invoke', options).result
        progress_id = resp.get('id')
        if not resp:
            raise UCTTest_DockerApp_UMCInstallFailed(resp, None)
        errors = list()
        finished = False
        progress = None
        event = threading.Event()
        threading.Thread(target=_thread, args=(event, options)).start()
        while not (event.wait(3) and finished):
            options = dict(progress_id=progress_id)
            progress = client.umc_command('appcenter/docker/progress',
                                          options,
                                          print_request_data=False,
                                          print_response=False).result
            progress.get('info', None)
            for i in progress.get('intermediate', []):
                if i['level'] in ['ERROR', 'CRITICAL']:
                    errors.append(i)
            finished = progress.get('finished', False)
        if not progress['result'].get('success',
                                      False) or not progress['result'].get(
                                          'can_continue', False):
            raise UCTTest_DockerApp_UMCInstallFailed(progress, errors)
        self.ucr.load()
        self.container_id = self.ucr.get('appcenter/apps/%s/container' %
                                         self.app_name)
        self.installed = True
        if errors:
            raise UCTTest_DockerApp_UMCInstallFailed(None, errors)

    def install_via_add_app(self):
        raise RuntimeError('"univention-add-app" is NOT supported!')
        self._update()
        # ret = subprocess.call('univention-app install --noninteractive --do-not-revert --username=%s --pwdfile=%s %s' %
        cmd = 'univention-add-app -a -l %s' % self.app_name
        print cmd
        ret = subprocess.call(cmd, shell=True)
        if ret != 0:
            raise UCSTest_DockerApp_InstallationFailed()

        self.ucr.load()
        self.installed = True

    def _update(self):
        ret = subprocess.call(['univention-app', 'update'])
        if ret != 0:
            raise UCSTest_DockerApp_UpdateFailed()

    def register(self):
        print 'App.register()'
        cmd = ['univention-app', 'register', '--app']
        print cmd
        ret = subprocess.call(' '.join(cmd), shell=True)
        if ret != 0:
            raise UCSTest_DockerApp_RegisterFailed()

    def upgrade(self):
        print 'App.upgrade()'
        self._update()
        cmd = ['univention-app', 'upgrade']
        if self.call_join_scripts is False:
            cmd.append('--do-not-call-join-scripts')
        cmd.append('--noninteractive')
        cmd.append('--username=%s' % self.admin_user)
        cmd.append('--pwdfile=%s' % self.admin_pwdfile)
        cmd.append('%s=%s' % (self.app_name, self.app_version))
        print cmd
        ret = subprocess.call(' '.join(cmd), shell=True)
        if ret != 0:
            raise UCSTest_DockerApp_UpgradeFailed()
        self.ucr.load()
        self.container_id = self.ucr.get('appcenter/apps/%s/container' %
                                         self.app_name)
        self.installed = True

    def verify(self, joined=True):
        print 'App.verify(%r)' % (joined, )
        ret = subprocess.call('univention-app status %s=%s' %
                              (self.app_name, self.app_version),
                              shell=True)
        if ret != 0:
            raise UCSTest_DockerApp_VerifyFailed()

        if joined:
            ret = subprocess.call(
                'docker exec %s univention-check-join-status' %
                self.container_id,
                stderr=subprocess.STDOUT,
                shell=True)
            if ret != 0:
                raise UCSTest_DockerApp_VerifyFailed()

        if self.package:
            try:
                output = subprocess.check_output(
                    'univention-app shell %s=%s dpkg-query -W %s' %
                    (self.app_name, self.app_version, self.package_name),
                    shell=True)
                expected_output1 = '%s\t%s\r\n' % (self.package_name,
                                                   self.package_version)
                expected_output2 = '%s\t%s\n' % (self.package_name,
                                                 self.package_version)
                if output not in [expected_output1, expected_output2]:
                    raise UCSTest_DockerApp_VerifyFailed(
                        '%r != %r' % (output, expected_output2))
            except subprocess.CalledProcessError:
                raise UCSTest_DockerApp_VerifyFailed(
                    'univention-app shell failed')

    def uninstall(self):
        print 'App.uninstall()'
        if self.installed:
            cmd = ['univention-app', 'remove']
            if self.call_join_scripts is False:
                cmd.append('--do-not-call-join-scripts')
            cmd.append('--noninteractive')
            cmd.append('--username=%s' % self.admin_user)
            cmd.append('--pwdfile=%s' % self.admin_pwdfile)
            cmd.append('%s=%s' % (self.app_name, self.app_version))
            print cmd
            ret = subprocess.call(' '.join(cmd), shell=True)
            if ret != 0:
                raise UCSTest_DockerApp_RemoveFailed()

    def execute_command_in_container(self, cmd):
        print 'Execute: %s' % cmd
        return subprocess.check_output('docker exec %s %s' %
                                       (self.container_id, cmd),
                                       stderr=subprocess.STDOUT,
                                       shell=True)

    def remove(self):
        print 'App.remove()'
        if self.package:
            self.package.remove()

    def _dump_ini(self):
        if not os.path.exists('/var/www/meta-inf/%s' % self.ucs_version):
            os.makedirs('/var/www/meta-inf/%s' % self.ucs_version)

        if self.ucs_version == '4.2':
            if not os.path.exists('/var/www/meta-inf/4.1'):
                os.makedirs('/var/www/meta-inf/4.1')

        target = os.path.join('/var/www/meta-inf/%s' % self.ucs_version,
                              '%s.ini' % self.app_directory)
        f = open(target, 'w')
        print 'Write ini file: %s' % target
        f.write('[Application]\n')
        print '[Application]'
        for key in self.ini.keys():
            f.write('%s: %s\n' % (key, self.ini[key]))
            print '%s: %s' % (key, self.ini[key])
        print
        f.close()
        svg = os.path.join('/var/www/meta-inf/%s' % self.ucs_version,
                           self.ini.get('Logo'))
        f = open(svg, 'w')
        f.write(get_dummy_svg())
        f.close()

    def _dump_scripts(self):
        for script in self.scripts.keys():
            comp_path = os.path.join(
                '/var/www/univention-repository/%s/maintained/component' %
                self.ucs_version, '%s' % self.app_directory)
            if not os.path.exists(comp_path):
                os.makedirs(comp_path)
            target = os.path.join(comp_path, script)

            print 'Create %s' % target
            print self.scripts[script]

            f = open(target, 'w')
            f.write(self.scripts[script])
            f.close()

    def _copy_package(self):
        target = os.path.join(
            '/var/www/univention-repository/%s/maintained/component' %
            self.ucs_version, '%s/all' % self.app_directory)
        os.makedirs(target)
        shutil.copy(self.package.get_binary_name(), target)
        subprocess.call('''
			cd /var/www/univention-repository/%(version)s/maintained/component;
			apt-ftparchive packages %(app)s/all >%(app)s/all/Packages;
			gzip -c %(app)s/all/Packages >%(app)s/all/Packages.gz
		''' % {
            'version': self.ucs_version,
            'app': self.app_directory
        },
                        shell=True)

    def create_basic_modproxy_settings(self):
        self.add_script(setup='''#!/bin/bash
set -x -e
eval "$(ucr shell)"
if [ "$version_version" = 4.0 ]; then
	ucr set repository/online/server="$(echo $repository_online_server | sed -e 's|.*//\(.*\)|\\1|')"
fi
univention-install --yes univention-apache
mkdir /var/www/%(app_name)s
echo "TEST-%(app_name)s" >>/var/www/%(app_name)s/index.txt
/usr/share/univention-docker-container-mode/setup "$@"
''' % {'app_name': self.app_name})

    def configure_tinyapp_modproxy(self):
        fqdn = '%s.%s' % (self.ucr['hostname'], self.ucr['domainname'])
        self.execute_command_in_container('apk add apache2-ssl')
        self.execute_command_in_container(
            "sed -i 's#/var/www/localhost/htdocs#/web/html#g' /etc/apache2/conf.d/ssl.conf"
        )
        self.execute_command_in_container(
            "sed -i 's#/var/www/localhost/cgi-bin#/web/cgi-bin#g' /etc/apache2/conf.d/ssl.conf"
        )
        self.execute_command_in_container(
            "sed -i 's#www.example.com#%s#g' /etc/apache2/conf.d/ssl.conf" %
            fqdn)
        self.execute_command_in_container(
            'cp /etc/apache2/conf.d/ssl.conf /web/config/conf.d')
        self.execute_command_in_container('sv restart apache2')
        self.execute_command_in_container(
            'cat  /etc/ssl/apache2/server.pem > /root/server.pem')
        self.execute_command_in_container('mkdir /web/html/%s' % self.app_name)
        self.execute_command_in_container(
            '/bin/sh -c "echo TEST-%s > /web/html/%s/index.txt"' %
            (self.app_name, self.app_name))

    def verify_basic_modproxy_settings_tinyapp(self, http=True, https=True):
        fqdn = '%s.%s' % (self.ucr['hostname'], self.ucr['domainname'])
        test_string = 'TEST-%s\n' % self.app_name
        if http is not None:
            try:
                response = urllib2.urlopen('http://%s/%s/index.txt' %
                                           (fqdn, self.app_name))
            except urllib2.HTTPError:
                if http:
                    raise
            else:
                html = response.read()
                if http:
                    correct = html == test_string
                else:
                    correct = html != test_string
                if not correct:
                    raise UCSTest_DockerApp_ModProxyFailed(
                        'Got: %r\nTested against: %r\nTested equality: %r' %
                        (html, test_string, http))

        if https is not None:
            try:
                ctx = ssl.create_default_context()
                ctx.check_hostname = False
                ctx.verify_mode = ssl.CERT_NONE
                response = urllib2.urlopen('https://%s/%s/index.txt' %
                                           (fqdn, self.app_name),
                                           context=ctx)
            except urllib2.HTTPError:
                if https:
                    raise
            else:
                html = response.read()
                if https:
                    correct = html == test_string
                else:
                    correct = html != test_string
                if not correct:
                    raise UCSTest_DockerApp_ModProxyFailed(
                        'Got: %r\nTested against: %r\nTested equality: %r' %
                        (html, test_string, https))

    def verify_basic_modproxy_settings(self, http=True, https=True):
        fqdn = '%s.%s' % (self.ucr['hostname'], self.ucr['domainname'])
        test_string = 'TEST-%s\n' % self.app_name

        if http is not None:
            try:
                response = urllib2.urlopen('http://%s/%s/index.txt' %
                                           (fqdn, self.app_name))
            except urllib2.HTTPError:
                if http:
                    raise
            else:
                html = response.read()
                if http:
                    correct = html == test_string
                else:
                    correct = html != test_string
                if not correct:
                    raise UCSTest_DockerApp_ModProxyFailed(
                        'Got: %r\nTested against: %r\nTested equality: %r' %
                        (html, test_string, http))

        if https is not None:
            try:
                response = urllib2.urlopen(
                    'https://%s/%s/index.txt' % (fqdn, self.app_name),
                    cafile='/etc/univention/ssl/ucsCA/CAcert.pem')
            except urllib2.HTTPError:
                if https:
                    raise
            else:
                html = response.read()
                if https:
                    correct = html == test_string
                else:
                    correct = html != test_string
                if not correct:
                    raise UCSTest_DockerApp_ModProxyFailed(
                        'Got: %r\nTested against: %r\nTested equality: %r' %
                        (html, test_string, https))
Exemplo n.º 3
0
def test_ucr_register_api():
    package_name = random_string()
    package_version = random_version()
    package = DebianPackage(name=package_name, version=package_version)
    package.create_debian_file_from_buffer(
        '/etc/univention/templates/modules/%s.py' % (package_name, ),
        UCR_MODULE)
    package.create_debian_file_from_buffer(
        '/etc/univention/templates/info/%s.info' % (package_name, ),
        UCR_INFO % (package_name, package_name))
    try:
        package.build()
        package.install()

        with UCSTestConfigRegistry():
            subprocess.call(['ucr', 'set', '%s/foo=bar' % (package_name, )])

            changes = json.loads(
                subprocess.check_output(['ucr', 'register',
                                         package_name]).split(b'####')[1])
            expected = {
                '%s/.*$' % (package_name, ): [None, None],
                '%s/foo' % (package_name, ): [None, 'bar'],
            }
            assert changes == expected, changes

            changes = json.loads(
                subprocess.check_output(
                    ['ucr', 'set',
                     '%s/foo=blub' % (package_name, )]).split(b'####')[1])
            expected = {'%s/foo' % (package_name, ): ['bar', 'blub']}
            assert changes == expected, changes
    finally:
        package.uninstall()
        package.remove()