vagrant-qubes 0.0.1
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 +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +121 -0
- data/LICENSE.txt +21 -0
- data/README.md +71 -0
- data/Rakefile +3 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/vagrant-qubes.rb +14 -0
- data/lib/vagrant-qubes/action.rb +97 -0
- data/lib/vagrant-qubes/action/address.rb +40 -0
- data/lib/vagrant-qubes/action/boot.rb +47 -0
- data/lib/vagrant-qubes/action/createvm.rb +68 -0
- data/lib/vagrant-qubes/action/destroy.rb +49 -0
- data/lib/vagrant-qubes/action/halt.rb +47 -0
- data/lib/vagrant-qubes/action/read_ssh_info.rb +72 -0
- data/lib/vagrant-qubes/action/read_state.rb +54 -0
- data/lib/vagrant-qubes/action/wait_for_state.rb +47 -0
- data/lib/vagrant-qubes/config.rb +32 -0
- data/lib/vagrant-qubes/errors.rb +20 -0
- data/lib/vagrant-qubes/plugin.rb +59 -0
- data/lib/vagrant-qubes/provider.rb +103 -0
- data/lib/vagrant-qubes/version.rb +6 -0
- data/locales/en.yml +55 -0
- data/qrexec-client-vm +1 -0
- data/vagrant-qubes.gemspec +33 -0
- metadata +88 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0f6142494a93149537680a6e20b96dc4b12e9f9d238047dca8ee7def967ba6e8
|
|
4
|
+
data.tar.gz: 298d52208e83ec1a0f08d9b327893506fa8f6e548e1f11d02205dd5fb5f59888
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7fade5c518b6d4373627986e9fadb73ba4a637eaec0fcb0798169e7925217ab6125b120434827727dcf94b79d67dee2da034af5263298b678772e4133cca66e6
|
|
7
|
+
data.tar.gz: f2d606de83270ac0235f2922660fd65b9ae0108fd3b8479a2631fa08bb06cdd63bc55845c42ac89e210c4883b7e6ece21699a6f77d9cc18a00ebff69e3dbeaf2
|
data/.gitignore
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
|
15
|
+
include:
|
|
16
|
+
|
|
17
|
+
* Using welcoming and inclusive language
|
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
|
19
|
+
* Gracefully accepting constructive criticism
|
|
20
|
+
* Focusing on what is best for the community
|
|
21
|
+
* Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior by participants include:
|
|
24
|
+
|
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
+
advances
|
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
+
* Public or private harassment
|
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
|
30
|
+
address, without explicit permission
|
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Our Responsibilities
|
|
35
|
+
|
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
+
response to any instances of unacceptable behavior.
|
|
39
|
+
|
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
+
threatening, offensive, or harmful.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
+
when an individual is representing the project or its community. Examples of
|
|
50
|
+
representing a project or community include using an official project e-mail
|
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
|
53
|
+
further defined and clarified by project maintainers.
|
|
54
|
+
|
|
55
|
+
## Enforcement
|
|
56
|
+
|
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
+
reported by contacting the project team at gp397@outlook.com. All
|
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
|
63
|
+
|
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
+
members of the project's leadership.
|
|
67
|
+
|
|
68
|
+
## Attribution
|
|
69
|
+
|
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
|
72
|
+
|
|
73
|
+
[homepage]: https://contributor-covenant.org
|
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
# Specify your gem's dependencies in vagrant-qubes.gemspec
|
|
4
|
+
# gemspec
|
|
5
|
+
|
|
6
|
+
group :development do
|
|
7
|
+
gem "vagrant", git: "https://github.com/hashicorp/vagrant.git"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
group :plugins do
|
|
11
|
+
gem "vagrant-qubes", path: "."
|
|
12
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: https://github.com/hashicorp/vagrant.git
|
|
3
|
+
revision: 22795b161bf67a4c0ebbe32c9ce8777cb888c4a7
|
|
4
|
+
specs:
|
|
5
|
+
vagrant (2.2.11.dev)
|
|
6
|
+
bcrypt_pbkdf (~> 1.0.0)
|
|
7
|
+
childprocess (~> 4.0.0)
|
|
8
|
+
ed25519 (~> 1.2.4)
|
|
9
|
+
erubi
|
|
10
|
+
hashicorp-checkpoint (~> 0.1.5)
|
|
11
|
+
i18n (~> 1.8)
|
|
12
|
+
listen (~> 3.1)
|
|
13
|
+
log4r (~> 1.1.9, < 1.1.11)
|
|
14
|
+
mime (~> 0.4.4)
|
|
15
|
+
net-scp (~> 1.2.0)
|
|
16
|
+
net-sftp (~> 3.0)
|
|
17
|
+
net-ssh (~> 6.0)
|
|
18
|
+
rb-kqueue (~> 0.2.0)
|
|
19
|
+
rest-client (>= 1.6.0, < 3.0)
|
|
20
|
+
ruby_dep (<= 1.3.1)
|
|
21
|
+
rubyzip (~> 2.0)
|
|
22
|
+
vagrant_cloud (~> 2.0.3)
|
|
23
|
+
wdm (~> 0.1.0)
|
|
24
|
+
winrm (>= 2.3.4, < 3.0)
|
|
25
|
+
winrm-elevated (>= 1.2.1, < 2.0)
|
|
26
|
+
winrm-fs (>= 1.3.4, < 2.0)
|
|
27
|
+
|
|
28
|
+
PATH
|
|
29
|
+
remote: .
|
|
30
|
+
specs:
|
|
31
|
+
vagrant-qubes (0.0.1)
|
|
32
|
+
log4r (~> 1.1)
|
|
33
|
+
|
|
34
|
+
GEM
|
|
35
|
+
remote: https://rubygems.org/
|
|
36
|
+
specs:
|
|
37
|
+
bcrypt_pbkdf (1.0.1)
|
|
38
|
+
builder (3.2.4)
|
|
39
|
+
childprocess (4.0.0)
|
|
40
|
+
concurrent-ruby (1.1.9)
|
|
41
|
+
domain_name (0.5.20190701)
|
|
42
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
43
|
+
ed25519 (1.2.4)
|
|
44
|
+
erubi (1.10.0)
|
|
45
|
+
ffi (1.15.3)
|
|
46
|
+
gssapi (1.3.1)
|
|
47
|
+
ffi (>= 1.0.1)
|
|
48
|
+
gyoku (1.3.1)
|
|
49
|
+
builder (>= 2.1.2)
|
|
50
|
+
hashicorp-checkpoint (0.1.5)
|
|
51
|
+
http-cookie (1.0.4)
|
|
52
|
+
domain_name (~> 0.5)
|
|
53
|
+
httpclient (2.8.3)
|
|
54
|
+
i18n (1.8.10)
|
|
55
|
+
concurrent-ruby (~> 1.0)
|
|
56
|
+
listen (3.5.1)
|
|
57
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
58
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
|
59
|
+
little-plugger (1.1.4)
|
|
60
|
+
log4r (1.1.10)
|
|
61
|
+
logging (2.3.0)
|
|
62
|
+
little-plugger (~> 1.1)
|
|
63
|
+
multi_json (~> 1.14)
|
|
64
|
+
mime (0.4.4)
|
|
65
|
+
mime-types (3.3.1)
|
|
66
|
+
mime-types-data (~> 3.2015)
|
|
67
|
+
mime-types-data (3.2021.0225)
|
|
68
|
+
multi_json (1.15.0)
|
|
69
|
+
net-scp (1.2.1)
|
|
70
|
+
net-ssh (>= 2.6.5)
|
|
71
|
+
net-sftp (3.0.0)
|
|
72
|
+
net-ssh (>= 5.0.0, < 7.0.0)
|
|
73
|
+
net-ssh (6.1.0)
|
|
74
|
+
netrc (0.11.0)
|
|
75
|
+
nori (2.6.0)
|
|
76
|
+
rb-fsevent (0.11.0)
|
|
77
|
+
rb-inotify (0.10.1)
|
|
78
|
+
ffi (~> 1.0)
|
|
79
|
+
rb-kqueue (0.2.6)
|
|
80
|
+
ffi (>= 0.5.0)
|
|
81
|
+
rest-client (2.0.2)
|
|
82
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
83
|
+
mime-types (>= 1.16, < 4.0)
|
|
84
|
+
netrc (~> 0.8)
|
|
85
|
+
ruby_dep (1.3.1)
|
|
86
|
+
rubyntlm (0.6.3)
|
|
87
|
+
rubyzip (2.3.0)
|
|
88
|
+
unf (0.1.4)
|
|
89
|
+
unf_ext
|
|
90
|
+
unf_ext (0.0.7.7)
|
|
91
|
+
vagrant_cloud (2.0.3)
|
|
92
|
+
rest-client (~> 2.0.2)
|
|
93
|
+
wdm (0.1.1)
|
|
94
|
+
winrm (2.3.6)
|
|
95
|
+
builder (>= 2.1.2)
|
|
96
|
+
erubi (~> 1.8)
|
|
97
|
+
gssapi (~> 1.2)
|
|
98
|
+
gyoku (~> 1.0)
|
|
99
|
+
httpclient (~> 2.2, >= 2.2.0.2)
|
|
100
|
+
logging (>= 1.6.1, < 3.0)
|
|
101
|
+
nori (~> 2.0)
|
|
102
|
+
rubyntlm (~> 0.6.0, >= 0.6.3)
|
|
103
|
+
winrm-elevated (1.2.3)
|
|
104
|
+
erubi (~> 1.8)
|
|
105
|
+
winrm (~> 2.0)
|
|
106
|
+
winrm-fs (~> 1.0)
|
|
107
|
+
winrm-fs (1.3.5)
|
|
108
|
+
erubi (~> 1.8)
|
|
109
|
+
logging (>= 1.6.1, < 3.0)
|
|
110
|
+
rubyzip (~> 2.0)
|
|
111
|
+
winrm (~> 2.0)
|
|
112
|
+
|
|
113
|
+
PLATFORMS
|
|
114
|
+
ruby
|
|
115
|
+
|
|
116
|
+
DEPENDENCIES
|
|
117
|
+
vagrant!
|
|
118
|
+
vagrant-qubes!
|
|
119
|
+
|
|
120
|
+
BUNDLED WITH
|
|
121
|
+
2.1.4
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Gary Pentland
|
|
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,71 @@
|
|
|
1
|
+
# Vagrant::Qubes
|
|
2
|
+
|
|
3
|
+
This is a vagrant provider for qubes.
|
|
4
|
+
|
|
5
|
+
If you don't know what qubes is, this is probably not somehting that you will want to experiment with yet.
|
|
6
|
+
|
|
7
|
+
The structure, and large chunks of code in here have been inspired by (and in some cases copied from) Jonathan Senkerik's ESXi plugin "vagrant-vmware-esxi" https://github.com/josenk/vagrant-vmware-esxi without the help of that I wouldn't have been able to put this together.
|
|
8
|
+
|
|
9
|
+
Right now, this should be considered alpha at best, basic "up" and "destroy" works for a minimally configured AppVM based on a Vagrantfile along these lines
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
vms = {
|
|
13
|
+
"test1" => ["AppVM","red","fedora-33", 2, 2048, "sys-firewall"],
|
|
14
|
+
"test2" => ["AppVM","red","fedora-33", 2, 2048, "sys-firewall"],
|
|
15
|
+
"test3" => ["AppVM","red","fedora-33", 2, 2048, "sys-firewall"],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Vagrant.configure("2") do |config|
|
|
19
|
+
vms.each do | (name, cfg) |
|
|
20
|
+
type, label, template, numvcpus, memory, network = cfg
|
|
21
|
+
|
|
22
|
+
config.vm.define name do |machine|
|
|
23
|
+
machine.vm.box = "box"
|
|
24
|
+
machine.vm.hostname = name
|
|
25
|
+
machine.vm.provider :vagrant_qubes do |qubes|
|
|
26
|
+
qubes.guest_type = type
|
|
27
|
+
qubes.guest_label = label
|
|
28
|
+
qubes.guest_template = template
|
|
29
|
+
qubes.guest_netvm = network
|
|
30
|
+
qubes.guest_memsize = memory
|
|
31
|
+
qubes.guest_numvcpus = numvcpus
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
Add this line to your application's Gemfile:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
gem 'vagrant-qubes'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
And then execute:
|
|
47
|
+
|
|
48
|
+
$ bundle install
|
|
49
|
+
|
|
50
|
+
Or install it yourself as:
|
|
51
|
+
|
|
52
|
+
$ gem install vagrant-qubes
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
TODO: Write usage instructions here
|
|
57
|
+
|
|
58
|
+
## Development
|
|
59
|
+
|
|
60
|
+
## Contributing
|
|
61
|
+
|
|
62
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gp397/vagrant-qubes. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/gp397/vagrant-qubes/blob/master/CODE_OF_CONDUCT.md).
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
68
|
+
|
|
69
|
+
## Code of Conduct
|
|
70
|
+
|
|
71
|
+
Everyone interacting in the Vagrant::Qubes project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gp397/vagrant-qubes/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "vagrant/qubes"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'vagrant-qubes/plugin'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
lib_path = Pathname.new(File.expand_path('../vagrant-qubes', __FILE__))
|
|
7
|
+
autoload :Action, lib_path.join('action')
|
|
8
|
+
autoload :Errors, lib_path.join('errors')
|
|
9
|
+
|
|
10
|
+
def self.source_root
|
|
11
|
+
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'vagrant/action/builder'
|
|
2
|
+
|
|
3
|
+
module VagrantPlugins
|
|
4
|
+
module Qubes
|
|
5
|
+
# actions and how to run them
|
|
6
|
+
module Action
|
|
7
|
+
include Vagrant::Action::Builtin
|
|
8
|
+
|
|
9
|
+
def self.action_read_state
|
|
10
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
11
|
+
b.use ReadState
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.action_address
|
|
16
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
17
|
+
b.use Address, false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.action_address_multi
|
|
22
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
23
|
+
b.use Address, true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.action_read_ssh_info
|
|
28
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
29
|
+
b.use ReadSSHInfo
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.action_up
|
|
34
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
35
|
+
b.use ConfigValidate
|
|
36
|
+
# b.use HandleBox - This downloads the "box"
|
|
37
|
+
b.use ReadState
|
|
38
|
+
b.use CreateVM
|
|
39
|
+
b.use ReadState
|
|
40
|
+
b.use Boot
|
|
41
|
+
b.use Call, WaitForState, :running, 240 do |env1, b1|
|
|
42
|
+
if env1[:result] == 'True'
|
|
43
|
+
b1.use action_provision
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.action_provision
|
|
50
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
51
|
+
b.use ReadState
|
|
52
|
+
b.use Call, WaitForState, :running, 240 do |env1, b1|
|
|
53
|
+
if env1[:result] == 'True'
|
|
54
|
+
b1.use ReadState
|
|
55
|
+
#b1.use Provision
|
|
56
|
+
#b1.use SyncedFolderCleanup
|
|
57
|
+
#b1.use SyncedFolders
|
|
58
|
+
#b1.use SetHostname
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.action_destroy
|
|
65
|
+
Vagrant::Action::Builder.new.tap do |b|
|
|
66
|
+
b.use Call, ReadState do |env1, b1|
|
|
67
|
+
b1.use ReadState
|
|
68
|
+
if env1[:machine_state].to_s == 'not_created'
|
|
69
|
+
env1[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
70
|
+
message: 'Not destroying VM in state ' + env1[:machine_state].to_s)
|
|
71
|
+
else
|
|
72
|
+
b1.use Halt unless env1[:machine_state] == 'halted'
|
|
73
|
+
b1.use ReadState
|
|
74
|
+
b1.use Call, WaitForState, :halted, 240 do |env2, b2|
|
|
75
|
+
b2.use ReadState
|
|
76
|
+
if env2[:result] == 'True'
|
|
77
|
+
b2.use Destroy
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
action_root = Pathname.new(File.expand_path('../action', __FILE__))
|
|
86
|
+
autoload :Boot, action_root.join('boot')
|
|
87
|
+
autoload :CreateVM, action_root.join('createvm')
|
|
88
|
+
autoload :ReadState, action_root.join('read_state')
|
|
89
|
+
autoload :WaitForState, action_root.join('wait_for_state')
|
|
90
|
+
autoload :Address, action_root.join('address')
|
|
91
|
+
autoload :ReadSSHInfo, action_root.join('read_ssh_info')
|
|
92
|
+
autoload :Halt, action_root.join('halt')
|
|
93
|
+
autoload :Destroy, action_root.join('destroy')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
|
|
3
|
+
module VagrantPlugins
|
|
4
|
+
module Qubes
|
|
5
|
+
module Action
|
|
6
|
+
class Address
|
|
7
|
+
def initialize(app, _env, multi)
|
|
8
|
+
@app = app
|
|
9
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::address')
|
|
10
|
+
@multi = multi
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
address(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def address(env)
|
|
19
|
+
@logger.info('vagrant-qubes, address: start...')
|
|
20
|
+
|
|
21
|
+
# Get config.
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
# return nil if machine is down.
|
|
26
|
+
return nil if machine.state.id != :running
|
|
27
|
+
|
|
28
|
+
ssh_info = machine.ssh_info
|
|
29
|
+
return nil if !ssh_info
|
|
30
|
+
|
|
31
|
+
if @multi == true
|
|
32
|
+
env[:ui].info ssh_info[:host]
|
|
33
|
+
else
|
|
34
|
+
env[:ui].info ssh_info[:host]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class Boot
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::boot')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
boot(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def boot(env)
|
|
19
|
+
@logger.info('vagrant-qubes, boot: start...')
|
|
20
|
+
|
|
21
|
+
# Get config
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
@logger.info("vagrant-qubes, boot: machine id: #{machine.id}")
|
|
26
|
+
@logger.info('vagrant-qubes, boot: current state: '\
|
|
27
|
+
"#{env[:machine_state]}")
|
|
28
|
+
|
|
29
|
+
if env[:machine_state].to_s == 'running'
|
|
30
|
+
env[:ui].info I18n.t('vagrant_qubes.already_running')
|
|
31
|
+
elsif env[:machine_state].to_s == 'not_created'
|
|
32
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
33
|
+
message: 'Cannot boot in state' + env[:machine_state].to_s)
|
|
34
|
+
else
|
|
35
|
+
command = 'qrexec-client-vm dom0 vagrant_start+' + env[:machine].config.vm.hostname
|
|
36
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
37
|
+
if status != 0
|
|
38
|
+
raise Errors::QRExecError,
|
|
39
|
+
message: 'qrexec failed with status' + status.to_s
|
|
40
|
+
end
|
|
41
|
+
env[:ui].info I18n.t('vagrant_qubes.states.running.long')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class CreateVM
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::createvm')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
createvm(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def createvm(env)
|
|
19
|
+
@logger.info('vagrant-qubes, createvm: start...')
|
|
20
|
+
|
|
21
|
+
# Get config
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
if env[:machine_state].to_s == 'not_created'
|
|
26
|
+
env[:ui].info I18n.t('vagrant_qubes.vmbuild_not_done')
|
|
27
|
+
else
|
|
28
|
+
env[:ui].info I18n.t('vagrant_qubes.vmbuild_already_done')
|
|
29
|
+
return
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Do some config validation
|
|
33
|
+
if env[:machine].config.vm.hostname.nil?
|
|
34
|
+
raise Errors::GeneralError,
|
|
35
|
+
message: 'Hostname is not set, fix Vagrantfile'
|
|
36
|
+
return
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if config.guest_type.is_a? String
|
|
40
|
+
case config.guest_type
|
|
41
|
+
when 'AppVM'
|
|
42
|
+
command = 'echo "' + config.guest_type\
|
|
43
|
+
+ ' ' + config.guest_label\
|
|
44
|
+
+ ' ' + config.guest_template\
|
|
45
|
+
+ ' ' + config.guest_numvcpus.to_s\
|
|
46
|
+
+ ' ' + config.guest_memsize.to_s\
|
|
47
|
+
+ ' ' + config.guest_netvm\
|
|
48
|
+
+ '"| qrexec-client-vm dom0 vagrant_create+' + env[:machine].config.vm.hostname
|
|
49
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
50
|
+
if status != 0
|
|
51
|
+
raise Errors::QRExecError,
|
|
52
|
+
message: 'qrexec failed with status' + status.to_s
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
raise Errors::GeneralError,
|
|
56
|
+
message: 'guest type ' + config.guest_type + ' is not supported'
|
|
57
|
+
return
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
raise Errors::GeneralError,
|
|
61
|
+
message: 'Type is not a string, fix Vagrantfile'
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class Destroy
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::destroy')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
destroy(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def destroy(env)
|
|
19
|
+
@logger.info('vagrant-qubes, destroy: start...')
|
|
20
|
+
|
|
21
|
+
# Get config
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
@logger.info("vagrant-qubes, destroy: machine id: #{machine.id}")
|
|
26
|
+
@logger.info('vagrant-qubes, destroy: current state: '\
|
|
27
|
+
"#{env[:machine_state]}")
|
|
28
|
+
|
|
29
|
+
if env[:machine_state].to_s == 'not_created'
|
|
30
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
31
|
+
message: 'Cannot destroy in state ' + env[:machine_state].to_s)
|
|
32
|
+
elsif env[:machine_state].to_s != 'halted'
|
|
33
|
+
raise Errors::GeneralError,
|
|
34
|
+
message: 'VM should have been halted before destroy'
|
|
35
|
+
else
|
|
36
|
+
command = 'qrexec-client-vm dom0 vagrant_destroy+' + env[:machine].config.vm.hostname
|
|
37
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
38
|
+
if status != 0
|
|
39
|
+
raise Errors::QRExecError,
|
|
40
|
+
message: 'qrexec failed with status' + status.to_s
|
|
41
|
+
end
|
|
42
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
43
|
+
message: env[:machine].config.vm.hostname + ' Removed')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class Halt
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::halt')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
halt(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def halt(env)
|
|
19
|
+
@logger.info('vagrant-qubes, halt: start...')
|
|
20
|
+
|
|
21
|
+
# Get config
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
@logger.info("vagrant-qubes, halt: machine id: #{machine.id}")
|
|
26
|
+
@logger.info('vagrant-qubes, halt: current state: '\
|
|
27
|
+
"#{env[:machine_state]}")
|
|
28
|
+
|
|
29
|
+
if env[:machine_state].to_s == 'halted'
|
|
30
|
+
env[:ui].info I18n.t('vagrant_qubes.already_halted')
|
|
31
|
+
elsif env[:machine_state].to_s == 'not_created'
|
|
32
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
33
|
+
message: 'Cannot halt in state ' + env[:machine_state].to_s)
|
|
34
|
+
else
|
|
35
|
+
command = 'qrexec-client-vm dom0 vagrant_stop+' + env[:machine].config.vm.hostname
|
|
36
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
37
|
+
if status != 0
|
|
38
|
+
raise Errors::QRExecError,
|
|
39
|
+
message: 'qrexec failed with status' + status.to_s
|
|
40
|
+
end
|
|
41
|
+
env[:ui].info I18n.t('vagrant_qubes.states.halted.long')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class ReadSSHInfo
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::read_ssh_info')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
env[:machine_ssh_info] = read_ssh_info(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def read_ssh_info(env)
|
|
19
|
+
@logger.info('vagrant-qubes, read_ssh_info: start...')
|
|
20
|
+
|
|
21
|
+
# Get config.
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
# return nil if machine.id.nil?
|
|
26
|
+
|
|
27
|
+
# most of the time, state will be nil. But that's OK, we need to
|
|
28
|
+
# continue to read_ssh_info...
|
|
29
|
+
if (env[:machine_state].to_s == 'not_created' ||
|
|
30
|
+
env[:machine_state].to_s == 'halted' )
|
|
31
|
+
config.saved_ipaddress = nil
|
|
32
|
+
return nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@logger.info("vagrant-qubes, read_ssh_info: machine id: #{machine.id}")
|
|
36
|
+
@logger.info('vagrant-qubes, read_ssh_info: current state:'\
|
|
37
|
+
" #{env[:machine_state]}")
|
|
38
|
+
|
|
39
|
+
if config.saved_ipaddress.nil? or config.local_use_ip_cache == 'False'
|
|
40
|
+
# Figure out vm_ipaddress
|
|
41
|
+
|
|
42
|
+
command = 'qrexec-client-vm dom0 vagrant_list+' + env[:machine].config.vm.hostname
|
|
43
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
44
|
+
|
|
45
|
+
fields = stdout.split('|')
|
|
46
|
+
ipaddress = fields.at(3).to_s
|
|
47
|
+
|
|
48
|
+
# env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
49
|
+
# message: 'address ' + ipaddress)
|
|
50
|
+
|
|
51
|
+
return nil if (ipaddress == '')
|
|
52
|
+
|
|
53
|
+
config.saved_ipaddress = ipaddress
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
host: ipaddress,
|
|
57
|
+
port: 22
|
|
58
|
+
}
|
|
59
|
+
else
|
|
60
|
+
env[:ui].info "Using cached guest IP address"
|
|
61
|
+
ipaddress = config.saved_ipaddress
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
host: ipaddress,
|
|
65
|
+
port: 22
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class ReadState
|
|
8
|
+
def initialize(app, _env)
|
|
9
|
+
@app = app
|
|
10
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::read_state')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
env[:machine_state] = read_state(env)
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def read_state(env)
|
|
19
|
+
@logger.info('vagrant-qubes, read_state: start...')
|
|
20
|
+
|
|
21
|
+
# Get config.
|
|
22
|
+
machine = env[:machine]
|
|
23
|
+
config = env[:machine].provider_config
|
|
24
|
+
|
|
25
|
+
#return :not_created if machine.id.to_i < 1
|
|
26
|
+
|
|
27
|
+
state = ''
|
|
28
|
+
|
|
29
|
+
command = 'qrexec-client-vm dom0 vagrant_list+' + env[:machine].config.vm.hostname
|
|
30
|
+
# env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
31
|
+
# message: command)
|
|
32
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
33
|
+
stdout.each_line do |line|
|
|
34
|
+
fields = line.split('|')
|
|
35
|
+
state = fields.at(1)
|
|
36
|
+
# env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
37
|
+
# message: 'state ' + state)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
case state
|
|
41
|
+
when 'Running'
|
|
42
|
+
return :running
|
|
43
|
+
when 'Halted'
|
|
44
|
+
return :halted
|
|
45
|
+
when 'Transient'
|
|
46
|
+
return :transient
|
|
47
|
+
else
|
|
48
|
+
return :not_created
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'timeout'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
module Action
|
|
7
|
+
class WaitForState
|
|
8
|
+
# env[:result] will be false in case of timeout.
|
|
9
|
+
# @param [Symbol] state Target machine state.
|
|
10
|
+
# @param [Number] timeout Timeout in seconds.
|
|
11
|
+
def initialize(app, _env, state, timeout)
|
|
12
|
+
@app = app
|
|
13
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::wait_for_state')
|
|
14
|
+
@state = state
|
|
15
|
+
@timeout = timeout
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call(env)
|
|
19
|
+
env[:result] = 'True'
|
|
20
|
+
if env[:machine].state.id != @state
|
|
21
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
22
|
+
message: "Waiting for state \"#{@state}\"")
|
|
23
|
+
begin
|
|
24
|
+
Timeout.timeout(@timeout) do
|
|
25
|
+
until env[:machine].state.id == @state
|
|
26
|
+
sleep 4
|
|
27
|
+
end
|
|
28
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
29
|
+
message: "Success, state is now \"#{@state}\"")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
rescue Timeout::Error
|
|
33
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
34
|
+
message: "Timeout waiting for \"#{@state}\"")
|
|
35
|
+
env[:result] = 'False' # couldn't reach state in time
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
env[:ui].info I18n.t('vagrant_qubes.vagrant_qubes_message',
|
|
39
|
+
message: "Success, state is now \"#{@state}\"")
|
|
40
|
+
end
|
|
41
|
+
env[:machine].provider_config.saved_ipaddress = nil
|
|
42
|
+
@app.call(env)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Config
|
|
2
|
+
|
|
3
|
+
module VagrantPlugins
|
|
4
|
+
module Qubes
|
|
5
|
+
# Config class
|
|
6
|
+
class Config < Vagrant.plugin('2', :config)
|
|
7
|
+
attr_accessor :debug
|
|
8
|
+
attr_accessor :guest_type
|
|
9
|
+
attr_accessor :guest_label
|
|
10
|
+
attr_accessor :guest_template
|
|
11
|
+
attr_accessor :guest_numvcpus
|
|
12
|
+
attr_accessor :guest_memsize
|
|
13
|
+
attr_accessor :guest_netvm
|
|
14
|
+
attr_accessor :saved_ipaddress
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@debug = 'False'
|
|
18
|
+
@local_use_ip_cache = 'True'
|
|
19
|
+
@saved_ipaddress = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def finalize!
|
|
23
|
+
if @local_use_ip_cache =~ /false/i
|
|
24
|
+
@local_use_ip_cache = 'False'
|
|
25
|
+
else
|
|
26
|
+
@local_use_ip_cache = 'True'
|
|
27
|
+
end
|
|
28
|
+
@saved_ipaddress = nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'vagrant'
|
|
2
|
+
|
|
3
|
+
module VagrantPlugins
|
|
4
|
+
module Qubes
|
|
5
|
+
module Errors
|
|
6
|
+
class QubesErrors < Vagrant::Errors::VagrantError
|
|
7
|
+
error_namespace('vagrant_qubes.errors')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class QRExecError < QubesErrors
|
|
11
|
+
error_key(:qrexec_error)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class GeneralError < QubesErrors
|
|
15
|
+
error_key(:general_error)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module VagrantPlugins
|
|
2
|
+
module Qubes
|
|
3
|
+
class Plugin < Vagrant.plugin('2')
|
|
4
|
+
name 'vagrant-qubes'
|
|
5
|
+
description 'Vagrant Qubes provider plugin'
|
|
6
|
+
config(:vagrant_qubes, :provider) do
|
|
7
|
+
require_relative 'config'
|
|
8
|
+
Config
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
provider(
|
|
12
|
+
:vagrant_qubes,
|
|
13
|
+
box_format: %w(qubes),
|
|
14
|
+
parallel: true
|
|
15
|
+
) do
|
|
16
|
+
setup_logging
|
|
17
|
+
setup_i18n
|
|
18
|
+
|
|
19
|
+
require_relative 'provider'
|
|
20
|
+
Provider
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# This initializes the internationalization strings.
|
|
24
|
+
def self.setup_i18n
|
|
25
|
+
require 'pathname'
|
|
26
|
+
I18n.load_path << File.expand_path('locales/en.yml', Qubes.source_root)
|
|
27
|
+
I18n.reload!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
|
31
|
+
def self.setup_logging
|
|
32
|
+
require 'log4r'
|
|
33
|
+
level = nil
|
|
34
|
+
begin
|
|
35
|
+
level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
|
|
36
|
+
rescue NameError
|
|
37
|
+
# This means that the logging constant wasn't found,
|
|
38
|
+
# which is fine. We just keep `level` as `nil`. But
|
|
39
|
+
# we tell the user.
|
|
40
|
+
level = nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Some constants, such as "true" resolve to booleans, so the
|
|
44
|
+
# above error checking doesn't catch it. This will check to make
|
|
45
|
+
# sure that the log level is an integer, as Log4r requires.
|
|
46
|
+
level = nil unless level.is_a?(Integer)
|
|
47
|
+
|
|
48
|
+
# Set the logging level on all "vagrant" namespaced
|
|
49
|
+
# logs as long as we have a valid level.
|
|
50
|
+
if level
|
|
51
|
+
logger = Log4r::Logger.new('vagrant_qubes')
|
|
52
|
+
logger.outputters = Log4r::Outputter.stderr
|
|
53
|
+
logger.level = level
|
|
54
|
+
logger = nil
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'vagrant'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Qubes
|
|
6
|
+
# Provider class
|
|
7
|
+
class Provider < Vagrant.plugin('2', :provider)
|
|
8
|
+
# @param [Boolean] raise_error If true, raise exception if not usable.
|
|
9
|
+
# @return [Boolean]
|
|
10
|
+
def self.usable?(raise_error=false)
|
|
11
|
+
# Return true by default for backwards compat since this was
|
|
12
|
+
# introduced long after providers were being written.
|
|
13
|
+
true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# If Environment.can_install_provider? returns false, then an error
|
|
17
|
+
# will be shown to the user.
|
|
18
|
+
def self.installed?
|
|
19
|
+
# By default return true for backwards compat so all providers
|
|
20
|
+
# continue to work.
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param [Vagrant::Machine] machine The machine that this provider
|
|
25
|
+
# is responsible for.
|
|
26
|
+
def initialize(machine)
|
|
27
|
+
@machine = machine
|
|
28
|
+
@logger = Log4r::Logger.new('vagrant_qubes::action::provider')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param [Symbol] name Name of the action.
|
|
32
|
+
# @return [Object] A callable action sequence object, whether it
|
|
33
|
+
# is a proc, object, etc.
|
|
34
|
+
def action(name)
|
|
35
|
+
method = "action_#{name}"
|
|
36
|
+
if Action.respond_to? method
|
|
37
|
+
Action.send(method)
|
|
38
|
+
else
|
|
39
|
+
# the specified action is not supported
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# This method is called if the underlying machine ID changes. Providers
|
|
45
|
+
# can use this method to load in new data for the actual backing
|
|
46
|
+
# machine or to realize that the machine is now gone (the ID can
|
|
47
|
+
# become `nil`). No parameters are given, since the underlying machine
|
|
48
|
+
# is simply the machine instance given to this object. And no
|
|
49
|
+
# return value is necessary.
|
|
50
|
+
def machine_id_changed
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# This should return a hash of information that explains how to
|
|
54
|
+
# SSH into the machine. If the machine is not at a point where
|
|
55
|
+
# SSH is even possible, then `nil` should be returned.
|
|
56
|
+
#
|
|
57
|
+
# The general structure of this returned hash should be the
|
|
58
|
+
# following:
|
|
59
|
+
#
|
|
60
|
+
# {
|
|
61
|
+
# host: "1.2.3.4",
|
|
62
|
+
# port: "22",
|
|
63
|
+
# username: "mitchellh",
|
|
64
|
+
# private_key_path: "/path/to/my/key"
|
|
65
|
+
# }
|
|
66
|
+
#
|
|
67
|
+
# **Note:** Vagrant only supports private key based authentication,
|
|
68
|
+
# mainly for the reason that there is no easy way to exec into an
|
|
69
|
+
# `ssh` prompt with a password, whereas we can pass a private key
|
|
70
|
+
# via commandline.
|
|
71
|
+
#
|
|
72
|
+
# @return [Hash] SSH information. For the structure of this hash
|
|
73
|
+
# read the accompanying documentation for this method.
|
|
74
|
+
def ssh_info
|
|
75
|
+
env = @machine.action('read_ssh_info')
|
|
76
|
+
env[:machine_ssh_info]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# This should return the state of the machine within this provider.
|
|
80
|
+
# The state must be an instance of {MachineState}. Please read the
|
|
81
|
+
# documentation of that class for more information.
|
|
82
|
+
#
|
|
83
|
+
# @return [MachineState]
|
|
84
|
+
def state
|
|
85
|
+
env = @machine.action('read_state')
|
|
86
|
+
state_id = env[:machine_state]
|
|
87
|
+
|
|
88
|
+
@logger.info("vagrant-qubes, boot: state_id: #{env[:state_id]}")
|
|
89
|
+
|
|
90
|
+
short = I18n.t("vagrant_qubes.states.#{state_id}.short")
|
|
91
|
+
long = I18n.t("vagrant_qubes.states.#{state_id}.long")
|
|
92
|
+
|
|
93
|
+
# If we're not created, then specify the special ID flag
|
|
94
|
+
if state_id == :not_created
|
|
95
|
+
state_id = Vagrant::MachineState::NOT_CREATED_ID
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Return the MachineState object
|
|
99
|
+
Vagrant::MachineState.new(state_id, short, long)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/locales/en.yml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
en:
|
|
2
|
+
vagrant_qubes:
|
|
3
|
+
support: |-
|
|
4
|
+
-----------------------:----------------------
|
|
5
|
+
Please buy me beer if you meet me
|
|
6
|
+
-----------------------:----------------------
|
|
7
|
+
Author : Gary Pentland
|
|
8
|
+
errors:
|
|
9
|
+
general_error: |-
|
|
10
|
+
There was an error.
|
|
11
|
+
%{message}
|
|
12
|
+
qrexec_error: |-
|
|
13
|
+
There was an error executing qrexec - please configure qubes-rpc.
|
|
14
|
+
%{message}
|
|
15
|
+
vagrant_qubes_message: |-
|
|
16
|
+
--- %{message}
|
|
17
|
+
vmbuild_not_done: |-
|
|
18
|
+
Virtual Machine will be built.
|
|
19
|
+
vmbuild_already_done: |-
|
|
20
|
+
Virtual Machine is already built.
|
|
21
|
+
already_running: |-
|
|
22
|
+
The VM is already running.
|
|
23
|
+
already_halted: |-
|
|
24
|
+
The VM is already halted.
|
|
25
|
+
# already_suspended: |-
|
|
26
|
+
# The VM is already suspended.
|
|
27
|
+
# already_destroyed: |-
|
|
28
|
+
# The VM is destroyed.
|
|
29
|
+
# snapshot_saved: |-
|
|
30
|
+
# The snapshot has been saved.
|
|
31
|
+
# snapshot_deleted: |-
|
|
32
|
+
# The snapshot has been deleted.
|
|
33
|
+
# snapshot_restored: |-
|
|
34
|
+
# The snapshot has been restored.
|
|
35
|
+
states:
|
|
36
|
+
running:
|
|
37
|
+
short: |-
|
|
38
|
+
running
|
|
39
|
+
long: |-
|
|
40
|
+
The virtual machine is running.
|
|
41
|
+
halted:
|
|
42
|
+
short: |-
|
|
43
|
+
halted
|
|
44
|
+
long: |-
|
|
45
|
+
The virtual machine is halted.
|
|
46
|
+
transient:
|
|
47
|
+
short: |-
|
|
48
|
+
transient
|
|
49
|
+
long: |-
|
|
50
|
+
The virtual machine is transitioning between states.
|
|
51
|
+
not_created:
|
|
52
|
+
short: |-
|
|
53
|
+
not created
|
|
54
|
+
long: |-
|
|
55
|
+
No Virtual Machines are created.
|
data/qrexec-client-vm
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1 2 3 4 5 6 dom0 vagrant_create+test1
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# require_relative 'lib/vagrant-qubes/version'
|
|
2
|
+
require File.expand_path('../lib/vagrant-qubes/version', __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |spec|
|
|
5
|
+
spec.name = "vagrant-qubes"
|
|
6
|
+
spec.version = VagrantPlugins::Qubes::VERSION
|
|
7
|
+
spec.date = '2021-06-30'
|
|
8
|
+
spec.authors = ["Gary Pentland"]
|
|
9
|
+
spec.email = [""]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Vagrant Qubes provider plugin"
|
|
12
|
+
spec.description = "A plugin for vagrant to provision machines within a qubes environment"
|
|
13
|
+
spec.homepage = "https://github.com/gp397/vagrant-qubes"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
|
16
|
+
|
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
18
|
+
|
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
20
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
21
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
|
22
|
+
|
|
23
|
+
spec.add_runtime_dependency 'log4r', '~> 1.1'
|
|
24
|
+
|
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
27
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
29
|
+
end
|
|
30
|
+
spec.bindir = "exe"
|
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
32
|
+
spec.require_paths = ["lib"]
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vagrant-qubes
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Gary Pentland
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-06-30 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: log4r
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.1'
|
|
27
|
+
description: A plugin for vagrant to provision machines within a qubes environment
|
|
28
|
+
email:
|
|
29
|
+
- ''
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- ".gitignore"
|
|
35
|
+
- CODE_OF_CONDUCT.md
|
|
36
|
+
- Gemfile
|
|
37
|
+
- Gemfile.lock
|
|
38
|
+
- LICENSE.txt
|
|
39
|
+
- README.md
|
|
40
|
+
- Rakefile
|
|
41
|
+
- bin/console
|
|
42
|
+
- bin/setup
|
|
43
|
+
- lib/vagrant-qubes.rb
|
|
44
|
+
- lib/vagrant-qubes/action.rb
|
|
45
|
+
- lib/vagrant-qubes/action/address.rb
|
|
46
|
+
- lib/vagrant-qubes/action/boot.rb
|
|
47
|
+
- lib/vagrant-qubes/action/createvm.rb
|
|
48
|
+
- lib/vagrant-qubes/action/destroy.rb
|
|
49
|
+
- lib/vagrant-qubes/action/halt.rb
|
|
50
|
+
- lib/vagrant-qubes/action/read_ssh_info.rb
|
|
51
|
+
- lib/vagrant-qubes/action/read_state.rb
|
|
52
|
+
- lib/vagrant-qubes/action/wait_for_state.rb
|
|
53
|
+
- lib/vagrant-qubes/config.rb
|
|
54
|
+
- lib/vagrant-qubes/errors.rb
|
|
55
|
+
- lib/vagrant-qubes/plugin.rb
|
|
56
|
+
- lib/vagrant-qubes/provider.rb
|
|
57
|
+
- lib/vagrant-qubes/version.rb
|
|
58
|
+
- locales/en.yml
|
|
59
|
+
- qrexec-client-vm
|
|
60
|
+
- vagrant-qubes.gemspec
|
|
61
|
+
homepage: https://github.com/gp397/vagrant-qubes
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata:
|
|
65
|
+
allowed_push_host: https://rubygems.org
|
|
66
|
+
homepage_uri: https://github.com/gp397/vagrant-qubes
|
|
67
|
+
source_code_uri: https://github.com/gp397/vagrant-qubes
|
|
68
|
+
changelog_uri: https://github.com/gp397/vagrant-qubes
|
|
69
|
+
post_install_message:
|
|
70
|
+
rdoc_options: []
|
|
71
|
+
require_paths:
|
|
72
|
+
- lib
|
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 2.3.0
|
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
requirements: []
|
|
84
|
+
rubygems_version: 3.1.6
|
|
85
|
+
signing_key:
|
|
86
|
+
specification_version: 4
|
|
87
|
+
summary: Vagrant Qubes provider plugin
|
|
88
|
+
test_files: []
|