vagrant-communicator-docker 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|