This is an automated email from the ASF dual-hosted git repository. geertjan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 7881913 Docker support: add inspect & process list actions (#1257) 7881913 is described below commit 7881913517664c169733faee9bd73d027e38cf92 Author: Ihsahn <ihs...@users.noreply.github.com> AuthorDate: Wed Sep 4 16:22:27 2019 +0200 Docker support: add inspect & process list actions (#1257) --- .../netbeans/modules/docker/api/DockerAction.java | 16 ++- .../modules/docker/api/DockerContainer.java | 8 +- .../modules/docker/api/DockerEntityType.java | 37 +++++++ .../netbeans/modules/docker/api/DockerImage.java | 8 +- .../modules/docker/api/DockerInstanceEntity.java | 30 +++++ .../org/netbeans/modules/docker/api/DockerTag.java | 14 ++- .../modules/docker/ui/JsonFormattingWriter.java | 72 ++++++++++++ .../docker/ui/node/DockerContainerNode.java | 2 + .../modules/docker/ui/node/DockerTagNode.java | 1 + .../docker/ui/node/InspectContainerAction.java | 122 +++++++++++++++++++++ .../modules/docker/ui/node/ProcessListAction.java | 81 ++++++++++++++ 11 files changed, 385 insertions(+), 6 deletions(-) diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java index a5f779f..f7f340d 100644 --- a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerAction.java @@ -78,6 +78,7 @@ import org.netbeans.modules.docker.DockerConfig; import org.netbeans.modules.docker.DockerUtils; import org.netbeans.modules.docker.Endpoint; import org.netbeans.modules.docker.StreamResult; +import static org.netbeans.modules.docker.api.DockerEntityType.Container; import org.newsclub.net.unix.AFUNIXSocket; import org.newsclub.net.unix.AFUNIXSocketAddress; import org.openide.filesystems.FileObject; @@ -307,9 +308,14 @@ public class DockerAction { return new DockerTag(source.getImage(), tagResult); } - public DockerContainerDetail getDetail(DockerContainer container) throws DockerException { - JSONObject value = (JSONObject) doGetRequest("/containers/" + container.getId() + "/json", + public JSONObject getRawDetails(DockerEntityType entityType, String containerId) throws DockerException { + JSONObject value = (JSONObject) doGetRequest(entityType.getUrlPath() + containerId + "/json", Collections.singleton(HttpURLConnection.HTTP_OK)); + return value; + } + + public DockerContainerDetail getDetail(DockerContainer container) throws DockerException { + JSONObject value = getRawDetails(DockerEntityType.Container, container.getId()); String name = (String) value.get("Name"); DockerContainer.Status status = DockerContainer.Status.STOPPED; JSONObject state = (JSONObject) value.get("State"); @@ -1378,6 +1384,12 @@ public class DockerAction { return id; } + public JSONObject getRunningProcessesList(DockerContainer container) throws DockerException { + JSONObject value = (JSONObject) doGetRequest(Container.getUrlPath() + container.getId() + "/top", + Collections.singleton(HttpURLConnection.HTTP_OK)); + return value; + } + private static class DirectFetcher implements StreamItem.Fetcher { private final InputStream is; diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerContainer.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerContainer.java index e8205e2..99c9aa8 100644 --- a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerContainer.java +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerContainer.java @@ -24,7 +24,12 @@ import java.util.Objects; * * @author Petr Hejl */ -public final class DockerContainer implements DockerEntity { +public final class DockerContainer implements DockerInstanceEntity { + + @Override + public DockerEntityType getType() { + return DockerEntityType.Container; + } public enum Status { RUNNING, @@ -50,6 +55,7 @@ public final class DockerContainer implements DockerEntity { this.status = status; } + @Override public DockerInstance getInstance() { return instance; } diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerEntityType.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerEntityType.java new file mode 100644 index 0000000..643022f --- /dev/null +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerEntityType.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.docker.api; + +/** + * + * @author ihsahn + */ +public enum DockerEntityType { + Container("/containers/"), Image("/images/"); + private final String urlPath; + + private DockerEntityType(String urlPath) { + this.urlPath = urlPath; + } + + public String getUrlPath() { + return urlPath; + } + +} diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerImage.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerImage.java index ebdb3d4..035eb01 100644 --- a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerImage.java +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerImage.java @@ -28,7 +28,7 @@ import java.util.logging.Logger; * * @author Petr Hejl */ -public final class DockerImage implements DockerEntity { +public final class DockerImage implements DockerInstanceEntity { private final DockerInstance instance; @@ -61,6 +61,7 @@ public final class DockerImage implements DockerEntity { } } + @Override public DockerInstance getInstance() { return instance; } @@ -125,4 +126,9 @@ public final class DockerImage implements DockerEntity { return "DockerImage{" + "instance=" + instance + ", id=" + id + '}'; } + @Override + public DockerEntityType getType() { + return DockerEntityType.Container; + } + } diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerInstanceEntity.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerInstanceEntity.java new file mode 100644 index 0000000..be98b85 --- /dev/null +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerInstanceEntity.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.docker.api; + +/** + * + * @author ihsahn + */ +public interface DockerInstanceEntity extends DockerEntity { + + DockerInstance getInstance(); + + public DockerEntityType getType(); +} diff --git a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerTag.java b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerTag.java index ed38e03..7507e91 100644 --- a/ide/docker.api/src/org/netbeans/modules/docker/api/DockerTag.java +++ b/ide/docker.api/src/org/netbeans/modules/docker/api/DockerTag.java @@ -24,12 +24,12 @@ import java.util.Objects; * * @author Petr Hejl */ -public final class DockerTag implements DockerEntity { +public final class DockerTag implements DockerInstanceEntity { private final DockerImage image; private final String tag; - + DockerTag(DockerImage image, String tag) { this.image = image; this.tag = tag; @@ -86,4 +86,14 @@ public final class DockerTag implements DockerEntity { public String toString() { return "DockerTag{" + "image=" + image + ", tag=" + tag + '}'; } + + @Override + public DockerInstance getInstance() { + return image.getInstance(); + } + + @Override + public DockerEntityType getType() { + return DockerEntityType.Image; + } } diff --git a/ide/docker.ui/src/org/netbeans/modules/docker/ui/JsonFormattingWriter.java b/ide/docker.ui/src/org/netbeans/modules/docker/ui/JsonFormattingWriter.java new file mode 100644 index 0000000..aebbb2f --- /dev/null +++ b/ide/docker.ui/src/org/netbeans/modules/docker/ui/JsonFormattingWriter.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.docker.ui; + +import java.io.StringWriter; + +/** + * + * @author ihsahn + */ +public class JsonFormattingWriter extends StringWriter { + + private int indent = 0; + private final int indentationWidth; + + public JsonFormattingWriter(int indentationWidth) { + this.indentationWidth = indentationWidth; + } + + @Override + public void write(int c) { + switch ((char) c) { + case '[': + case '{': + super.write(c); + super.write('\n'); + indent++; + writeIndentation(); + break; + case ',': + super.write(c); + super.write('\n'); + writeIndentation(); + break; + case ']': + case '}': + super.write('\n'); + indent--; + writeIndentation(); + super.write(c); + break; + default: + super.write(c); + break; + } + + } + + private void writeIndentation() { + for (int i = 0; i < indent; i++) { + for (int j = 0; j < indentationWidth; j++) { + super.write(' '); + } + } + } +} diff --git a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java index 9abbe6d..c1e1f9b 100644 --- a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java +++ b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerContainerNode.java @@ -97,6 +97,8 @@ public class DockerContainerNode extends AbstractNode { null, SystemAction.get(CopyIdAction.class), SystemAction.get(GetPortMappingsAction.class), + SystemAction.get(InspectContainerAction.class), + SystemAction.get(ProcessListAction.class), null, SystemAction.get(RefreshAction.class), null, diff --git a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerTagNode.java b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerTagNode.java index 6cf097d..ae7408c 100644 --- a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerTagNode.java +++ b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/DockerTagNode.java @@ -55,6 +55,7 @@ public class DockerTagNode extends AbstractNode { SystemAction.get(PushTagAction.class), null, SystemAction.get(CopyIdAction.class), + SystemAction.get(InspectContainerAction.class), null, SystemAction.get(RemoveTagAction.class) }; diff --git a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/InspectContainerAction.java b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/InspectContainerAction.java new file mode 100644 index 0000000..39a3a44 --- /dev/null +++ b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/InspectContainerAction.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.docker.ui.node; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.json.simple.JSONObject; +import org.netbeans.modules.docker.api.DockerAction; +import org.netbeans.modules.docker.api.DockerException; +import org.netbeans.modules.docker.api.DockerInstanceEntity; +import org.netbeans.modules.docker.ui.JsonFormattingWriter; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.nodes.Node; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; +import org.openide.util.actions.NodeAction; +import org.openide.windows.IOProvider; +import org.openide.windows.InputOutput; + +/** + * + * @author ihsahn + */ +public class InspectContainerAction extends NodeAction { + + private static final Logger LOGGER = Logger.getLogger(InspectContainerAction.class.getName()); + private final RequestProcessor requestProcessor = new RequestProcessor(InspectContainerAction.class); + + @NbBundle.Messages("LBL_InspectAction=Inspect") + @Override + public String getName() { + return Bundle.LBL_InspectAction(); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + protected boolean asynchronous() { + return false; + } + + @Override + protected boolean enable(Node[] activatedNodes) { + for (Node node : activatedNodes) { + DockerInstanceEntity entity = node.getLookup().lookup(DockerInstanceEntity.class); + if (entity == null) { + return false; + } + } + return true; + } + + @Override + protected void performAction(Node[] activatedNodes) { + for (final Node node : activatedNodes) { + DockerInstanceEntity container = node.getLookup().lookup(DockerInstanceEntity.class); + if (container != null) { + requestProcessor.post(new InspectRunnable(container)); + } + } + } + + private static class InspectRunnable implements Runnable { + + private final DockerInstanceEntity container; + + public InspectRunnable(DockerInstanceEntity container) { + this.container = container; + } + + @NbBundle.Messages({ + "# {0} - container id", + "MSG_Inspecting=Inspecting container {0}" + }) + @Override + public void run() { + JsonFormattingWriter formattedJsonWriter = new JsonFormattingWriter(2); + + try { + DockerAction facade = new DockerAction(container.getInstance()); + JSONObject rawDetails = facade.getRawDetails(container.getType(), container.getId()); + + rawDetails.writeJSONString(formattedJsonWriter); + + InputOutput io = IOProvider.getDefault().getIO(Bundle.MSG_Inspecting(container.getShortId()), false); + io.getOut().reset(); + io.getOut().println(formattedJsonWriter.toString()); + io.getOut().close(); + io.getErr().close(); + io.select(); + } catch (IOException | DockerException ex) { + LOGGER.log(Level.INFO, null, ex); + String msg = ex.getLocalizedMessage(); + NotifyDescriptor desc = new NotifyDescriptor.Message(msg, NotifyDescriptor.ERROR_MESSAGE); + DialogDisplayer.getDefault().notify(desc); + } + } + } + +} diff --git a/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/ProcessListAction.java b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/ProcessListAction.java new file mode 100644 index 0000000..ab1bc94 --- /dev/null +++ b/ide/docker.ui/src/org/netbeans/modules/docker/ui/node/ProcessListAction.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.docker.ui.node; + +import java.io.IOException; +import org.json.simple.JSONObject; +import org.netbeans.modules.docker.api.DockerAction; +import org.netbeans.modules.docker.api.DockerContainer; +import org.netbeans.modules.docker.api.DockerContainerDetail; +import org.netbeans.modules.docker.api.DockerException; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.openide.windows.IOProvider; +import org.openide.windows.InputOutput; + +/** + * + * @author ihsahn + */ +public class ProcessListAction extends AbstractContainerAction { + + private static final String PROCESSES_JSON_KEY = "Processes"; + private static final String TITLES_JSON_KEY = "Titles"; + + @NbBundle.Messages("LBL_ProcessListAction=List running processes") + public ProcessListAction() { + super(Bundle.LBL_ProcessListAction()); + } + + @NbBundle.Messages({ + "# {0} - container id", + "MSG_ProcessList=Processes in {0}" + }) + @Override + protected void performAction(DockerContainer container) throws DockerException { + try { + DockerAction facade = new DockerAction(container.getInstance()); + JSONObject processList = facade.getRunningProcessesList(container); + + InputOutput io = IOProvider.getDefault().getIO(Bundle.MSG_ProcessList(container.getShortId()), false); + io.getOut().reset(); + io.getOut().println(processList.get(TITLES_JSON_KEY).toString()); + io.getOut().println(processList.get(PROCESSES_JSON_KEY).toString()); + io.getOut().close(); + io.getErr().close(); + io.select(); + } catch (IOException ex) { + throw new DockerException(ex); + } + } + + @NbBundle.Messages({ + "# {0} - container id", + "MSG_ListingProcessesInContainer=Listing running processes in container {0}" + }) + @Override + protected String getProgressMessage(DockerContainer container) { + return Bundle.MSG_ListingProcessesInContainer(container.getShortId()); + } + + @Override + protected boolean isEnabled(DockerContainerDetail detail) { + return detail.getStatus() == DockerContainer.Status.RUNNING; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists