Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Launching with lightningd: FileNotFoundError: No such file or directory: 'bin/lightningd': 'bin/lightningd' #55

Open
s-tikhomirov opened this issue May 28, 2019 · 6 comments

Comments

@s-tikhomirov
Copy link

As per readme, I put the lightningd binary (from release v0.7.0) into /bin and ran py.test -v test.py, but the tests fail with

FileNotFoundError: [Errno 2] No such file or directory: 'bin/lightningd': 'bin/lightningd'
@cdecker
Copy link
Owner

cdecker commented May 31, 2019

The path should be bin/ not /bin/ :-)

@s-tikhomirov
Copy link
Author

There was a typo in my comment, I meant the bin which is inside the lightning-integration directory. I put the lightningd binary there and get the error above. It works with the lnd binary which is in the same directory...

@cdecker
Copy link
Owner

cdecker commented Jun 7, 2019

Is there more to this error message? It'd be good to know where this is being raised.

@s-tikhomirov
Copy link
Author

Sure. I modified test.py in two ways: changed impls to [LightningNode] and commented all tests except for the first one (test_start). Then I run py.test -v test.py and get:

=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.6.7, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/sergei/Documents/vienna/lightning-integration, inifile: pytest.ini
plugins: rerunfailures-5.0, timeout-1.3.3, json-0.4.0, xdist-1.25.0, forked-1.0.2
collected 1 item                                                                                                                                                                                           

test.py::test_start[LightningNode] FAILED                                                                                                                                                            [100%]
test.py::test_start[LightningNode] ERROR                                                                                                                                                             [100%]

================================================================================================== ERRORS ==================================================================================================
______________________________________________________________________________ ERROR at teardown of test_start[LightningNode] ______________________________________________________________________________

tp = <class 'AttributeError'>, value = None, tb = None

    def reraise(tp, value, tb=None):
        try:
            if value is None:
                value = tp()
            if value.__traceback__ is not tb:
                raise value.with_traceback(tb)
>           raise value

../../../.local/lib/python3.6/site-packages/six.py:693: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../.local/lib/python3.6/site-packages/six.py:693: in reraise
    raise value
../../../.local/lib/python3.6/site-packages/six.py:693: in reraise
    raise value
fixtures.py:142: in node_factory
    node_factory.killall()
fixtures.py:50: in killall
    n.daemon.stop()
lightningd.py:53: in stop
    TailableProc.stop(self)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <lightningd.LightningD object at 0x7fa5ab727a90>

    def stop(self):
>       self.proc.terminate()
E       AttributeError: 'NoneType' object has no attribute 'terminate'

utils.py:74: AttributeError
------------------------------------------------------------------------------------------ Captured stdout setup -------------------------------------------------------------------------------------------
Running tests in /tmp/ltests-9mdqre5n
================================================================================================= FAILURES =================================================================================================
________________________________________________________________________________________ test_start[LightningNode] _________________________________________________________________________________________

bitcoind = <btcproxy.ProxiedBitcoinD object at 0x7fa5a8352048>, node_factory = <fixtures.NodeFactory object at 0x7fa5a7ae7c18>, impl = <class 'lightningd.LightningNode'>

    @pytest.mark.parametrize("impl", impls, ids=idfn)
    def test_start(bitcoind, node_factory, impl):
>       node = node_factory.get_node(implementation=impl)

test.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
fixtures.py:45: in get_node
    node.daemon.start()
lightningd.py:47: in start
    TailableProc.start(self)
utils.py:62: in start
    self.proc = subprocess.Popen(self.cmd_line, stdout=subprocess.PIPE)
/usr/lib/python3.6/subprocess.py:709: in __init__
    restore_signals, start_new_session)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <subprocess.Popen object at 0x7fa5a7af5be0>
args = ['bin/lightningd', '--bitcoin-datadir=/tmp/ltests-9mdqre5n/test_start_1/bitcoind', '--lightning-dir=/tmp/lightning-y1e..._start[LightningNode]/node-1/', '--addr=127.0.0.1:43025', '--dev-broadcast-interval=500', '--dev-bitcoind-poll=1', ...]
executable = b'bin/lightningd', preexec_fn = None, close_fds = True, pass_fds = (), cwd = None, env = None, startupinfo = None, creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11
c2pwrite = 12, errread = -1, errwrite = -1, restore_signals = True, start_new_session = False

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       restore_signals, start_new_session):
        """Execute program (POSIX version)"""
    
        if isinstance(args, (str, bytes)):
            args = [args]
        else:
            args = list(args)
    
        if shell:
            args = ["/bin/sh", "-c"] + args
            if executable:
                args[0] = executable
    
        if executable is None:
            executable = args[0]
        orig_executable = executable
    
        # For transferring possible exec failure from child to parent.
        # Data format: "exception name:hex errno:description"
        # Pickle is not used; it is complex and involves memory allocation.
        errpipe_read, errpipe_write = os.pipe()
        # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
        low_fds_to_close = []
        while errpipe_write < 3:
            low_fds_to_close.append(errpipe_write)
            errpipe_write = os.dup(errpipe_write)
        for low_fd in low_fds_to_close:
            os.close(low_fd)
        try:
            try:
                # We must avoid complex work that could involve
                # malloc or free in the child process to avoid
                # potential deadlocks, thus we do all this here.
                # and pass it to fork_exec()
    
                if env is not None:
                    env_list = []
                    for k, v in env.items():
                        k = os.fsencode(k)
                        if b'=' in k:
                            raise ValueError("illegal environment variable name")
                        env_list.append(k + b'=' + os.fsencode(v))
                else:
                    env_list = None  # Use execv instead of execve.
                executable = os.fsencode(executable)
                if os.path.dirname(executable):
                    executable_list = (executable,)
                else:
                    # This matches the behavior of os._execvpe().
                    executable_list = tuple(
                        os.path.join(os.fsencode(dir), executable)
                        for dir in os.get_exec_path(env))
                fds_to_keep = set(pass_fds)
                fds_to_keep.add(errpipe_write)
                self.pid = _posixsubprocess.fork_exec(
                        args, executable_list,
                        close_fds, tuple(sorted(map(int, fds_to_keep))),
                        cwd, env_list,
                        p2cread, p2cwrite, c2pread, c2pwrite,
                        errread, errwrite,
                        errpipe_read, errpipe_write,
                        restore_signals, start_new_session, preexec_fn)
                self._child_created = True
            finally:
                # be sure the FD is closed no matter what
                os.close(errpipe_write)
    
            # self._devnull is not always defined.
            devnull_fd = getattr(self, '_devnull', None)
            if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd:
                os.close(p2cread)
            if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd:
                os.close(c2pwrite)
            if errwrite != -1 and errread != -1 and errwrite != devnull_fd:
                os.close(errwrite)
            if devnull_fd is not None:
                os.close(devnull_fd)
            # Prevent a double close of these fds from __init__ on error.
            self._closed_child_pipe_fds = True
    
            # Wait for exec to fail or succeed; possibly raising an
            # exception (limited in size)
            errpipe_data = bytearray()
            while True:
                part = os.read(errpipe_read, 50000)
                errpipe_data += part
                if not part or len(errpipe_data) > 50000:
                    break
        finally:
            # be sure the FD is closed no matter what
            os.close(errpipe_read)
    
        if errpipe_data:
            try:
                pid, sts = os.waitpid(self.pid, 0)
                if pid == self.pid:
                    self._handle_exitstatus(sts)
                else:
                    self.returncode = sys.maxsize
            except ChildProcessError:
                pass
    
            try:
                exception_name, hex_errno, err_msg = (
                        errpipe_data.split(b':', 2))
                # The encoding here should match the encoding
                # written in by the subprocess implementations
                # like _posixsubprocess
                err_msg = err_msg.decode()
            except ValueError:
                exception_name = b'SubprocessError'
                hex_errno = b'0'
                err_msg = 'Bad exception data from child: {!r}'.format(
                              bytes(errpipe_data))
            child_exception_type = getattr(
                    builtins, exception_name.decode('ascii'),
                    SubprocessError)
            if issubclass(child_exception_type, OSError) and hex_errno:
                errno_num = int(hex_errno, 16)
                child_exec_never_called = (err_msg == "noexec")
                if child_exec_never_called:
                    err_msg = ""
                    # The error must be from chdir(cwd).
                    err_filename = cwd
                else:
                    err_filename = orig_executable
                if errno_num != 0:
                    err_msg = os.strerror(errno_num)
                    if errno_num == errno.ENOENT:
                        err_msg += ': ' + repr(err_filename)
>               raise child_exception_type(errno_num, err_msg, err_filename)
E               FileNotFoundError: [Errno 2] No such file or directory: 'bin/lightningd': 'bin/lightningd'

/usr/lib/python3.6/subprocess.py:1344: FileNotFoundError
------------------------------------------------------------------------------------------ Captured stdout setup -------------------------------------------------------------------------------------------
Running tests in /tmp/ltests-9mdqre5n
==================================================================================== 1 failed, 1 error in 2.07 seconds =====================================================================================

@s-tikhomirov
Copy link
Author

And ls bin gives me, as expected, eclair.jar lightningd lnd (I'm trying to experiment with the three implementations).

@cdecker
Copy link
Owner

cdecker commented Jun 22, 2019

lightningd is just one of the executables that should be in the bin/ directory.

Mine looks like this:

$ tree bin/
bin
├── eclair.jar
├── lightning_channeld
├── lightning_closingd
├── lightning_connectd
├── lightningd
├── lightning_gossipd
├── lightning_hsmd
├── lightning_onchaind
├── lightning_openingd
├── lncli
└── lnd

0 directories, 11 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants