Closed LukasHanusek closed 4 years ago
Tried to execute the same script via PHP so to confirm that it is not just Java's problem, I get exactly the same behavior, it hang indefinitely on lxc init with PHP as well:
<?php
$descriptor = [
0 => ["pipe", "r"],
1 => ["pipe", "w"]
];
$proc = proc_open("/home/nc/tmp/myscript.sh", $descriptor, $pipes);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
?>
Fixed by immediately closing outputstream after process start:
Process p = pb.start();
p.getOutputStream().close();
If using python with paramiko setting get_pty=True
will fix it
http://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.exec_command
Hi! I have the same problem on Ubuntu 20.04 (in Vagrant). The lxc process hangs forever when started from ProcessBuilder. In my case, it hangs for "lxc launch". The solution from @LukasHanusek works, but IMHO, the problem still needs to be solved. I am creating a generic tool for executing different commands, and I really don't understand why I should close the output stream, just after starting ProcessBuilder. It doesn't sound as the correct solution, but rather just a workaround.
Is it possible to reopen this ticket, or should I create a new one?
lxc init reads config from stdin, so if you are not passing config in you need to ensure stdin is closed.
I have just updated my comment: in my case, it happens also during "lxc launch". So AFAIK it doesn't read input, am I wrong?
And in fact also "lxc init" can be correctly executed without providing stdin. I think that in such a case it should not block on reading stdin anyway, and just check if the input is provided. In my case "lxc init" is not a problem - I am feeding "lxc init" with configuration. But "lxc launch" also blocks for following arguments:
lxc launch -p development ubuntu:20.04 my-server
lxc launch also reads from stdin as it is a convenience combination of lxc init and lxc start.
Closing or not providing stdin will prevent these commands from blocking.
Ok, just for the record. Here is a minimal test case:
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public final class Main {
public static void main(String[] args) throws IOException, InterruptedException {
System.out.println("Program started");
Process process = new ProcessBuilder("bash", "-c", "lxc launch -p development ubuntu:20.04 my-server")
.redirectInput(ProcessBuilder.Redirect.PIPE)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.start();
//process.getOutputStream().close();
process.waitFor(10, TimeUnit.MINUTES);
System.out.println("Program finished");
}
}
You can start it like that:
javac Main.java && java Main
So if the intention is to write to lxc stdin from a Java application, then there should be used following code to do it:
OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
and the required data should be written using writer
, or if nothing should be written, we can just close the stream.
If the intention is to provide data from Java process stdin, then the following form should be used in ProcessBuilder:
.redirectInput(ProcessBuilder.Redirect.INHERIT)
It's indeed not a problem of LXC. The exact result you will get if the bash command is read NAME
.
Maybe one thing in LXC is slightly misleading: when you start lxc launch
from the command line, it never hangs, waiting for user input. But when it is started from ProcessBuilder it hangs forever.
lxc info:
Issue description
I am trying to automate LXC container creation process. So I generated LXC .sh script to create a new LXC container. It works when I execute it manually from ssh. However when I try to run this script from Java programming language, it hangs on "lxc init" for some reason and I cannot figure out why.
The script:
How I tried to execute it (from Java language):
And with debug (BufferedReader.readLine()), the last thing I see is "2" which is the "echo 2" right before lxc init, then it hang indefinitely.
Is there anything that might be blocking the execution of lxc init from Java ? It is very weird because the Java is only triggering the script.sh and the commands are not directly executed via java process builder.
All other LXC commands (when executed from java) are working perfectly, just this one is not.