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 +7 -0
- data/.gitignore +13 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +114 -0
- data/Rakefile +3 -0
- data/communicator-docker-0.0.1.gem +0 -0
- data/communicator-docker-1.0.0.gem +0 -0
- data/communicator-docker-1.0.1.gem +0 -0
- data/communicator-docker-1.0.2.gem +0 -0
- data/communicator-docker-1.0.3.gem +0 -0
- data/communicator-docker-1.0.4.gem +0 -0
- data/communicator-docker-1.0.5.gem +0 -0
- data/communicator-docker-1.0.6.gem +0 -0
- data/communicator-docker.gemspec +16 -0
- data/lib/vagrant-communicator-docker/config.rb +19 -0
- data/lib/vagrant-communicator-docker/plugin.rb +29 -0
- data/lib/vagrant-communicator-docker/vagrant-communicator-docker.rb +157 -0
- data/lib/vagrant-communicator-docker/version.rb +5 -0
- data/lib/vagrant-communicator-docker.rb +2 -0
- data/package-lock.json +3 -0
- metadata +64 -0
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
data/Gemfile
ADDED
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
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
|
data/package-lock.json
ADDED
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: []
|