[gnome-boxes/wip/feborges/containers] docker: Suport pulling an image and running it



commit 2237a442a3ae05e3f4f05cd6f267daaa881990b7
Author: Felipe Borges <felipeborges gnome org>
Date:   Tue Jul 3 12:54:25 2018 +0200

    docker: Suport pulling an image and running it

 src/app.vala            |  3 +-
 src/docker-display.vala | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/meson.build         |  1 +
 src/remote-machine.vala |  4 ++
 src/wizard.vala         |  3 ++
 5 files changed, 108 insertions(+), 1 deletion(-)
---
diff --git a/src/app.vala b/src/app.vala
index dd764d8b..2dae4d47 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -381,6 +381,7 @@ public async void add_collection_source (CollectionSource source) throws GLib.Er
         case "vnc":
         case "spice":
         case "ssh":
+        case "docker":
         case "rdp":
             try {
                 var machine = new RemoteMachine (source);
@@ -653,4 +654,4 @@ public new void uninhibit () {
     construct {
         set_transient_for (App.app.main_window);
     }
-}
\ No newline at end of file
+}
diff --git a/src/docker-display.vala b/src/docker-display.vala
new file mode 100644
index 00000000..c7655979
--- /dev/null
+++ b/src/docker-display.vala
@@ -0,0 +1,98 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+using Gtk;
+using Vte;
+
+private class Boxes.DockerDisplay: Boxes.Display {
+    public override string protocol { get { return "DOCKER"; } }
+    public override string? uri { owned get { return @"docker://$host"; } }
+    private Terminal display;
+    private string host;
+    private BoxConfig.SavedProperty[] saved_properties;
+
+    construct {
+        saved_properties = {
+            BoxConfig.SavedProperty () { name = "read-only", default_value = false }
+        };
+        display = new Terminal ();
+       display.show.connect (() => {
+            show (0);
+            access_start ();
+       });
+    }
+
+    public DockerDisplay (BoxConfig config, string host, int port) {
+        this.config = config;
+
+        this.host = host;
+
+        config.save_properties (display, saved_properties);
+    }
+
+    public DockerDisplay.with_uri (BoxConfig config, string _uri) throws Boxes.Error {
+        this.config = config;
+
+        var uri = Xml.URI.parse (_uri);
+
+        if (uri.scheme != "docker")
+            throw new Boxes.Error.INVALID ("the URL is not docker://");
+
+        if (uri.server == null)
+            throw new Boxes.Error.INVALID ("the URL is missing a server");
+
+       this.host = uri.server + uri.path;
+
+        config.save_properties (display, saved_properties);
+    }
+
+    public override Gtk.Widget get_display (int n) {
+        return display;
+    }
+
+    public override void set_enable_audio (bool enable) {
+    }
+
+    public override Gdk.Pixbuf? get_pixbuf (int n) throws Boxes.Error {
+       return null;
+    }
+
+    private bool run (string [] command) {
+        if (!connected)
+            return false;
+
+       SpawnFlags flags = SpawnFlags.SEARCH_PATH_FROM_ENVP | SpawnFlags.DO_NOT_REAP_CHILD;
+
+       return display.spawn_sync (PtyFlags.DEFAULT, Environment.get_home_dir (), command, null, flags, null, 
null);
+    }
+
+    public override void connect_it (owned Display.OpenFDFunc? open_fd = null) throws GLib.Error {
+        // We only initiate connection once
+        if (connected)
+            return;
+        connected = true;
+       
+       display.show_all ();
+
+       string[] docker_pull = {
+            "/usr/bin/docker", "pull " + host,
+        };
+
+       string[] docker_run = {
+           "/usr/bin/docker", "run", "-it", host,
+       };
+
+       run (docker_pull);
+       run (docker_run);
+    }
+
+    public override void disconnect_it () {
+    }
+
+    public override List<Boxes.Property> get_properties (Boxes.PropertiesPage page) {
+        var list = new List<Boxes.Property> ();
+
+        return list;
+    }
+
+    public override void send_keys (uint[] keyvals) {
+    }
+}
diff --git a/src/meson.build b/src/meson.build
index 3bc6be2c..7dffa639 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -106,6 +106,7 @@ vala_sources = [
   'libvirt-vm-importer.vala',
   'vnc-display.vala',
   'ssh-display.vala',
+  'docker-display.vala',
   'wizard-downloads-page.vala',
   'wizard-window.vala',
   'wizard-source.vala',
diff --git a/src/remote-machine.vala b/src/remote-machine.vala
index 8359a961..355e8bb6 100644
--- a/src/remote-machine.vala
+++ b/src/remote-machine.vala
@@ -9,6 +9,7 @@ public RemoteMachine (CollectionSource source) throws Boxes.Error {
         if (source.source_type != "spice" &&
             source.source_type != "vnc" &&
             source.source_type != "ssh" &&
+            source.source_type != "docker" &&
             source.source_type != "rdp")
             throw new Boxes.Error.INVALID ("source is not remote machine: %s", source.uri);
 
@@ -44,6 +45,9 @@ public RemoteMachine (CollectionSource source) throws Boxes.Error {
         case "ssh":
             return new SshDisplay.with_uri (config, source.uri);
 
+        case "docker":
+            return new DockerDisplay.with_uri (config, source.uri);
+
         default:
             throw new Boxes.Error.INVALID ("unsupported display of type " + type);
         }
diff --git a/src/wizard.vala b/src/wizard.vala
index 056d9a0b..7d9a502a 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -364,6 +364,8 @@ private void prepare_for_uri (string uri_as_text, string? filename = null, strin
         if (uri.scheme.has_prefix ("spice")) {
             spice_validate_uri (uri_as_text);
             source.source_type = "spice";
+        } else if (uri.scheme == "docker") {
+            // accept any docker:// uri
         } else if (uri.scheme == "vnc") {
             // accept any vnc:// uri
         } else if (uri.scheme == "ssh") {
@@ -558,6 +560,7 @@ private async bool do_review_cancellable () {
             case "vnc":
             case "rdp":
             case "ssh":
+            case "docker":
                 if (uri.port > 0)
                     summary.add_property (_("Port"), uri.port.to_string ());
                 break;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]