pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.85k stars 374 forks source link

lxd.container hangs forever using @local #860

Closed zachwaite closed 2 years ago

zachwaite commented 2 years ago

Describe the bug

A clear and concise description of what the bug is. Running the lxd.container(...) operation in a @local deploy never returns control and does not succeed

To Reproduce

Steps to reproduce the behavior (include code & usage example):

# deploy.py
from pyinfra.operations import lxd                                                      

lxd.container(                                                                             
    id="test-container",                                                                
    present=True,                                                                       
    image="ubuntu:20.04",                                                               
)  
$ pyinfra @local deploy.py

Expected behavior

A clear and concise description of what you expected to happen.

I expect to have a new lxd container created on my local installation

Meta

--> Connecting to hosts... [@local] Connected [pyinfra.api.state] Activating host: @local

--> Preparing operations... Loading: deploy.py [pyinfra.api.operation] Adding operation, {'Lxd/Container'}, opOrder=(0, 3), opHash=cedda09f9ebcba03bb3a36b21a0111fc8b7c3ec0 [pyinfra.api.facts] Getting fact: lxd.LxdContainers () (ensure_hosts: None) [pyinfra.connectors.local] --> Running command on localhost: sh -c '! command -v lxc >/dev/null || lxc list --format json --fast' [@local] >>> sh -c '! command -v lxc >/dev/null || lxc list --format json --fast' [@local] [] [pyinfra.connectors.util] --> Waiting for exit status... [pyinfra.connectors.util] --> Command exit status: 0 [@local] Loaded fact lxd.LxdContainers [@local] Ready: deploy.py

--> Proposed changes: Groups: @local [@local] Operations: 1 Change: 1 No change: 0

--> Beginning operation run... --> Starting operation: Lxd/Container (id=test-container, present=True, image=ubuntu:20.04) [pyinfra.api.operations] Starting operation Lxd/Container on @local [pyinfra.connectors.local] --> Running command on localhost: sh -c 'lxc launch ubuntu:20.04 test-container' [@local] >>> sh -c 'lxc launch ubuntu:20.04 test-container'

zachwaite commented 2 years ago

I did some research on this and this appears to be a behavior of lxc. https://discuss.linuxcontainers.org/t/lxc-launch-over-ssh-need-pseudo-terminal-allocation/6238. Adding the < /dev/null in the underlying operation command https://github.com/Fizzadar/pyinfra/blob/2.x/pyinfra/operations/lxd.py#L65, might do the trick. e.g. yield "lxc launch {image} {id} < /dev/null".format(id=id, image=image)