/*******************************************************************************
* Copyright (c) 2010, 2016 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alexander Kurtakov - initial API and implementation
* Red Hat Inc - modified to use in Docker UI
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui.consoles;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.core.IDockerContainerState;
import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IOConsole;
/**
* RpmConsole is used to output rpm/rpmbuild output.
*
*/
public class RunConsole extends IOConsole {
/** Id of this console. */
public static final String ID = "containerLog"; //$NON-NLS-1$
public static final String CONTAINER_LOG_TITLE = "ContainerLog.title"; //$NON-NLS-1$
public static final String DEFAULT_ID = "__DEFAULT_ID__"; //$NON-NLS-1$
private String containerId;
private String id;
private OutputStream outputStream;
private boolean attached = false;
/**
* Returns a reference to the console that is for the given container id. If
* such a console does not yet exist, it will be created.
*
* @param containerId
* The container id this console will be for. Must not be
* <code>null</code>.
* @return A console instance or <code>null</code> if the given containerId
* was <code>null</code>.
*/
public static RunConsole findConsole(String containerId) {
if (containerId == null)
return null;
return findConsole(containerId, DEFAULT_ID);
}
/**
* Returns a reference to the console that is for the given container id. If
* such a console does not yet exist, it will be created.
*
* @param container
* The container this console will be for. Must not be
* <code>null</code>.
* @return A console instance or <code>null</code> if the given containerId
* was <code>null</code>.
*/
public static RunConsole findConsole(IDockerContainer container) {
if (container == null)
return null;
return findConsole(container.id(), DEFAULT_ID, container.name());
}
/**
* Returns a reference to the console that is for the given container id. If
* such a console does not yet exist, it will be created.
*
* @param containerId
* The container this console will be for. Must not be
* <code>null</code>.
* @param id
* The secondary id used to identify consoles belonging to
* various owners.
* @return A console instance.
*/
public static RunConsole findConsole(String containerId, String id) {
return findConsole(containerId, id, containerId.substring(0, 8));
}
/**
* Returns a reference to the console that is for the given container id. If
* such a console does not yet exist, it will be created.
*
* @param containerId
* The container this console will be for. Must not be
* <code>null</code>.
* @param id
* The secondary id used to identify consoles belonging to
* various owners.
* @param name
* the name of the console to create if it did not already exist
* @return A console instance.
*/
public static RunConsole findConsole(String containerId, String id,
String name) {
RunConsole ret = null;
for (IConsole cons : ConsolePlugin.getDefault().getConsoleManager()
.getConsoles()) {
if (cons instanceof RunConsole
&& ((RunConsole) cons).containerId.equals(containerId)
&& ((RunConsole) cons).id.equals(id)) {
ret = (RunConsole) cons;
}
}
// no existing console, create new one
if (ret == null) {
ret = new RunConsole(containerId, id, name);
ConsolePlugin.getDefault().getConsoleManager()
.addConsoles(new IConsole[] { ret });
}
return ret;
}
/**
* Set the title of the RunConsole
*
* @param name
* - new title
*/
public void setTitle(String name) {
setName(name);
}
/**
* The console will be attached to the underlying container.
*
* @param connection
* The connection associated with this console.
*/
public void attachToConsole(final IDockerConnection connection) {
final InputStream in = getInputStream();
final OutputStream out = newOutputStream();
Thread t = new Thread(() -> {
try {
DockerConnection conn = (DockerConnection) connection;
if (conn.getContainerInfo(containerId).config().openStdin()) {
IDockerContainerState state = conn
.getContainerInfo(containerId).state();
do {
if (!state.running() && state.finishDate() == null) {
Thread.sleep(300);
}
state = conn.getContainerInfo(containerId).state();
} while (!state.running() && state.finishDate() == null);
conn.attachCommand(containerId, in, out);
}
} catch (Exception e) {
}
});
t.start();
attached = true;
}
public static void attachToTerminal (final IDockerConnection connection, final String containerId) {
Thread t = new Thread(() -> {
try {
DockerConnection conn = (DockerConnection) connection;
IDockerContainerState state = conn.getContainerInfo(containerId)
.state();
do {
if (!state.running() && state.finishDate() == null) {
Thread.sleep(300);
}
state = conn.getContainerInfo(containerId).state();
} while (!state.running() && state.finishDate() == null);
conn.attachCommand(containerId, null, null);
} catch (Exception e) {
}
});
t.start();
}
public void attachToConsole(final IDockerConnection connection,
String containerId) {
this.containerId = containerId;
attachToConsole(connection);
}
/**
* Indicates whether the console is attached to the container's terminal.
*
* @return true if the console is attached and false otherwise.
*/
public boolean isAttached() {
/*
* TODO: This will still return true when the corresponding container is
* stopped but not currently a problem as we always attach to a
* container about to be started.
*/
return attached;
}
/**
* Remove a given console from the Console view
*
* @param console
* the console to remove
*/
public static void removeConsole(RunConsole console) {
console.closeOutputStream();
ConsolePlugin.getDefault().getConsoleManager()
.removeConsoles(new IConsole[] { console });
}
/**
* Show this console in the Console View.
*/
public void showConsole() {
// Show this console
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(this);
}
/**
* Close the last output stream opened for this console.
*/
public void closeOutputStream() {
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
// do nothing...we tried
}
}
/**
* Get a new output stream for this console
*
* @return An output stream for writing to the console
*/
public OutputStream getOutputStream() {
outputStream = new ConsoleOutputStream(newOutputStream());
// outputStream = newOutputStream();
return outputStream;
}
/**
* Creates the console.
*
* @param containerId
* The container id this console is for.
* @param id
* The id to associate with this console.
* @param name
* The name to use for the console.
*/
private RunConsole(String containerId, String id, String name) {
super(DVMessages.getFormattedString(CONTAINER_LOG_TITLE, name), ID,
null, true);
this.containerId = containerId;
this.id = id;
}
}