def test_0101_relative(self):
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx -p /var', {'conf-path': 'dir/nginx.conf'}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/var'))
     assert_that(conf_path, equal_to('/var/dir/nginx.conf'))
 def test_0110(self):
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx -p /var', {'prefix': '/foo'}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/var'))
     assert_that(conf_path, equal_to('/var/conf/nginx.conf'))
 def test_0011_absolute(self):
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx', {'prefix': '/var', 'conf-path': '/etc/nginx/nginx.conf'}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/var'))
     assert_that(conf_path, equal_to('/etc/nginx/nginx.conf'))
 def test_1100_absolute(self):
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx -p /var -c /etc/nginx.conf', {}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/var'))
     assert_that(conf_path, equal_to('/etc/nginx.conf'))
 def test_1001_relative(self):
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx -c dir/nginx.conf', {'conf-path': 'foo/nginx.conf'}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/usr/local/nginx'))
     assert_that(conf_path, equal_to('/usr/local/nginx/dir/nginx.conf'))
 def test_0000(self):
     # none specified
     bin_path, prefix, conf_path, version = get_prefix_and_conf_path(
         'nginx: master process nginx', {}
     )
     assert_that(bin_path, equal_to('nginx'))
     assert_that(prefix, equal_to('/usr/local/nginx'))
     assert_that(conf_path, equal_to('/usr/local/nginx/conf/nginx.conf'))
    def find_all():
        """
        Tries to find all master processes

        :return: list of dict: nginx object definitions
        """
        # get ps info
        ps_cmd = 'ps -xa -o pid,ppid,command | egrep "PID|nginx" | grep -v egrep'
        try:
            ps, _ = subp.call(ps_cmd)
        except:
            context.log.warn(ps_cmd, exc_info=True)
            return []

        # calculate total amount of nginx master processes
        # if no masters - return
        masters_amount = len(filter(lambda x: 'nginx: master process' in x, ps))
        if masters_amount == 0:
            return []

        # collect all info about processes
        masters = {}
        try:
            for line in ps:
                # parse ps response line:
                # 21355     1 nginx: master process /usr/sbin/nginx
                gwe = re.match(r'\s*(?P<pid>\d+)\s+(?P<ppid>\d+)\s+(?P<cmd>.+)\s*', line)

                # if not parsed - go to the next line
                if not gwe:
                    continue

                pid, ppid, cmd = int(gwe.group('pid')), int(gwe.group('ppid')), gwe.group('cmd')

                # match daemonized master and skip the other stuff
                if 'nginx: master process' in cmd and ppid == 1:
                    # get path to binary, prefix and conf_path
                    try:
                        bin_path, prefix, conf_path, version = get_prefix_and_conf_path(cmd)
                    except:
                        context.log.error('failed to find bin_path, prefix and conf_path for %s' % cmd)
                        context.log.debug('', exc_info=True)
                    else:
                        # calculate local id
                        local_id = hashlib.sha256('%s_%s_%s' % (bin_path, conf_path, prefix)).hexdigest()

                        if pid in masters:
                            masters[pid].update(
                                dict(
                                    version=version,
                                    bin_path=bin_path,
                                    conf_path=conf_path,
                                    prefix=prefix,
                                    pid=pid,
                                    local_id=local_id
                                )
                            )
                        else:
                            masters[pid] = dict(
                                version=version,
                                bin_path=bin_path,
                                conf_path=conf_path,
                                prefix=prefix,
                                pid=pid,
                                local_id=local_id,
                                workers=[]
                            )
                # match worker
                elif 'nginx: worker process' in cmd:
                    if ppid in masters:
                        masters[ppid]['workers'].append(pid)
                    else:
                        masters[ppid] = dict(workers=[pid])
        except:
            context.log.warn('failed to parse ps results', exc_info=True)

        # collect results
        results = []
        for pid, description in masters.iteritems():
            if 'bin_path' in description:  # filter workers from nginx with non-executable nginx -V (relative paths, etc)
                definition = {'local_id': description['local_id'], 'type': NginxContainer.type}
                results.append((definition, description))
        return results