vagrant-smartos-zones 0.0.1.pre.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +12 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +268 -0
  7. data/Rakefile +6 -0
  8. data/Vagrantfile +29 -0
  9. data/examples/Vagrantfile +18 -0
  10. data/examples/Vagrantfile.chef_server +33 -0
  11. data/examples/Vagrantfile.lx +22 -0
  12. data/examples/Vagrantfile.rsync +23 -0
  13. data/files/gz_vnic/create_gz_vnic +15 -0
  14. data/files/smf/create-gz-vnic.xml +31 -0
  15. data/files/smf/zonegate.xml +34 -0
  16. data/files/zonegate/zonegate +60 -0
  17. data/files/zonegate/zonemon +15 -0
  18. data/files/zonegate/zonenat +153 -0
  19. data/lib/vagrant/smartos/locales/en.yml +41 -0
  20. data/lib/vagrant/smartos/zones/action/configure_zone_synced_folders.rb +53 -0
  21. data/lib/vagrant/smartos/zones/action/create_gz_vnic.rb +28 -0
  22. data/lib/vagrant/smartos/zones/action/forward_gz_ports.rb +46 -0
  23. data/lib/vagrant/smartos/zones/action/helper.rb +33 -0
  24. data/lib/vagrant/smartos/zones/action/imgadm_import.rb +24 -0
  25. data/lib/vagrant/smartos/zones/action/virtualbox/platform_iso.rb +57 -0
  26. data/lib/vagrant/smartos/zones/action/zone/create.rb +25 -0
  27. data/lib/vagrant/smartos/zones/action/zone/start.rb +25 -0
  28. data/lib/vagrant/smartos/zones/action/zone/stop.rb +25 -0
  29. data/lib/vagrant/smartos/zones/action/zone_gate/enable.rb +26 -0
  30. data/lib/vagrant/smartos/zones/action/zone_gate/install.rb +26 -0
  31. data/lib/vagrant/smartos/zones/action.rb +75 -0
  32. data/lib/vagrant/smartos/zones/cap/base.rb +29 -0
  33. data/lib/vagrant/smartos/zones/cap/create_gz_vnic.rb +45 -0
  34. data/lib/vagrant/smartos/zones/cap/imgadm_import.rb +30 -0
  35. data/lib/vagrant/smartos/zones/cap/platform_image/install.rb +17 -0
  36. data/lib/vagrant/smartos/zones/cap/platform_image/latest.rb +19 -0
  37. data/lib/vagrant/smartos/zones/cap/platform_image/list.rb +17 -0
  38. data/lib/vagrant/smartos/zones/cap/zone/base.rb +32 -0
  39. data/lib/vagrant/smartos/zones/cap/zone/create.rb +45 -0
  40. data/lib/vagrant/smartos/zones/cap/zone/start.rb +29 -0
  41. data/lib/vagrant/smartos/zones/cap/zone/stop.rb +29 -0
  42. data/lib/vagrant/smartos/zones/cap/zone_gate/enable.rb +20 -0
  43. data/lib/vagrant/smartos/zones/cap/zone_gate/install.rb +46 -0
  44. data/lib/vagrant/smartos/zones/commands/dataset.rb +91 -0
  45. data/lib/vagrant/smartos/zones/commands/global_zone.rb +43 -0
  46. data/lib/vagrant/smartos/zones/commands/multi_command.rb +46 -0
  47. data/lib/vagrant/smartos/zones/commands/smartos.rb +70 -0
  48. data/lib/vagrant/smartos/zones/commands/zlogin.rb +35 -0
  49. data/lib/vagrant/smartos/zones/commands/zones.rb +136 -0
  50. data/lib/vagrant/smartos/zones/communicator/smartos.rb +87 -0
  51. data/lib/vagrant/smartos/zones/config/global_zone.rb +26 -0
  52. data/lib/vagrant/smartos/zones/config/zone.rb +33 -0
  53. data/lib/vagrant/smartos/zones/errors.rb +9 -0
  54. data/lib/vagrant/smartos/zones/guest.rb +25 -0
  55. data/lib/vagrant/smartos/zones/hooks.rb +41 -0
  56. data/lib/vagrant/smartos/zones/models/dataset.rb +27 -0
  57. data/lib/vagrant/smartos/zones/models/snapshot.rb +71 -0
  58. data/lib/vagrant/smartos/zones/models/zone.rb +80 -0
  59. data/lib/vagrant/smartos/zones/models/zone_group.rb +11 -0
  60. data/lib/vagrant/smartos/zones/models/zone_user.rb +11 -0
  61. data/lib/vagrant/smartos/zones/plugin.rb +118 -0
  62. data/lib/vagrant/smartos/zones/util/checksum.rb +22 -0
  63. data/lib/vagrant/smartos/zones/util/downloader.rb +48 -0
  64. data/lib/vagrant/smartos/zones/util/global_zone/connection.rb +192 -0
  65. data/lib/vagrant/smartos/zones/util/global_zone/helper.rb +33 -0
  66. data/lib/vagrant/smartos/zones/util/global_zone/ssh_info.rb +85 -0
  67. data/lib/vagrant/smartos/zones/util/platform_images.rb +132 -0
  68. data/lib/vagrant/smartos/zones/util/public_key.rb +14 -0
  69. data/lib/vagrant/smartos/zones/util/snapshots.rb +63 -0
  70. data/lib/vagrant/smartos/zones/util/zone_group.rb +34 -0
  71. data/lib/vagrant/smartos/zones/util/zone_info.rb +72 -0
  72. data/lib/vagrant/smartos/zones/util/zone_json.rb +77 -0
  73. data/lib/vagrant/smartos/zones/util/zone_project.rb +25 -0
  74. data/lib/vagrant/smartos/zones/util/zone_user.rb +63 -0
  75. data/lib/vagrant/smartos/zones/version.rb +7 -0
  76. data/lib/vagrant/smartos/zones.rb +10 -0
  77. data/vagrant-smartos-zones.gemspec +24 -0
  78. metadata +163 -0
@@ -0,0 +1,22 @@
1
+ require 'digest/md5'
2
+
3
+ module Vagrant
4
+ module Smartos
5
+ module Zones
6
+ module Util
7
+ class Checksum
8
+ attr_reader :path, :checksum
9
+
10
+ def initialize(path, checksum)
11
+ @path = path
12
+ @checksum = checksum
13
+ end
14
+
15
+ def valid?
16
+ Digest::MD5.file(path) == checksum
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ module Vagrant
2
+ module Smartos
3
+ module Zones
4
+ module Util
5
+ class Downloader
6
+ attr_reader :url, :utility
7
+
8
+ GET_PARAMS = {
9
+ 'wget' => '-qO',
10
+ 'curl' => '--silent -o'
11
+ }
12
+
13
+ READ_PARAMS = {
14
+ 'wget' => '-qO-',
15
+ 'curl' => '--silent'
16
+ }
17
+
18
+ def initialize(url)
19
+ @url = url
20
+ @utility = download_utility
21
+ end
22
+
23
+ def self.get(url, path)
24
+ new(url).get(path)
25
+ end
26
+
27
+ def get(path)
28
+ `#{utility} #{url} #{GET_PARAMS[utility]} #{path}`
29
+ end
30
+
31
+ def read
32
+ `#{utility} #{url} #{READ_PARAMS[utility]}`
33
+ end
34
+
35
+ private
36
+
37
+ def download_utility
38
+ if system('which wget >/dev/null')
39
+ 'wget'
40
+ else
41
+ 'curl'
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,192 @@
1
+ require 'net/ssh'
2
+ require 'stringio'
3
+ require 'timeout'
4
+ require 'vagrant/util/retryable'
5
+ require 'vagrant/smartos/zones/util/global_zone/ssh_info'
6
+
7
+ module Vagrant
8
+ module Smartos
9
+ module Zones
10
+ module Util
11
+ module GlobalZone
12
+ class Connection < Struct.new(:machine, :logger)
13
+ include Vagrant::Util::Retryable
14
+
15
+ CONNECTION_TIMEOUT = 60
16
+
17
+ # These are the exceptions that we retry because they represent
18
+ # errors that are generally fixed from a retry and don't
19
+ # necessarily represent immediate failure cases.
20
+ RETRYABLE_EXCEPTIONS = [
21
+ Errno::EACCES,
22
+ Errno::EADDRINUSE,
23
+ Errno::ECONNREFUSED,
24
+ Errno::ECONNRESET,
25
+ Errno::ENETUNREACH,
26
+ Errno::EHOSTUNREACH,
27
+ Net::SSH::Disconnect,
28
+ Timeout::Error
29
+ ]
30
+
31
+ class ErrorHandler < Struct.new(:error)
32
+ ERROR_MAPPING = {
33
+ # This happens on connect() for unknown reasons yet...
34
+ Errno::EACCES => Vagrant::Errors::SSHConnectEACCES,
35
+ # This happens if we continued to timeout when attempting to connect.
36
+ Errno::ETIMEDOUT => Vagrant::Errors::SSHConnectionTimeout,
37
+ Timeout::Error => Vagrant::Errors::SSHConnectionTimeout,
38
+ # This happens if authentication failed. We wrap the error in our own exception.
39
+ Net::SSH::AuthenticationFailed => Vagrant::Errors::SSHAuthenticationFailed,
40
+ # This happens if the remote server unexpectedly closes the
41
+ # connection. This is usually raised when SSH is running on the
42
+ # other side but can't properly setup a connection. This is
43
+ # usually a server-side issue.
44
+ Net::SSH::Disconnect => Vagrant::Errors::SSHDisconnected,
45
+ # This is raised if we failed to connect the max amount of times
46
+ Errno::ECONNREFUSED => Vagrant::Errors::SSHConnectionRefused,
47
+ # This is raised if we failed to connect the max number of times
48
+ # due to an ECONNRESET.
49
+ Errno::ECONNRESET => Vagrant::Errors::SSHConnectionReset,
50
+ # This is raised if we get an ICMP DestinationUnknown error.
51
+ Errno::EHOSTDOWN => Vagrant::Errors::SSHHostDown,
52
+ # This is raised if we can't work out how to route traffic.
53
+ Errno::EHOSTUNREACH => Vagrant::Errors::SSHNoRoute,
54
+ # This is raised if a private key type that Net-SSH doesn't support
55
+ # is used. Show a nicer error.
56
+ NotImplementedError => Vagrant::Errors::SSHKeyTypeNotSupported
57
+ }.freeze
58
+
59
+ def handle!
60
+ error_class = ERROR_MAPPING[error.class]
61
+ raise error_class if error_class
62
+ end
63
+ end
64
+
65
+ class SSHLogger
66
+ attr_reader :logger
67
+
68
+ def initialize
69
+ @io = StringIO.new
70
+ @logger = Logger.new(@io)
71
+ end
72
+
73
+ def to_s
74
+ @io.string
75
+ end
76
+ end
77
+
78
+ def with_connection
79
+ connect
80
+ yield @connection if block_given?
81
+ end
82
+
83
+ # rubocop:disable Metrics/MethodLength
84
+ def connect(**opts)
85
+ return @connection if connection_valid?
86
+
87
+ validate_ssh_info!
88
+ check_ssh_key_permissions
89
+
90
+ # Default some options
91
+ opts[:retries] = 5 unless opts.key?(:retries)
92
+
93
+ # Connect to SSH, giving it a few tries
94
+ connection = nil
95
+ begin
96
+ logger.info('Attempting SSH connection...')
97
+ connection = retryable(tries: opts[:retries], on: RETRYABLE_EXCEPTIONS) do
98
+ Timeout.timeout(CONNECTION_TIMEOUT) do
99
+ begin
100
+ ssh_logger = SSHLogger.new
101
+
102
+ # Setup logging for connections
103
+ connect_opts = common_connect_opts.dup
104
+ connect_opts[:logger] = ssh_logger.logger
105
+
106
+ if ssh_info[:proxy_command]
107
+ connect_opts[:proxy] = Net::SSH::Proxy::Command.new(ssh_info[:proxy_command])
108
+ end
109
+
110
+ logger.info('Attempting to connect to SSH...')
111
+ logger.info(" - Host: #{ssh_info[:host]}")
112
+ logger.info(" - Port: #{ssh_info[:port]}")
113
+ logger.info(" - Username: #{ssh_info[:username]}")
114
+ logger.info(" - Password? #{uses_password?}")
115
+ logger.info(" - Key Path: #{ssh_info[:private_key_path]}")
116
+
117
+ Net::SSH.start(ssh_info[:host], ssh_info[:username], connect_opts)
118
+ ensure
119
+ # Make sure we output the connection log
120
+ logger.debug('== Net-SSH connection debug-level log START ==')
121
+ logger.debug(ssh_logger.to_s)
122
+ logger.debug('== Net-SSH connection debug-level log END ==')
123
+ end
124
+ end
125
+ end
126
+ rescue StandardError => e
127
+ ErrorHandler.new(e).handle!
128
+ end
129
+
130
+ @connection = connection
131
+ end
132
+
133
+ def ssh_info
134
+ @ssh_info ||= Util::GlobalZone::SSHInfo.new(machine.provider, machine.config, machine.env).to_hash
135
+ end
136
+
137
+ private
138
+
139
+ def check_ssh_key_permissions
140
+ ssh_info[:private_key_path].each do |path|
141
+ Vagrant::Util::SSH.check_key_permissions(Pathname.new(path))
142
+ end
143
+ end
144
+
145
+ def common_connect_opts
146
+ # Build the options we'll use to initiate the connection via Net::SSH
147
+ @common_connect_opts ||= {
148
+ auth_methods: %w(none publickey hostbased password),
149
+ config: false,
150
+ forward_agent: ssh_info[:forward_agent],
151
+ keys: ssh_info[:private_key_path],
152
+ keys_only: true,
153
+ paranoid: false,
154
+ password: ssh_info[:password],
155
+ port: ssh_info[:port],
156
+ timeout: 15,
157
+ user_known_hosts_file: [],
158
+ verbose: :debug
159
+ }
160
+ end
161
+
162
+ def connection_valid?
163
+ return false unless @connection
164
+ return false if @connection.closed?
165
+
166
+ # There is a chance that the socket is closed despite us checking
167
+ # 'closed?' above. To test this we need to send data through the
168
+ # socket.
169
+ begin
170
+ @connection.exec!('')
171
+ true
172
+ rescue StandardError => e
173
+ logger.info('Connection errored, not re-using. Will reconnect.')
174
+ logger.debug(e.inspect)
175
+ @connection = nil
176
+ false
177
+ end
178
+ end
179
+
180
+ def uses_password?
181
+ !!ssh_info[:password]
182
+ end
183
+
184
+ def validate_ssh_info!
185
+ raise Vagrant::Errors::SSHNotReady if ssh_info.nil?
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,33 @@
1
+ module Vagrant
2
+ module Smartos
3
+ module Zones
4
+ module Util
5
+ module GlobalZone
6
+ module Helper
7
+ def self.included(klass)
8
+ klass.send(:extend, ClassHelpers)
9
+ end
10
+
11
+ def sudo
12
+ machine.config.smartos.suexec_cmd
13
+ end
14
+
15
+ def with_gz(command, options = {})
16
+ machine.communicate.gz_execute(command, options) do |_type, output|
17
+ yield output if block_given?
18
+ end
19
+ end
20
+ end
21
+
22
+ module ClassHelpers
23
+ def with_gz(machine, command, options = {})
24
+ machine.communicate.gz_execute(command, options) do |_type, output|
25
+ yield output if block_given?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,85 @@
1
+ module Vagrant
2
+ module Smartos
3
+ module Zones
4
+ module Util
5
+ module GlobalZone
6
+ class SSHInfo < Struct.new(:provider, :config, :env)
7
+ def forward_agent
8
+ config.ssh.forward_agent
9
+ end
10
+
11
+ def forward_x11
12
+ config.ssh.forward_x11
13
+ end
14
+
15
+ def host
16
+ return config.ssh.host if config.ssh.host
17
+ return ssh_info[:host] if ssh_info[:host]
18
+ config.ssh.default.host
19
+ end
20
+
21
+ def password
22
+ config.ssh.password
23
+ end
24
+
25
+ def port
26
+ port_forward[2]
27
+ end
28
+
29
+ def private_key_paths
30
+ return [] if password
31
+
32
+ @paths ||= [].tap do |paths|
33
+ paths << config.ssh.private_key_path
34
+ paths << config.ssh.default.private_key_path
35
+ paths << env.default_private_key_path
36
+ end.compact.map do |path|
37
+ File.expand_path(path, env.root_path)
38
+ end
39
+ end
40
+
41
+ def proxy_command
42
+ config.ssh.proxy_command if config.ssh.proxy_command
43
+ end
44
+
45
+ def username
46
+ return config.ssh.password if config.ssh.password
47
+ return ssh_info[:username] if ssh_info[:username]
48
+ config.ssh.default.username
49
+ end
50
+
51
+ # rubocop:disable Metrics/MethodLength
52
+ def to_hash
53
+ # From machine#ssh_info, if provider ssh_info is nil,
54
+ # machine is not ready for SSH.
55
+ return nil if ssh_info.nil?
56
+
57
+ {
58
+ host: host,
59
+ port: port,
60
+ private_key_path: private_key_paths,
61
+ username: username,
62
+ password: password,
63
+ proxy_command: proxy_command,
64
+ forward_agent: forward_agent,
65
+ forward_x11: forward_x11
66
+ }.delete_if { |_k, v| v.nil? }
67
+ end
68
+
69
+ private
70
+
71
+ def ssh_info
72
+ @ssh_info ||= provider.ssh_info
73
+ end
74
+
75
+ def port_forward
76
+ @port_forward ||= provider.driver.read_forwarded_ports.find do |fw|
77
+ fw[1] == 'gz_ssh'
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,132 @@
1
+ require 'vagrant/smartos/zones/util/checksum'
2
+ require 'vagrant/smartos/zones/util/downloader'
3
+ require 'vagrant/util/downloader'
4
+
5
+ module Vagrant
6
+ module Smartos
7
+ module Zones
8
+ module Util
9
+ class PlatformImages
10
+ attr_reader :env, :image, :machine
11
+
12
+ def initialize(env, machine = nil)
13
+ @env = env
14
+ @machine = machine
15
+ setup_smartos_directories
16
+ end
17
+
18
+ def get_platform_image(image)
19
+ @image = image
20
+ @image = latest_remote_or_current_image if image == 'latest'
21
+ install(image)
22
+ platform_image_path
23
+ end
24
+
25
+ def install(image)
26
+ @image = image
27
+ @image = latest_remote_or_current_image if image == 'latest'
28
+ if ::File.exist?(platform_image_path) && valid?
29
+ ui.info "SmartOS platform image #{image} exists"
30
+ else
31
+ download_checksum_file
32
+ download_platform_image
33
+ end
34
+ end
35
+
36
+ def list
37
+ ui.info(images.join("\n"), prefix: false)
38
+ end
39
+
40
+ def latest
41
+ latest_html = Zones::Util::Downloader.new(platform_image_latest_url).read
42
+ latest = latest_html.match(/(\d{8}T\d{6}Z)/)
43
+ return unless latest
44
+ latest[1]
45
+ end
46
+
47
+ protected
48
+
49
+ def setup_smartos_directories
50
+ env.setup_home_path if env.respond_to?(:setup_home_path)
51
+ FileUtils.mkdir_p(images_dir)
52
+ FileUtils.mkdir_p(checksums_dir)
53
+ end
54
+
55
+ def download_checksum_file
56
+ return if machine && machine.config.global_zone.platform_image_url
57
+ ui.info "Downloading checksums for SmartOS platform image #{image}"
58
+ Zones::Util::Downloader.get(platform_image_checksum_url, platform_image_checksum_path)
59
+ end
60
+
61
+ def download_platform_image
62
+ ui.info "Downloading SmartOS platform image #{image}"
63
+ Vagrant::Util::Downloader.new(platform_image_url, platform_image_path, ui: ui).download!
64
+ end
65
+
66
+ private
67
+
68
+ def ui
69
+ env.respond_to?(:ui) ? env.ui : env[:ui]
70
+ end
71
+
72
+ def home_path
73
+ env.respond_to?(:home_path) ? env.home_path : env[:home_path]
74
+ end
75
+
76
+ def valid?
77
+ return true if machine && machine.config.global_zone.platform_image_url
78
+ checksums = ::File.read(platform_image_checksum_path).split("\n")
79
+ iso_checksum = checksums.grep(/\.iso/).first.match(/^[^\s]+/).to_s
80
+ Checksum.new(platform_image_path, iso_checksum).valid?
81
+ end
82
+
83
+ def images
84
+ Dir[images_dir.join('*')].map do |f|
85
+ File.basename(f, '.iso')
86
+ end.sort
87
+ end
88
+
89
+ def images_dir
90
+ home_path.join('smartos', 'platform_images')
91
+ end
92
+
93
+ def checksums_dir
94
+ home_path.join('smartos', 'checksums')
95
+ end
96
+
97
+ def latest_remote_or_current_image
98
+ return latest if latest
99
+ ui.info 'Unable to read remote latest platform image, using local'
100
+ images.last
101
+ end
102
+
103
+ def platform_image_root
104
+ 'https://us-east.manta.joyent.com'
105
+ end
106
+
107
+ def platform_image_path
108
+ images_dir.join("#{image}.iso")
109
+ end
110
+
111
+ def platform_image_url
112
+ return machine.config.global_zone.platform_image_url if machine &&
113
+ machine.config.global_zone.platform_image_url
114
+ "#{platform_image_root}/Joyent_Dev/public/SmartOS/#{image}/smartos-#{image}.iso"
115
+ end
116
+
117
+ def platform_image_latest_url
118
+ "#{platform_image_root}/Joyent_Dev/public/SmartOS/latest.html"
119
+ end
120
+
121
+ def platform_image_checksum_path
122
+ checksums_dir.join("#{image}.txt")
123
+ end
124
+
125
+ def platform_image_checksum_url
126
+ "#{platform_image_root}/Joyent_Dev/public/SmartOS/#{image}/md5sums.txt"
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,14 @@
1
+ module Vagrant
2
+ module Smartos
3
+ module Zones
4
+ module Util
5
+ class PublicKey
6
+ # rubocop:disable Metrics/LineLength
7
+ def to_s
8
+ 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require 'vagrant/smartos/zones/models/snapshot'
2
+
3
+ module Vagrant
4
+ module Smartos
5
+ module Zones
6
+ module Util
7
+ class Snapshots
8
+ include GlobalZone::Helper
9
+
10
+ attr_reader :machine, :zonename
11
+
12
+ def initialize(machine, zonename)
13
+ @machine = machine
14
+ @zonename = zonename
15
+ end
16
+
17
+ def run(action, snapshot = nil)
18
+ send action, snapshot
19
+ end
20
+
21
+ def list(_snapshot)
22
+ Models::Snapshot.all(zone).tap do |snapshots|
23
+ sns = snapshots.map do |snapshot|
24
+ [snapshot.name.ljust(12), snapshot.created_at.to_s.ljust(21),
25
+ snapshot.space_used.to_s.rjust(6), snapshot.zone.name].join(' ')
26
+ end
27
+ machine.ui.info(I18n.t('vagrant.smartos.zones.commands.zones.snapshot.list',
28
+ snapshots: sns.join("\n")), prefix: false)
29
+ end
30
+ end
31
+
32
+ def create(name)
33
+ machine.ui.info(I18n.t('vagrant.smartos.zones.commands.zones.snapshot.create',
34
+ name: name), prefix: false)
35
+ Models::Snapshot.create(name, zone)
36
+ end
37
+
38
+ def destroy(name)
39
+ Models::Snapshot.find(name, zone).tap do |snapshot|
40
+ machine.ui.info(I18n.t('vagrant.smartos.zones.commands.zones.snapshot.destroy',
41
+ name: snapshot.name), prefix: false)
42
+ snapshot.destroy
43
+ end
44
+ end
45
+
46
+ def rollback(name)
47
+ Models::Snapshot.find(name, zone).tap do |snapshot|
48
+ machine.ui.info(I18n.t('vagrant.smartos.zones.commands.zones.snapshot.rollback',
49
+ zonename: zone.name, name: snapshot.name), prefix: false)
50
+ snapshot.rollback
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def zone
57
+ @zone ||= Models::Zone.find(machine, zonename)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,34 @@
1
+ require 'vagrant/smartos/zones/models/zone_group'
2
+ require 'vagrant/smartos/zones/util/global_zone/helper'
3
+
4
+ module Vagrant
5
+ module Smartos
6
+ module Zones
7
+ module Util
8
+ class ZoneGroup
9
+ include GlobalZone::Helper
10
+
11
+ attr_reader :machine, :zone
12
+
13
+ def initialize(machine, zone)
14
+ @machine = machine
15
+ @zone = zone
16
+ end
17
+
18
+ def find(group)
19
+ Models::ZoneGroup.new.tap do |g|
20
+ g.name = group
21
+ with_gz("#{sudo} zlogin #{zone.uuid} gid -g #{group}") do |_type, output|
22
+ g.gid = output.chomp
23
+ end
24
+ end
25
+ end
26
+
27
+ def create(group)
28
+ zone.zlogin("groupadd #{group}")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,72 @@
1
+ require 'vagrant/smartos/zones/models/zone'
2
+ require 'vagrant/smartos/zones/util/global_zone/helper'
3
+ require 'vagrant/smartos/zones/util/zone_group'
4
+ require 'vagrant/smartos/zones/util/zone_json'
5
+ require 'vagrant/smartos/zones/util/zone_project'
6
+ require 'vagrant/smartos/zones/util/zone_user'
7
+
8
+ module Vagrant
9
+ module Smartos
10
+ module Zones
11
+ module Util
12
+ class ZoneInfo
13
+ include GlobalZone::Helper
14
+
15
+ attr_reader :machine
16
+
17
+ ROOT_PASSWORD = '\$5\$90x8mAeX\$SKKNEjeztV.ruPBNf/E5y3xqGkwDv9A5KNP2S89GuB.'
18
+ VAGRANT_PASSWORD = '\$5\$UzQ1rHU/\$o67DYOyHOOabzJt.6DwgZP2qCGoAO7aVel2bgkuIwL7'
19
+
20
+ def initialize(machine)
21
+ @machine = machine
22
+ end
23
+
24
+ def create(name)
25
+ machine.ui.info "Creating zone #{machine.config.zone.name} with image #{machine.config.zone.image}"
26
+ with_gz("echo '#{zone_json}' | #{sudo} vmadm create")
27
+ with_zone(name) do |zone|
28
+ create_zone_users(zone)
29
+ end
30
+ end
31
+
32
+ def update(name)
33
+ with_zone(name) do |zone|
34
+ machine.ui.info "Updating zone #{name}..."
35
+ with_gz("echo '#{zone_json}' | #{sudo} vmadm update #{zone.uuid}")
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def create_zone_users(zone)
42
+ create_zone_vagrant_user(zone)
43
+ configure_zone_passwords(zone)
44
+ end
45
+
46
+ def create_zone_vagrant_user(zone)
47
+ Util::ZoneGroup.new(machine, zone).create('vagrant')
48
+ Util::ZoneUser.new(machine, zone).create('vagrant', 'vagrant', 'Primary Administrator')
49
+ Util::ZoneProject.new(machine, zone).create('vagrant', %w(vagrant), 'Vagrant')
50
+ end
51
+
52
+ def configure_zone_passwords(zone)
53
+ overwrite_password(zone, 'root', ROOT_PASSWORD, '16151')
54
+ overwrite_password(zone, 'vagrant', VAGRANT_PASSWORD, '16158')
55
+ end
56
+
57
+ def overwrite_password(zone, user, pw, ts)
58
+ zone.zlogin("sed -i -e \\'s@#{user}:.*@#{user}:#{pw}:#{ts}::::::@\\' /etc/shadow")
59
+ end
60
+
61
+ def zone_json
62
+ Util::ZoneJson.new(machine).to_json
63
+ end
64
+
65
+ def with_zone(name)
66
+ Models::Zone.find(machine, name).tap { |zone| yield zone }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end