vagrant-communicator-docker 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: eb4aea56e9f2b6c933234e8c76a9bde7721b897639ace97c9d8546d50343d2cd
4
+ data.tar.gz: d9bc70a8168645b609d1b5c9ba57e6059180d74969097f1b06bbf0e934741c4f
5
+ SHA512:
6
+ metadata.gz: c55d121aca3d826ffbe5f1b6c053a23b3843183056f2e6d9e47755a661d00338c2e35dbb54cc7c21797cb1c6127d6eeb66670a1bb1b2cca807c5944d7477a1c0
7
+ data.tar.gz: bd23c04708f136e37381e0ad0d10b7fadf1013188879c94b4111cc83dfe896a690fe512fce035376b72f5136ac7207174f4842ff91db3bdca35792ae7f8e5dc8
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /spec/reports/
7
+ /tmp/
8
+ /vendor
9
+ /vagrant-communicator-docker
10
+ /bin
11
+ /pkg
12
+ Gemfile.lock
13
+
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+ gem 'docker-api'
3
+
4
+ group :development do
5
+ gem "vagrant", git: "https://github.com/hashicorp/vagrant.git"
6
+ end
7
+
8
+ group :plugins do
9
+ gem "communicator-docker", path: "."
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Lucas van Staden
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # Vagrant::Communicator::Docker
2
+
3
+ This is a communicator plugin allowing vagrant to access docker instances as if they have SSH.
4
+
5
+ This was created to facilitate host file management using a vagrant host file manager plugin, which requires SSH to fetch,
6
+ edit, and put back container hosts files. The assumption that vagrant SSH communicator makes, is that all containers
7
+ have SSH - They do not.
8
+
9
+ This communicator will make vagrant tasks that require SSH, interact with the docker instances, as if SSH exists, by
10
+ using the Docker API.
11
+
12
+ This has only been used in a Linux environment.
13
+
14
+ ## Requirements
15
+
16
+ * Docker API gem: ```vagrant plugin install docker-api```
17
+
18
+ If you get an error noted as: ```undefined method `copy' for...``` please use : ```vagrant plugin install docker-api --plugin-version=1.34.2```
19
+
20
+ ## Installation
21
+
22
+ Needs to be installed as a vagrant plugin
23
+
24
+ ```
25
+ vagrant plugin install vagrant-communicator-docker
26
+ ```
27
+
28
+ ### Manual install
29
+
30
+ * fetch the built gem package located here: ```https://raw.githubusercontent.com/ProxiBlue/vagrant-communicator-docker/master/communicator-docker-1.0.6.gem```
31
+ * install using: ```vagrant plugin install communicator-docker-1.0.6.gem```
32
+
33
+ ```
34
+ curl https://raw.githubusercontent.com/ProxiBlue/vagrant-communicator-docker/master/communicator-docker-1.0.6.gem > communicator-docker-1.0.6.gem
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ * You need to set your vagrant instance to have SSH using ```has_ssh```
40
+ * You need to set the communicator using ```vm.communicator = 'docker'```
41
+ * You can set the shell to use with ```vm.communicator.bash_shell```
42
+ * You can set the shell wait with ```vm.communicator.bash_wait```
43
+
44
+ Example vagrant definition:
45
+
46
+ ```
47
+ config.vm.define "database", primary: false do |database|
48
+ database.hostmanager.aliases = [ "database."+dev_domain ]
49
+ database.vm.network :private_network, ip: "172.20.0.208", subnet: "172.20.0.0/16"
50
+ database.vm.hostname = "database"
51
+ database.vm.communicator = 'docker'
52
+ database.vm.provider 'docker' do |d|
53
+ d.image = "mysql:5.7"
54
+ d.has_ssh = true
55
+ d.name = "database"
56
+ d.remains_running = true
57
+ end
58
+ end
59
+ ```
60
+
61
+ ## Limitations
62
+
63
+ Communicates with a local docker service via linux sockets. That is all I need.
64
+ Should be able to be extended to include a docker connection string to a tcp connection, but I have no need for that as yet, so not implemented.
65
+
66
+ The default shell will be /bin/bash inside the docker container. You can override this using : ```vm.communicator.bash_shell = '/bin/sh';``` to use /bin/sh (or any other shell)
67
+
68
+ If you get the error:
69
+
70
+ ```
71
+ The guest operating system of the machine could not be detected!
72
+ Vagrant requires this knowledge to perform specific tasks such
73
+ as mounting shared folders and configuring networks. Please add
74
+ the ability to detect this guest operating system to Vagrant
75
+ by creating a plugin or reporting a bug.
76
+
77
+ ```
78
+
79
+ you likely need to change the shell to /bin/sh OR increase the shell_wait (default is 10)
80
+
81
+ ## shell_wait
82
+
83
+ I have found some docker instances need a little extra time to initialise, before docker can send commands
84
+ The default wait timeout is 10s. Increase in increments of 5 to see if you can overcome issue.
85
+
86
+ ## Solved issues?
87
+
88
+ Not had this for some time, so I think solved due to ongoing changes.
89
+
90
+ ### Problems with some docker images, failing with message that image is not running
91
+
92
+ I have not managed to spend time on this, to pin it down, but some (random) docker images will fail if you set ```d.has_ssh = true``` - The only fix is to set that to false, which can stop other functions (example usage of a hostmanager plugin)
93
+
94
+ You can run a global trigger to overcome this, allowing hostmanagers to update after it was completed:
95
+
96
+ ```
97
+ config.trigger.after :up do |trigger|
98
+ trigger.run = {inline: "bash -c 'vagrant hostmanager --provider docker'"}
99
+ end
100
+ ```
101
+
102
+ ## Debug
103
+
104
+ ```vagrant halt database && vagrant up database --debug &>/tmp/debug.log``` then view the debug log.
105
+
106
+ You will see debug entries with the string: ```DOCKER COMMUNICATOR```
107
+
108
+ ## Contributing
109
+
110
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ProxiBlue/vagrant-communicator-docker.
111
+
112
+ ## License
113
+
114
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ Bundler::GemHelper.install_tasks
Binary file
Binary file
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../lib/vagrant-communicator-docker/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'vagrant-communicator-docker'
5
+ s.version = VagrantPlugins::VagrantCommunicatorDocker::VERSION
6
+ s.date = '2019-11-01'
7
+ s.summary = "Simulate SSH using Docket API when provisioning vagrant machines that use docker images without SSH"
8
+ s.description = "Simulate SSH using Docket API when provisioning vagrant machines that use docker images without SSH"
9
+ s.authors = ["Lucas van Staden"]
10
+ s.email = 'sales@proxiblue.com.au'
11
+ s.files = `git ls-files`.split($\)
12
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ s.require_paths = ['lib']
14
+ s.homepage = 'https://github.com/ProxiBlue/vagrant-communicator-docker'
15
+ s.license = 'MIT'
16
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module VagrantCommunicatorDocker
3
+ class Config < Vagrant.plugin('2', :config)
4
+ attr_accessor :bash_shell
5
+ attr_accessor :bash_wait
6
+
7
+ def initialize
8
+ @bash_shell = UNSET_VALUE
9
+ @bash_wait = UNSET_VALUE
10
+ end
11
+
12
+ def finalize!
13
+ @bash_shell = '/bin/bash' if @bash_shell == UNSET_VALUE
14
+ @bash_wait = 10 if @bash_wait == UNSET_VALUE
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+
2
+
3
+ begin
4
+ require "vagrant"
5
+ rescue LoadError
6
+ raise "The Vagrant AWS plugin must be run within Vagrant."
7
+ end
8
+
9
+ module VagrantPlugins
10
+ module VagrantCommunicatorDocker
11
+ class Plugin < Vagrant.plugin("2")
12
+ name "Docker Communicator"
13
+ description <<-DESC
14
+ This plugin allows Vagrant to communicate with docker instances that do not have SSH,
15
+ but can use docker exec to run commands within
16
+ DESC
17
+
18
+ communicator("docker") do
19
+ require File.expand_path("../vagrant-communicator-docker", __FILE__)
20
+ Communicator
21
+ end
22
+
23
+ config("communicator") do
24
+ require_relative "config"
25
+ Config
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,157 @@
1
+ require 'logger'
2
+ require 'timeout'
3
+ require 'rubygems/package'
4
+ require 'fileutils'
5
+
6
+ require 'log4r'
7
+ require 'docker'
8
+
9
+ module VagrantPlugins
10
+ module VagrantCommunicatorDocker
11
+ # This class provides communication with Docker instances
12
+ class Communicator < Vagrant.plugin("2", :communicator)
13
+
14
+ def self.match?(machine)
15
+ # All machines are currently expected to be docker instances.
16
+ return true
17
+ end
18
+
19
+ def initialize(machine)
20
+ @logger = Log4r::Logger.new("vagrant::communication::docker")
21
+ @machine = machine
22
+ @machineID = machine.id
23
+ @logger.debug("MACHINE ID #{@machineID}")
24
+ @logger.debug("MACHINE SHELL: #{@machine.config.communicator.bash_shell}")
25
+ @logger.debug("SHELL WAIT: #{@machine.config.communicator.bash_wait}")
26
+ end
27
+
28
+ def ready?
29
+ begin
30
+ @logger.info(Docker.version)
31
+ @container = Docker::Container.get(@machineID)
32
+ @logger.debug(@container.json)
33
+ # If we reached this point then we successfully connected
34
+ true
35
+ rescue
36
+ @logger.debug("DOCKER COMMUNICATOR - Could not make connection to #{@machineID}")
37
+ false
38
+ end
39
+ end
40
+
41
+ # wait_for_ready waits until the communicator is ready, blocking
42
+ # until then. It will wait up to the given duration or raise an
43
+ # exception if something goes wrong.
44
+ #
45
+ # @param [Integer] duration Timeout in seconds.
46
+ # @return [Boolean] Will return true on successful connection
47
+ # or false on timeout.
48
+ def wait_for_ready(duration)
49
+ # By default, we implement a naive solution.
50
+ begin
51
+ Timeout.timeout(duration) do
52
+ while true
53
+ return true if ready?
54
+ sleep 0.5
55
+ end
56
+ end
57
+ rescue Timeout::Error
58
+ # We timed out, we failed.
59
+ end
60
+
61
+ return false
62
+ end
63
+
64
+ # Download a file from the remote machine to the local machine.
65
+ #
66
+ # @param [String] from Path of the file on the remote machine.
67
+ # @param [String] to Path of where to save the file locally.
68
+ def download(from, to)
69
+ @logger.debug("DOCKER COMMUNICATOR - DOWNLOAD from: #{from} to: #{to}")
70
+ tempfile = "/tmp/#{SecureRandom.urlsafe_base64}.tar"
71
+ @logger.debug("DOCKER COMMUNICATOR - tempfile - #{tempfile}")
72
+ File.open(tempfile, "w") do |file|
73
+ @container.archive_out(from) do |chunk|
74
+ file.write(chunk)
75
+ end
76
+ end
77
+ Gem::Package::TarReader.new( File.open(tempfile) ) do |tar|
78
+ tar.each do |entry|
79
+ File.open to, "wb" do |f|
80
+ f.print entry.read
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ # Upload a file to the remote machine.
87
+ #
88
+ # @param [String] from Path of the file locally to upload.
89
+ # @param [String] to Path of where to save the file on the remote
90
+ # machine.
91
+ def upload(from, to)
92
+ @logger.debug("DOCKER COMMUNICATOR - upload from: #{from} to: #{to}")
93
+ @container.archive_in(from, File.dirname(to), overwrite: true)
94
+ end
95
+
96
+ # Execute a command on the remote machine. The exact semantics
97
+ # of this method are up to the implementor, but in general the
98
+ # users of this class will expect this to be a shell.
99
+ #
100
+ # This method gives you no way to write data back to the remote
101
+ # machine, so only execute commands that don't expect input.
102
+ #
103
+ # @param [String] command Command to execute.
104
+ # @yield [type, data] Realtime output of the command being executed.
105
+ # @yieldparam [String] type Type of the output. This can be
106
+ # `:stdout`, `:stderr`, etc. The exact types are up to the
107
+ # implementor.
108
+ # @yieldparam [String] data Data for the given output.
109
+ # @return [Integer] Exit code of the command.
110
+ def execute(command, opts=nil)
111
+ begin
112
+ wait_for_ready(@machine.config.communicator.bash_wait)
113
+ result = @container.exec([@machine.config.communicator.bash_shell, '-c' , command], stderr: false)
114
+ @logger.debug(result)
115
+ @logger.debug(result.last)
116
+ return result.last
117
+ rescue
118
+ @logger.info("Error running command " + command + " on guest using shell #{@machine.config.communicator.bash_shell}")
119
+ end
120
+ return 255
121
+ end
122
+
123
+ # Executes a command on the remote machine with administrative
124
+ # privileges. See {#execute} for documentation, as the API is the
125
+ # same.
126
+ #
127
+ # @see #execute
128
+ def sudo(command, opts=nil)
129
+ @logger.debug("DOCKER COMMUNICATOR - EXECUTE WITH SUDO: #{command}")
130
+ execute(command, opts)
131
+ end
132
+
133
+ # Executes a command and returns true if the command succeeded,
134
+ # and false otherwise. By default, this executes as a normal user,
135
+ # and it is up to the communicator implementation if they expose an
136
+ # option for running tests as an administrator.
137
+ #
138
+ # @see #execute
139
+ def test(command, opts=nil)
140
+ result = execute(command, opts)
141
+ if result == 0
142
+ return true
143
+ end
144
+ return false
145
+ end
146
+
147
+ # Reset the communicator. For communicators which establish
148
+ # a persistent connection to the remote machine, this connection
149
+ # should be terminated and re-established. The communicator
150
+ # instance should be in a "fresh" state after calling this method.
151
+ def reset!
152
+ @logger.debug("DOCKER COMMUNICATOR - RESET - NOT IMPLEMENTED")
153
+ end
154
+
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module VagrantCommunicatorDocker
3
+ VERSION = '1.0.7'
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ require 'vagrant-communicator-docker/plugin'
2
+
data/package-lock.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "lockfileVersion": 1
3
+ }
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-communicator-docker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.7
5
+ platform: ruby
6
+ authors:
7
+ - Lucas van Staden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Simulate SSH using Docket API when provisioning vagrant machines that
14
+ use docker images without SSH
15
+ email: sales@proxiblue.com.au
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - Gemfile
22
+ - LICENSE.txt
23
+ - README.md
24
+ - Rakefile
25
+ - communicator-docker-0.0.1.gem
26
+ - communicator-docker-1.0.0.gem
27
+ - communicator-docker-1.0.1.gem
28
+ - communicator-docker-1.0.2.gem
29
+ - communicator-docker-1.0.3.gem
30
+ - communicator-docker-1.0.4.gem
31
+ - communicator-docker-1.0.5.gem
32
+ - communicator-docker-1.0.6.gem
33
+ - communicator-docker.gemspec
34
+ - lib/vagrant-communicator-docker.rb
35
+ - lib/vagrant-communicator-docker/config.rb
36
+ - lib/vagrant-communicator-docker/plugin.rb
37
+ - lib/vagrant-communicator-docker/vagrant-communicator-docker.rb
38
+ - lib/vagrant-communicator-docker/version.rb
39
+ - package-lock.json
40
+ homepage: https://github.com/ProxiBlue/vagrant-communicator-docker
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.1.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Simulate SSH using Docket API when provisioning vagrant machines that use
63
+ docker images without SSH
64
+ test_files: []