Beispiel #1
0
def listservers():

    OUT.notice('\n'.join(['apache',
                          'lighttpd',
                          'cherokee',
                          'nginx',
                          'gatling']))
Beispiel #2
0
    def read(self,
             config_owned  = 'config-files',
             server_owned  = 'server-owned-files',
             virtual_files = 'virtual',
             default_dirs  = 'default-owned'):
        '''
        Initialize the type cache.
        '''
        import WebappConfig.filetype

        server_files = []
        config_files = []

        if os.access(self.appdir() + '/' + config_owned, os.R_OK):
            flist = open(self.appdir() + '/' + config_owned)
            config_files = flist.readlines()

            OUT.debug('Identified config-protected files.', 7)

            flist.close()

        if os.access(self.appdir() + '/' + server_owned, os.R_OK):
            flist = open(self.appdir() + '/' + server_owned)
            server_files = flist.readlines()

            OUT.debug('Identified server-owned files.', 7)

            flist.close()

        self.__types = WebappConfig.filetype.FileType(config_files,
                                                      server_files,
                                                      virtual_files,
                                                      default_dirs)
Beispiel #3
0
    def filetype(self, filename, parent_type = ''):
        ''' Determine filetype for the given file.'''
        if self.__types:

            OUT.debug('Returning file type', 7)

            return self.__types.filetype(filename, parent_type)
Beispiel #4
0
def get_root(config):
    '''Returns the $ROOT variable'''
    if config.config.get('USER', 'package_manager') == "portage":
        try:
            import portage
        except ImportError as e:
            OUT.die("Portage libraries not found, quitting:\n%s" % e)

        return portage.settings['ROOT']

    elif config.config.get('USER', 'package_manager') == "paludis":
        cat = config.maybe_get('cat')
        pn  = config.maybe_get('pn')

        if cat and pn:
            cmd="cave print-id-environment-variable -b --format '%%v\n' --variable-name ROOT %s/%s" % (cat,pn)

            fi, fo, fe = os.popen3(cmd)
            fi.close()
            result_lines = fo.readlines()
            fo.close()
            fe.close()

            if result_lines[0].strip():
                return result_lines[0].strip()
            else:
                return '/'
        else:
            return '/'
    else:
        OUT.die("Unknown package manager: " + pm)
Beispiel #5
0
    def dirtype(self, directory, parent_type = ''):
        ''' Determine filetype for the given directory.'''
        if self.__types:

            OUT.debug('Returning directory type', 7)

            return self.__types.dirtype(directory, parent_type)
Beispiel #6
0
    def packageavail(self):
        '''
        Check to see whether the given package has been installed or not.

        These checks are carried out by using wrapper.py to facilitate
        distribution independant handling of the task.

        Outputs:
            0       - on success
            1       - package not found
            2       - no package to find
            3       - package isn't webapp-config compatible          '
        '''

        OUT.debug('Verifying package ' + self.package_name(), 6)

        # package_installed() does not handle "/PN" correctly
        package = self.pn

        if self.category:
            package = self.category + '/' + self.pn

            # not using self.package_name() here as we don't need pvr
            return 1

        # unfortunately, just because a package has been installed, it
        # doesn't mean that the package itself is webapp-compatible
        #
        # we need to check that the package has an entry in the
        # application repository

        if not self.appdb():
            return 3
        else:
            return 0
Beispiel #7
0
    def filetype(self, filename):
        ''' Determine filetype for the given file.'''
        if self.__types:

            OUT.debug('Returning file type', 7)

            return self.__types.filetype(filename)
Beispiel #8
0
    def dirisconfigprotected(self, installdir):
        '''
        Traverses the path of parent directories for the
        given install dir and checks if any matches the list
        of config protected files.

        >>> a = Protection('','horde','3.0.5','portage')

        Add a virtual config protected directory:

        >>> a.config_protect += ' /my/strange/htdocs/'
        >>> a.dirisconfigprotected('/my/strange/htdocs/where/i/installed/x')
        True
        >>> a.dirisconfigprotected('/my/strange/htdocs/where/i/installed/x/')
        True
        >>> a.config_protect += ' /my/strange/htdocs'
        >>> a.dirisconfigprotected('/my/strange/htdocs/where/i/installed/x')
        True
        >>> a.dirisconfigprotected('/my/strange/htdocs/where/i/installed/x/')
        True

        >>> a.config_protect += ' bad_user /my/strange/htdocs'
        >>> a.dirisconfigprotected('/my/bad_user/htdocs/where/i/installed/x')
        False
        >>> a.dirisconfigprotected('/my/strange/htdocs/where/i/installed/x/')
        True

        >>> a.dirisconfigprotected('/')
        False
        '''

        my_master = []
        for i in self.config_protect.split(' '):
            if i[0] == '/':
                if i[-1] == '/':
                    my_master.append(i[:-1])
                else:
                    my_master.append(i)

        if installdir[0] != '/':
            OUT.die('BUG! Don\'t call this with a relative path.')

        if installdir[-1] == '/':
            my_dir = installdir[:-1]
        else:
            my_dir = installdir

        while my_dir:

            if my_dir == '.' or my_dir == '/':
                return False

            for x in my_master:
                if my_dir == x:
                    return True

            my_dir = os.path.dirname(my_dir)

        # nope, the directory isn't config-protected at this time
        return False
Beispiel #9
0
    def how_to_update(self, dirs):
        '''
        Instruct the user how to update the application.
        '''
        my_command = self.update_command

        directories = []

        for i in dirs:
            present = False
            if directories:
                for j in directories:
                    if (i == j[:len(i)] or j == i[:len(j)]):
                        present = True
                        break
            if not present:
                directories.append(i)

        my_command_list = ''

        for i in directories:
            if not self.dirisconfigprotected(i):
                my_command_list += 'CONFIG_PROTECT="' + i + '" ' + my_command + '\n'

        if not my_command_list:
            my_command_list = my_command

        OUT.warn(
            'One or more files have been config protected\nTo comple'
            'te your install, you need to run the following command(s):\n\n' +
            my_command_list)
Beispiel #10
0
    def read(self,
             config_owned='config-files',
             server_owned='server-owned-files',
             virtual_files='virtual',
             default_dirs='default-owned'):
        '''
        Initialize the type cache.
        '''
        import WebappConfig.filetype

        server_files = []
        config_files = []

        if os.access(self.appdir() + '/' + config_owned, os.R_OK):
            flist = open(self.appdir() + '/' + config_owned)
            config_files = flist.readlines()

            OUT.debug('Identified config-protected files.', 7)

            flist.close()

        if os.access(self.appdir() + '/' + server_owned, os.R_OK):
            flist = open(self.appdir() + '/' + server_owned)
            server_files = flist.readlines()

            OUT.debug('Identified server-owned files.', 7)

            flist.close()

        self.__types = WebappConfig.filetype.FileType(config_files,
                                                      server_files,
                                                      virtual_files,
                                                      default_dirs)
Beispiel #11
0
    def read(self):
        ''' Read the contents of the dot config file.'''
        dotconfig = self.__dot_config()

        OUT.debug('Checking for dotconfig ', 6)

        if not self.has_dotconfig():
            raise Exception('Cannot read file ' + dotconfig)

        tokens = shlex.shlex(open(dotconfig))

        while True:
            a = tokens.get_token()
            b = tokens.get_token()
            c = tokens.get_token()

            OUT.debug('Reading token', 8)

            if (a in self.__tokens and
                b == '=' and c):

                if c[0] == '"':
                    c = c[1:]

                if c[-1] == '"':
                    c = c[:-1]

                self.__data[a] = c

            else:
                break
Beispiel #12
0
    def how_to_update(self, dirs):
        '''
        Instruct the user how to update the application.
        '''
        my_command = self.update_command

        directories = []

        for i in dirs:
            present = False
            if directories:
                for j in directories:
                    if (i == j[:len(i)] or 
                        j == i[:len(j)]):
                        present = True
                        break
            if not present:
                directories.append(i)

        my_command_list = ''

        for i in directories:
            if not self.dirisconfigprotected(i):
                my_command_list += 'CONFIG_PROTECT="' + i + '" ' + my_command + '\n'

        if not my_command_list:
            my_command_list = my_command

        OUT.warn('One or more files have been config protected\nTo comple'
                 'te your install, you need to run the following command(s):\n\n'
                 + my_command_list)
Beispiel #13
0
    def test_add_rm(self):
        OUT.color_off()
        db = WebappDB(root='/'.join((HERE, 'testfiles', 'webapps')),
                      pretend=True,
                      package='horde',
                      version='3.0.5')
        # Test adding:
        db.add('/'.join(('/screwy', 'wonky', 'foobar', 'horde', 'hierarchy')),
               user='******',
               group='me')
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[0], '* Pretended to append installation '\
                                    '/screwy/wonky/foobar/horde/hierarchy')

        # Test deleting a webapp that is actually in the database:
        db.remove('/'.join(('/var', 'www', 'localhost', 'htdocs', 'horde')))
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[6], '* ')

        # And now test deleting one that isn't:
        db.remove('/'.join(
            ('/screwy', 'wonky', 'foobar', 'horde', 'hierarchy')))
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[11], '* 1124612110 root root '\
                                     '/var/www/localhost/htdocs/horde')
Beispiel #14
0
    def packageavail(self):
        '''
        Check to see whether the given package has been installed or not.

        These checks are carried out by using wrapper.py to facilitate
        distribution independant handling of the task.

        Outputs:
            0       - on success
            1       - package not found
            2       - no package to find
            3       - package isn't webapp-config compatible          '
        '''

        OUT.debug('Verifying package ' + self.package_name(), 6)

        # package_installed() does not handle "/PN" correctly
        package = self.pn

        if self.category:
            package = self.category + '/' + self.pn

        # not using self.package_name() here as we don't need pvr
            return 1

        # unfortunately, just because a package has been installed, it
        # doesn't mean that the package itself is webapp-compatible
        #
        # we need to check that the package has an entry in the
        # application repository

        if not self.appdb():
            return 3
        else:
            return 0
Beispiel #15
0
    def dirtype(self, directory):
        ''' Determine filetype for the given directory.'''
        if self.__types:

            OUT.debug('Returning directory type', 7)

            return self.__types.dirtype(directory)
Beispiel #16
0
    def remove(self, entry):
        '''
        Decide whether to delete something - and then go ahead and do so

        Just like portage, we only remove files that have not changed
        from when we installed them.  If the timestamp or checksum is
        different, we leave the file in place.

        Inputs

          entry    - file/dir/sym to remove
        '''

        OUT.debug('Trying to remove file', 6)

        # okay, deal with the file | directory | symlink

        removeable = self.__content.get_canremove(entry)

        if not removeable:

            # Remove directory or file.

            # Report if we are only pretending
            if self.__p:
                OUT.info('    pretending to remove: ' + entry)

            # try to remove the entry
            try:
                entry_type = self.__content.etype(entry)
                if self.__content.etype(entry) == 'dir':
                    # its a directory -> rmdir
                    if not self.__p:
                        os.rmdir(entry)
                else:
                    # its a file -> unlink
                    if not self.__p:
                        os.unlink(entry)
            except:
                # Report if there is a problem
                OUT.notice('!!!      '
                           + self.__content.epath(entry))
                return

            if self.__v and not self.__p:
                # Report successful deletion

                OUT.notice('<<< ' + entry_type + ' '
                           * (5 - len(entry_type))
                           + self.__content.epath(entry))

            self.__content.delete(entry)

            return True

        else:

            OUT.notice(removeable)

            return False
Beispiel #17
0
    def show_postinst(self, server = None):
        '''
        Display any post-installation instructions, if there are any.
        '''

        OUT.debug('Running show_postinst', 6)

        self.show_post(filename = 'postinst-en.txt', ptype = 'install', server = server)
Beispiel #18
0
    def test_read_corrupt(self):
        contents = Contents('/'.join((HERE, 'testfiles', 'contents')),
                            package = 'test', version = '1.1')

        OUT.color_off()
        contents.read()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[12], '* Not enough entries.')
Beispiel #19
0
    def show_postupgrade(self, server = None):
        '''
        Display any post-upgrade instructions, if there are any.
        '''

        OUT.debug('Running show_postupgrade', 6)

        self.show_post(filename = 'postupgrade-en.txt', ptype = 'upgrade', server = server)
Beispiel #20
0
    def __init__(self, directories, permissions, handler, flags, pm):

        if self.dep and not self.supported(pm):
            print(self.dep)
            OUT.die('Your configuration file sets the server type "' +
                    self.name +
                    '"\nbut the corresponding package does not seem to be '
                    'installed!\nPlease "emerge ' + self.dep + '" or correct '
                    'your settings.')

        try:
            self.set_server_user()
        except KeyError:
            OUT.die('The user for the server type "' + self.name +
                    '" does not exist!')

        self.__sourced = directories['source']
        self.__destd = directories['destination']
        self.__hostroot = directories['hostroot']
        self.__vhostroot = directories['vhostroot']

        # + server owned
        if permissions['file']['server-owned'][0] == 0:
            permissions['file']['server-owned'][0] = self.vhost_server_uid
            permissions['dir']['server-owned'][0] = self.vhost_server_uid
        if permissions['file']['server-owned'][1] == 0:
            permissions['file']['server-owned'][1] = self.vhost_server_gid
            permissions['dir']['server-owned'][1] = self.vhost_server_gid
            # and config owned directories have server gid
            permissions['dir']['config-owned'][1] = self.vhost_server_gid
            # allows server and config owned
            permissions['file']['config-server-owned'][
                1] = self.vhost_server_gid
            permissions['dir']['config-server-owned'][
                1] = self.vhost_server_gid

        self.__perm = permissions
        self.__handler = handler
        self.__flags = flags

        self.__ws = handler['source']
        self.__content = handler['content']
        self.__protect = handler['protect']
        self.__dotconfig = handler['dotconfig']
        self.__ebuild = handler['ebuild']
        self.__db = handler['db']

        self.__v = flags['verbose']
        self.__p = flags['pretend']

        wd = WebappRemove(self.__content, self.__v, self.__p)

        handler['removal'] = wd

        self.__del = wd

        # Set by the install function
        self.__add = None
Beispiel #21
0
    def remove(self, entry):
        '''
        Decide whether to delete something - and then go ahead and do so

        Just like portage, we only remove files that have not changed
        from when we installed them.  If the timestamp or checksum is
        different, we leave the file in place.

        Inputs

          entry    - file/dir/sym to remove
        '''

        OUT.debug('Trying to remove file', 6)

        # okay, deal with the file | directory | symlink

        removeable = self.__content.get_canremove(entry)

        if not removeable:

            # Remove directory or file.

            # Report if we are only pretending
            if self.__p:
                OUT.info('    pretending to remove: ' + entry)

            # try to remove the entry
            try:
                entry_type = self.__content.etype(entry)
                if self.__content.etype(entry) == 'dir':
                    # its a directory -> rmdir
                    if not self.__p:
                        os.rmdir(entry)
                else:
                    # its a file -> unlink
                    if not self.__p:
                        os.unlink(entry)
            except:
                # Report if there is a problem
                OUT.notice('!!!      ' + self.__content.epath(entry))
                return

            if self.__v and not self.__p:
                # Report successful deletion

                OUT.notice('<<< ' + entry_type + ' ' * (5 - len(entry_type)) +
                           self.__content.epath(entry))

            self.__content.delete(entry)

            return True

        else:

            OUT.notice(removeable)

            return False
Beispiel #22
0
    def test_add(self):
        loc = '/'.join((HERE, 'testfiles', 'contents', 'app'))
        contents = Contents(loc, package='test', version='1.0')
        OUT.color_off()
        contents.add('file',
                     'config_owned',
                     destination=loc,
                     path='/test1',
                     real_path=loc + '/test1',
                     relative=True)

        # Now trigger an error by adding a file that doesn't exist!
        contents.add('file',
                     'config_owned',
                     destination=loc,
                     path='/test0',
                     real_path=loc + '/test0',
                     relative=True)

        output = sys.stdout.getvalue().strip('\n')

        self.assertTrue('WebappConfig/tests/testfiles/contents/app/test0 to '\
                        'add it as installation content. This should not '\
                        'happen!' in output)

        # Test adding hardlinks:
        contents.add('hardlink',
                     'config_owned',
                     destination=loc,
                     path='/test2',
                     real_path=loc + '/test2',
                     relative=True)
        self.assertTrue(
            'file 1 config_owned "test2" ' in contents.entry(loc + '/test2'))
        # Test adding dirs:
        contents.add('dir',
                     'default_owned',
                     destination=loc,
                     path='/dir1',
                     real_path=loc + '/dir1',
                     relative=True)
        self.assertTrue(
            'dir 1 default_owned "dir1" ' in contents.entry(loc + '/dir1'))

        # Test adding symlinks:
        contents.add('sym',
                     'virtual',
                     destination=loc,
                     path='/test3',
                     real_path=loc + '/test3',
                     relative=True)
        self.assertTrue('sym 1 virtual "test3" ' in contents.entry(loc +
                                                                   '/test3'))

        # Printing out the db after adding these entries:
        contents.db_print()
        output = sys.stdout.getvalue().split('\n')
        self.assertTrue('file 1 config_owned "test1" ' in output[1])
Beispiel #23
0
def listservers():

    OUT.notice('\n'.join(['apache',
                          'lighttpd',
                          'cherokee',
                          'nginx',
                          'gatling',
                          'hiawatha',
                          'tracd',]))
Beispiel #24
0
    def test_read_corrupt(self):
        contents = Contents('/'.join((HERE, 'testfiles', 'contents')),
                            package='test',
                            version='1.1')

        OUT.color_off()
        contents.read()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[12], '* Not enough entries.')
Beispiel #25
0
 def db_print(self):
     ''' Print all enties of the contents file.'''
     entries = self.get_sorted_files()
     values = []
     for i in entries:
         # Fix relative entry
         s = self.__content[i]
         s[1] = str(int(s[1]))
         values.append(' '.join(s))
     OUT.notice('\n'.join(values))
Beispiel #26
0
    def show_postupgrade(self, server=None):
        '''
        Display any post-upgrade instructions, if there are any.
        '''

        OUT.debug('Running show_postupgrade', 6)

        self.show_post(filename='postupgrade-en.txt',
                       ptype='upgrade',
                       server=server)
Beispiel #27
0
    def show_postinst(self, server=None):
        '''
        Display any post-installation instructions, if there are any.
        '''

        OUT.debug('Running show_postinst', 6)

        self.show_post(filename='postinst-en.txt',
                       ptype='install',
                       server=server)
def listservers():

    OUT.notice('\n'.join([
        'apache',
        'lighttpd',
        'cherokee',
        'nginx',
        'gatling',
        'tracd',
    ]))
Beispiel #29
0
 def db_print(self):
     ''' Print all enties of the contents file.'''
     entries = self.get_sorted_files()
     values = []
     for i in entries:
         # Fix relative entry
         s = self.__content[i]
         s[1] = str(int(s[1]))
         values.append(' '.join(s))
     OUT.notice('\n'.join(values))
Beispiel #30
0
    def test_add_pretend(self):
        loc = '/'.join((HERE, 'testfiles', 'contents', 'app'))
        contents = Contents(loc, package = 'test', version = '1.0',
                            pretend = True)
        OUT.color_off()
        contents.add('file', 'config_owned', destination = loc, path = '/test1',
                     real_path = loc + '/test1', relative = True)

        output = sys.stdout.getvalue().strip('\n')
        self.assertEqual(output,
                       '*     pretending to add: file 1 config_owned "test1"')
Beispiel #31
0
    def remove_files(self):
        '''
        It is time to remove the files that we installed originally.
        '''

        OUT.debug('Trying to remove files', 6)

        success = [self.remove(i) for i in self.__content.get_files()]

        # Tell the caller if anything was left behind

        return all(success)
Beispiel #32
0
    def remove_files(self):
        '''
        It is time to remove the files that we installed originally.
        '''

        OUT.debug('Trying to remove files', 6)

        success = [self.remove(i) for i in self.__content.get_files()]

        # Tell the caller if anything was left behind

        return all(success)
Beispiel #33
0
    def test_remove_files(self):
        OUT.color_off()
        contents = Contents('/'.join((HERE, 'testfiles', 'contents', 'app2')),
                            package = 'test', version = '1.0', pretend = True)
        contents.read()
        webrm = WebappRemove(contents, True, True)
        webrm.remove_files()

        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[3], '*     pretending to remove: ' +
                         '/'.join((HERE, 'testfiles', 'contents', 'app2',
                                   'test3')))
Beispiel #34
0
    def packagename(self):
        ''' Retrieve the package name from the values specified in the dot
        config file'''

        OUT.debug('Trying to retrieve package name', 6)

        if 'WEB_PN' in list(self.__data.keys()) and 'WEB_PVR' in list(self.__data.keys()):
            if 'WEB_CATEGORY' in list(self.__data.keys()):
                return self.__data['WEB_CATEGORY'] + '/' + \
                    self.__data['WEB_PN'] + '-' + self.__data['WEB_PVR']
            else:
                return self.__data['WEB_PN'] + '-' + self.__data['WEB_PVR']
        return ''
Beispiel #35
0
def want_category(config):
    '''Check if the package manager requires category info

    Portage: optional
    Paludis: mandatory
    '''

    if config.config.get('USER', 'package_manager') == "portage":
        return
    elif config.config.get('USER', 'package_manager') == "paludis":
        if not config.config.has_option('USER', 'cat'):
            OUT.die("Package name must be in the form CAT/PN")
    else:
        OUT.die("Unknown package manager: " + pm)
Beispiel #36
0
    def test_write(self):
        contents = Contents('/'.join((HERE, 'testfiles', 'contents')),
                            package = 'test', version = '1.0', pretend = True)
        OUT.color_off()
        contents.read()

        contents.write()
        output = sys.stdout.getvalue().split('\n')

        expected = '* Would have written content file ' + '/'.join((HERE,
                                                          'testfiles',
                                                          'contents',
                                                          '.webapp-test-1.0!'))
        self.assertEqual(output[0], expected)
Beispiel #37
0
    def has_dotconfig(self):
        ''' Return True if the install location already has a dotconfig
        file.'''
        dotconfig = self.__dot_config()

        OUT.debug('Verifying path', 7)

        if not os.path.isfile(dotconfig):
            return False

        if not os.access(dotconfig, os.R_OK):
            return False

        return True
Beispiel #38
0
    def test_remove_files(self):
        OUT.color_off()
        contents = Contents('/'.join((HERE, 'testfiles', 'contents', 'app2')),
                            package='test',
                            version='1.0',
                            pretend=True)
        contents.read()
        webrm = WebappRemove(contents, True, True)
        webrm.remove_files()

        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(
            output[3], '*     pretending to remove: ' + '/'.join(
                (HERE, 'testfiles', 'contents', 'app2', 'test3')))
Beispiel #39
0
    def listunused(self, db):
        '''
        Outputs a list of what has not been installed so far
        '''

        packages = self.list_locations()

        if not packages:
            OUT.die('No packages found!')

        keys = sorted(packages)

        OUT.debug('Check for unused web applications', 7)

        for i in keys:

            db.set_category(packages[i][0])
            db.set_package(packages[i][1])
            db.set_version(packages[i][2])

            if not db.has_installs():
                if packages[i][0]:
                    OUT.notice(packages[i][0] + '/' + packages[i][1] + '-' +
                               packages[i][2])
                else:
                    OUT.notice(packages[i][1] + '-' + packages[i][2])
Beispiel #40
0
    def listunused(self, db):
        '''
        Outputs a list of what has not been installed so far
        '''

        packages = self.list_locations()

        if not packages:
            OUT.die('No packages found!')

        keys = sorted(packages)

        OUT.debug('Check for unused web applications', 7)

        for i in keys:

            db.set_category(packages[i][0])
            db.set_package (packages[i][1])
            db.set_version (packages[i][2])

            if not db.has_installs():
                if packages[i][0]:
                    OUT.notice(packages[i][0] + '/' + packages[i][1] + '-' + packages[i][2])
                else:
                    OUT.notice(packages[i][1] + '-' + packages[i][2])
Beispiel #41
0
    def test_add_pretend(self):
        loc = '/'.join((HERE, 'testfiles', 'contents', 'app'))
        contents = Contents(loc, package='test', version='1.0', pretend=True)
        OUT.color_off()
        contents.add('file',
                     'config_owned',
                     destination=loc,
                     path='/test1',
                     real_path=loc + '/test1',
                     relative=True)

        output = sys.stdout.getvalue().strip('\n')
        self.assertEqual(
            output, '*     pretending to add: file 1 config_owned "test1"')
Beispiel #42
0
    def test_list_installs(self):
        OUT.color_off()
        db = WebappDB(root = '/'.join((HERE, 'testfiles', 'webapps')))

        db.listinstalls()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[1], '/var/www/localhost/htdocs/horde')

        # Now test the verbosity:
        db = WebappDB(root = '/'.join((HERE, 'testfiles', 'webapps')),
                      verbose = True)
        db.listinstalls()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[5], '* Installs for horde-3.0.5')
Beispiel #43
0
    def packageavail(self):
        '''
        Check to see whether the given package has been installed or not.

        These checks are carried out by using wrapper.py to facilitate
        distribution independant handling of the task.

        Outputs:
            0       - on success
            1       - package not found
            2       - no package to find
            3       - package isn't webapp-config compatible          '

        >>> import os.path
        >>> here = os.path.dirname(os.path.realpath(__file__))

        Does not exist:

        >>> a = WebappSource(root = here + '/tests/testfiles/share-webapps',
        ...             category='www-apps',package='nothere', version='1',pm='portage')
        >>> a.packageavail()
        1

        Incompatible cannot be tested since that would require a
        oackage (including version number) that is installed on
        all systems.
        '''

        OUT.debug('Verifying package ' + self.package_name(), 6)

        # package_installed() does not handle "/PN" correctly
        package = self.pn

        if self.category:
            package = self.category + '/' + self.pn

        # not using self.package_name() here as we don't need pvr
        if not wrapper.package_installed(package, self.pm):
            return 1

        # unfortunately, just because a package has been installed, it
        # doesn't mean that the package itself is webapp-compatible
        #
        # we need to check that the package has an entry in the
        # application repository

        if not self.appdb():
            return 3
        else:
            return 0
Beispiel #44
0
    def test_list_installs(self):
        OUT.color_off()
        db = WebappDB(root='/'.join((HERE, 'testfiles', 'webapps')))

        db.listinstalls()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[1], '/var/www/localhost/htdocs/horde')

        # Now test the verbosity:
        db = WebappDB(root='/'.join((HERE, 'testfiles', 'webapps')),
                      verbose=True)
        db.listinstalls()
        output = sys.stdout.getvalue().split('\n')
        self.assertEqual(output[5], '* Installs for horde-3.0.5')
Beispiel #45
0
    def test_write(self):
        contents = Contents('/'.join((HERE, 'testfiles', 'contents')),
                            package='test',
                            version='1.0',
                            pretend=True)
        OUT.color_off()
        contents.read()

        contents.write()
        output = sys.stdout.getvalue().split('\n')

        expected = '* Would have written content file ' + '/'.join(
            (HERE, 'testfiles', 'contents', '.webapp-test-1.0!'))
        self.assertEqual(output[0], expected)
Beispiel #46
0
    def __init__(self,
                 config_owned,
                 server_owned,
                 server_owned_r,
                 virtual_files = 'virtual',
                 default_dirs  = 'default-owned'):
        '''
        Populates the cache with the file types as provided by the
        ebuild.
        '''

        self.__cache = {}

        # Validity of entries are checked by the command line parser
        self.__virtual_files = virtual_files
        self.__default_dirs  = default_dirs

        # populate cache
        for i in config_owned:

            OUT.debug('Adding config-owned file', 8)

            self.__cache[self.__fix(i)] = 'config-owned'

        for i in server_owned:

            if self.__fix(i) in self.__cache.keys():

                OUT.debug('Adding config-server-owned file', 8)

                self.__cache[self.__fix(i)] = 'config-server-owned'

            else:

                OUT.debug('Adding server-owned file', 8)

                self.__cache[self.__fix(i)] = 'server-owned'

        for i in server_owned_r:

            if self.__fix(i) in self.__cache.keys():

                OUT.die('{} is a the same time recursively server-owned and {}: This case is not supported.'.format(self.__fix(i), self.__cache[self.__fix(i)]))

            else :

                OUT.debug('Adding recursively server-owned file', 8)

                self.__cache[self.__fix(i).strip()] = 'server-owned-dir'
Beispiel #47
0
 def kill(self):
     ''' Remove the contents file.'''
     if not self.__p:
         try:
             dbpath = self.appdb()
             self.check_installdir()
             os.unlink(dbpath)
             self.__content = {}
             return True
         except:
             OUT.warn('Failed to remove ' + self.appdb() + '!')
             return False
     else:
         OUT.info('Would have removed ' + self.appdb())
         return True
Beispiel #48
0
 def kill(self):
     ''' Remove the contents file.'''
     if not self.__p:
         try:
             dbpath = self.appdb()
             self.check_installdir()
             os.unlink(dbpath)
             self.__content = {}
             return True
         except:
             OUT.warn('Failed to remove ' + self.appdb() + '!')
             return False
     else:
         OUT.info('Would have removed ' + self.appdb())
         return True
Beispiel #49
0
    def write(self,
              category,
              package,
              version,
              host,
              original_installdir,
              user_group):
        '''
        Output the .webapp file, that tells us in future what has been installed
        into this directory.
        '''
        self.__data['WEB_CATEGORY']      = category
        self.__data['WEB_PN']            = package
        self.__data['WEB_PVR']           = version
        self.__data['WEB_INSTALLEDBY']   = pwd.getpwuid(os.getuid())[0]
        self.__data['WEB_INSTALLEDDATE'] = strftime('%Y-%m-%d %H:%M:%S')
        self.__data['WEB_INSTALLEDFOR']  = user_group
        self.__data['WEB_HOSTNAME']      = host
        self.__data['WEB_INSTALLDIR']    = original_installdir


        info = ['# ' + self.__file,
                '#	config file for this copy of '
                + package + '-' + version,
                '#',
                '#	automatically created by Gentoo\'s webapp-config',
                '#	do NOT edit this file by hand',
                '',]
        for i in self.__tokens:
            info.append(i + '="' + self.__data[i] + '"')

        if not self.__p:
            try:

                fd = os.open(self.__dot_config(),
                             os.O_WRONLY | os.O_CREAT,
                             self.__perm(0o600))

                os.write(fd, ('\n'.join(info)).encode('utf-8'))
                os.close(fd)

            except Exception as e:

                OUT.die('Unable to write to ' + self.__dot_config()
                        + '\nError was: ' + str(e))
        else:
            OUT.info('Would have written the following information into '
                     + self.__dot_config() + ':\n' + '\n'.join(info))
Beispiel #50
0
    def dirtype(self, directory, parent_type = ''):
        '''
        Inputs:

          directory     - the directory that we need a decision about

          parent_type  - the type of the parent directory

        returns one of these:

          server-owned         - dir needs to be owned by the webserver user
          config-owned         - dir needs to be owned by the config user
          config-server-owned  - Both the previous cases at the same time
          server-owned-dir     - Directory that contains file/dirs to be owned
                                 by the webserver user
          default-owned        - we need a local copy, owned by root

        NOTE:
          Use get_filetype(filename) for files

        NOTE:
          the user can use --default-dirs on the command-line to change
          what type default directories are really reported as
        '''

        # remove any whitespace and trailing /
        directory = self.__fix(directory)

        # check the cache
        if directory in self.__cache.keys():
            # Check if parent type is recursive
            if parent_type == 'server-owned-dir':
                new_type = self.__cache[directory]
                if new_type == 'config-owned':
                    OUT.die('This version does not support config dirs')
                if new_type == server-owned:
                    OUT.warn('Configuration error: {} is marked server-owned two times'.format(filename))
                return 'server-owned-dir'
            return self.__cache[directory]

        # Check if parent type is recursive
        if parent_type == 'server-owned-dir':
            return 'server-owned-dir'
        # unspecified directories are default-owned
        return self.__default_dirs
Beispiel #51
0
    def filetype(self, filename, parent_type = ''):
        '''
        Inputs:

          filename      - the file that we need a decision about

          parent_type  - the type of the parent directory

        returns one of these:

          server-owned         - file needs to be owned by the webserver user
                                 (and needs to be a local copy)
          config-owned         - file needs to be owned by the config user
                                 (and needs to be a local copy)
          config-server-owned  - Both the previous cases at the same time
          virtual              - we do not need a local copy of the file

        NOTE:
          Use get_dirtype(directory) for directories

        NOTE:
          the user can use --virtual-files on the command-line to change
          what type virtual files are really reported as
        '''

        # remove any whitespace and trailing /
        filename = self.__fix(filename)

        # check the cache
        if filename in self.__cache.keys():
            # Check if parent type is recursive
            if parent_type == 'server-owned-dir':
                new_type = self.__cache[filename]
                if new_type == 'config-owned':
                    return 'config-server-owned'
                if new_type == 'server-owned':
                    OUT.warn('Configuration error: {} is marked server-owned twice'.format(filename))
                return 'server-owned' 
            return self.__cache[filename]

        # Check if parent type is recursive
        if parent_type == 'server-owned-dir':
            return 'server-owned'
        # unspecified file (and thus virtual)
        return self.__virtual_files
Beispiel #52
0
    def list_locations(self):
        ''' List all available db files.'''

        OUT.debug('Retrieving hierarchy locations', 6)

        dbpath = self.appdb()

        if dbpath and os.path.isfile(dbpath):
            return {dbpath: [self.category, self.pn, self.pvr]}

        if dbpath and not os.path.isfile(dbpath):
            OUT.debug(
                'Package "' + self.package_name() +
                '" not listed in the hierarchy (file "' + dbpath +
                ' is missing)!', 8)
            return {}

        locations = {}
        packages = []

        if self.pn:
            packages.append(os.path.join(self.root, self.pn))
            if self.category:
                packages.append(os.path.join(self.root, self.category,
                                             self.pn))
        else:
            packages.extend(
                os.path.join(self.root, m) for m in os.listdir(self.root))
            for i in packages:
                if os.path.isdir(i):
                    packages.extend(os.path.join(i, m) for m in os.listdir(i))

        for i in packages:

            OUT.debug('Checking package', 8)

            if os.path.isdir(i):

                OUT.debug('Checking version', 8)

                versions = os.listdir(i)

                for j in versions:
                    appdir = os.path.join(i, j)
                    location = os.path.join(appdir, self.dbfile)
                    if (os.path.isdir(appdir) and os.path.isfile(location)):
                        pn = os.path.basename(i)
                        cat = os.path.basename(os.path.split(i)[0])
                        if cat == "webapps":
                            cat = ""
                        locations[location] = [cat, pn, j]

        return locations
Beispiel #53
0
    def test_how_to_update(self):
        OUT.color_off()
        pro = Protection('', 'horde', '3.0.5', 'portage')
        strange_htdocs = '/'.join(
            ('/my', 'strange', 'htdocs', 'where', 'i', 'installed', 'x'))
        pro.how_to_update([strange_htdocs])
        output = sys.stdout.getvalue().split('\n')

        self.assertEqual(
            output[3], '* CONFIG_PROTECT="' + strange_htdocs + '" etc-update')

        # Adding a virtual config protected directory:
        i = strange_htdocs.replace('/where/i/instaled/x', '')
        pro.config_protect += ' ' + i

        pro.how_to_update([strange_htdocs])
        output = sys.stdout.getvalue().split('\n')

        self.assertEqual(output[8], '* etc-update')
Beispiel #54
0
    def mkdirs(self, directory=''):
        '''
        Create a set of directories

        Inputs

        directory   - the directory within the source hierarchy
        '''

        sd = self.__sourced + '/' + directory
        real_dir = re.compile('/+').sub(
            '/',
            self.__ws.appdir() + '/' + self.__sourced + '/' + directory)

        OUT.debug('Creating directories', 6)

        if not self.__ws.source_exists(sd):

            OUT.warn(self.__ws.package_name() +
                     ' does not install any files from ' + real_dir +
                     '; skipping')
            return

        OUT.info('    Installing from ' + real_dir)

        for i in self.__ws.get_source_directories(sd):

            OUT.debug('Handling directory', 7)

            # create directory first
            self.mkdir(directory + '/' + i)

            # then recurse into the directory
            self.mkdirs(directory + '/' + i)

        for i in self.__ws.get_source_files(sd):

            OUT.debug('Handling file', 7)

            # handle the file
            self.mkfile(directory + '/' + i)