package com.github.ruediste1.btrbck;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.inject.Singleton;
import com.github.ruediste1.btrbck.dom.RemoteRepository;
import com.github.ruediste1.btrbck.dom.SshTarget;
@Singleton
public class SshService {
private ThreadLocal<Boolean> sudoRemoteBtrbck = new ThreadLocal<>();
public void setSudoRemoteBtrbck(boolean value) {
sudoRemoteBtrbck.set(value);
}
protected boolean sudoRemoteBtrbck() {
return Boolean.TRUE.equals(sudoRemoteBtrbck.get());
}
private ThreadLocal<Boolean> sudoRemoteBtrfs = new ThreadLocal<>();
public void setSudoRemoteBtrfs(boolean value) {
sudoRemoteBtrfs.set(value);
}
protected boolean sudoRemoteBtrfs() {
return Boolean.TRUE.equals(sudoRemoteBtrfs.get());
}
private ThreadLocal<Boolean> verboseRemote = new ThreadLocal<>();
public void setVerboseRemote(boolean value) {
verboseRemote.set(value);
}
protected boolean verboseRemote() {
return Boolean.TRUE.equals(verboseRemote.get());
}
private final class SshConnectionimpl implements SshConnection {
private final Process process;
private SshConnectionimpl(Process process) {
this.process = process;
}
@Override
public OutputStream getOutputStream() {
return process.getOutputStream();
}
@Override
public InputStream getInputStream() {
return process.getInputStream();
}
@Override
public void close() throws Exception {
process.waitFor();
}
}
public interface SshConnection {
InputStream getInputStream();
OutputStream getOutputStream();
void close() throws Exception;
}
private ProcessBuilder processBuilder(SshTarget target,
List<String> commands) {
// construct command
LinkedList<String> list = new LinkedList<String>();
list.add("ssh");
// add port
if (target.getPort() != null) {
list.add("-p");
list.add(target.getPort().toString());
}
// add host
list.add(target.getHost());
// add commands
list.addAll(commands);
return new ProcessBuilder().redirectError(Redirect.INHERIT).command(
list);
}
public SshConnection sendSnapshots(RemoteRepository repo,
String remoteStreamName) throws IOException {
List<String> commands = new ArrayList<>();
if (sudoRemoteBtrbck()) {
commands.add("sudo");
}
commands.add("btrbck");
commands.add("-r");
commands.add(repo.location);
if (sudoRemoteBtrfs()) {
commands.add("-sudo");
}
if (verboseRemote()) {
commands.add("-v");
}
commands.add("sendSnapshots");
commands.add(remoteStreamName);
final Process process = processBuilder(repo.sshTarget, commands)
.start();
return new SshConnectionimpl(process);
}
public SshConnection receiveSnapshots(RemoteRepository repo,
String remoteStreamName, boolean createRemoteIfNecessary)
throws IOException {
List<String> commands = new ArrayList<>();
if (sudoRemoteBtrbck()) {
commands.add("sudo");
}
commands.add("btrbck");
if (createRemoteIfNecessary) {
commands.add("-c");
}
commands.add("-r");
commands.add(repo.location);
if (sudoRemoteBtrfs()) {
commands.add("-sudo");
}
if (verboseRemote()) {
commands.add("-v");
}
commands.add("receiveSnapshots");
commands.add(remoteStreamName);
Process process = processBuilder(repo.sshTarget, commands).start();
return new SshConnectionimpl(process);
}
}