def xdg_data_home(request):
    """A fixure that creates a temporary $XDG_DATA_HOME directory."""
    d = tempfile.mkdtemp()
    with ENV.swap(XDG_DATA_HOME=d):
        with environ.context():
            yield d
    shutil.rmtree(d)
Exemple #2
0
def distinct_status_dirs(d):
    d = expand_and_make_dir(d)
    t = 'FIXIE_{0}_JOBS_DIR'
    for x, y in itertools.combinations(QUEUE_STATUSES, 2):
        xd = ENV.get(t.format(x.upper()), None)
        yd = ENV.get(t.format(y.upper()), None)
        if xd is not None and yd is not None and xd == yd:
            msg = '${0} and ${1} must have distinct values, got {2!r}'
            raise ValueError(msg.format(x, y, xd))
        elif xd is not None and xd == d:
            msg = '${0} and new value must be distinct, got {1!r}'
            raise ValueError(msg.format(x, d))
        elif yd is not None and yd == d:
            msg = '${0} and new value must be distinct, got {1!r}'
            raise ValueError(msg.format(y, d))
    return d
Exemple #3
0
def verify_user(user, token, url=None):
    """verifies a user/token pair. This happens either locally (if creds is available)
    or remotely (if $FIXIE_CREDS_URL was provided).
    """
    url = ENV.get('FIXIE_CREDS_URL', '') if url is None else url
    if url:
        return verify_user(user, token, url)
    else:
        return verify_user_local(user, token)
Exemple #4
0
def test_detached_call():
    with ENV.swap(FIXIE_DETACHED_CALL='test'), tempfile.NamedTemporaryFile(
            'w+t') as f:
        child_pid = detached_call(['env'], stdout=f)
        status = waitpid(child_pid, timeout=10.0)
        f.seek(0)
        s = f.read()
    assert status
    assert os.getpid() != child_pid
    assert 'FIXIE_DETACHED_CALL=test' in s
def xdg(request):
    """A fixure that creates a temporary XDG base directory and sets
    $XDG_DATA_HOME={xdg-base}/share and $XDG_CONFIG_HOME={xdg-base}/config.
    """
    d = tempfile.mkdtemp()
    data = os.path.join(d, 'share')
    conf = os.path.join(d, 'config')
    with ENV.swap(XDG_DATA_HOME=data, XDG_CONFIG_HOME=conf):
        with environ.context():
            yield d
    shutil.rmtree(d)
Exemple #6
0
def detached_call(args,
                  stdout=None,
                  stderr=None,
                  stdin=None,
                  env=None,
                  **kwargs):
    """Runs a process and detaches it from its parent (i.e. the current process).
    In the parent process, this will return the PID of the child. By default,
    this will return redirect all streams to os.devnull. Additionally, if an
    environment is not provided, the current fixie environment is passed in.
    If close_fds is provided, it must be True.
    All other kwargs are passed through to Popen.

    Inspired by detach.call(), Copyright (c) 2014 Ryan Bourgeois.
    """
    env = ENV.detype() if env is None else env
    stdin = os.open(os.devnull, os.O_RDONLY) if stdin is None else stdin
    stdout = os.open(os.devnull, os.O_WRONLY) if stdout is None else stdout
    stderr = os.open(os.devnull, os.O_WRONLY) if stderr is None else stderr
    if not kwargs.get('close_fds', True):
        raise RuntimeError('close_fds must be True.')
    shared_pid = multiprocessing.Value('i', 0)
    pid = os.fork()
    if pid == 0:
        # in child
        os.setsid()
        proc = subprocess.Popen(args,
                                stdout=stdout,
                                stderr=stderr,
                                stdin=stdin,
                                close_fds=True,
                                env=env)
        shared_pid.value = proc.pid
        os._exit(0)
    else:
        # in parent
        os.waitpid(pid, 0)
        child_pid = shared_pid.value
        del shared_pid
        return child_pid
Exemple #7
0
def fixie_job_status_dir(status):
    """Ensures and returns the $FIXIE_{STATUS}_JOBS_DIR"""
    fsjd = os.path.join(ENV.get('FIXIE_JOBS_DIR'), status)
    os.makedirs(fsjd, exist_ok=True)
    return fsjd