vagrant-grid5000 0.0.3 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 613f9417d67cd5678dea8bd2ccfb3614a77074b4
4
- data.tar.gz: 24d2c93783aa39a57b5b2156143b3969116f40a8
3
+ metadata.gz: 049b3239e51d78bc2e7278a79807d4dfa83347fa
4
+ data.tar.gz: 6f46fa07a915340c8875fe652f5d277afaedbf7d
5
5
  SHA512:
6
- metadata.gz: cc15abf4ef72d1bdc9f45a43395192884101c0fb6575fe1fc2fd5e1b1403cba75a4dd752509d3333424a9e35bee261e56b329534843afe76b9ff6fab1b613240
7
- data.tar.gz: f15092b80f70ef5553fb3c28b99555503bb6eb991624c4ab0145f5e962304262054fb75f40ceaad8669f3e543fc438913a6de95443db0bac19ec57b5e31ecefa
6
+ metadata.gz: f5923379e403ca03bf5ab71099a0770a8909d5d056c3c5bb41fe61da8040a37747c4af3145c72aaa5e6bf32efd8dbf2b3a16501377489a1eb0f813a54fd3700a
7
+ data.tar.gz: 3ae45922886bc50362a8acd708c3398cec35d7da6a3a307622a2ef124776df333e5b5f9904491dfcfff025971f809c589921fcac6859f95542f507e2792d2173
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/README.md CHANGED
@@ -10,19 +10,7 @@ This is a [Vagrant](http://www.vagrantup.com) plugin that adds a provider for
10
10
  machines running on the [Grid'5000](https://www.grid5000.fr) testbed to
11
11
  Vagrant.
12
12
 
13
- This is still at an early state of development.
14
-
15
- ## What works
16
- * vagrant up --provider=grid5000
17
- * vagrant status
18
- * vagrant ssh
19
- * vagrant destroy
20
-
21
- ## What doesn't work
22
-
23
- * everything else
24
-
25
- ## Installation
13
+ ## Installation and usage
26
14
 
27
15
  ```
28
16
  $ vagrant plugin install vagrant-grid5000
@@ -33,16 +21,16 @@ Each provider needs at least one ''box''. This does not really make sense here,
33
21
  $ vagrant box add --name dummy https://github.com/lnussbaum/vagrant-grid5000/raw/master/dummy.box
34
22
  ```
35
23
 
36
- Example Vagrantfile:
24
+ Example basic Vagrantfile:
37
25
  ```ruby
38
26
  Vagrant.configure("2") do |config|
39
27
 
40
- # Global configuration for Grid'5000 access
28
+ # Global configuration for Grid'5000
41
29
  config.vm.provider "grid5000" do |g5k|
42
- # cute_parameters = { :conf_file =>"config file path" }
30
+ # Ruby-Cute's authentication parameters
31
+ #g5k.cute_parameters = { :conf_file => "config file path" }
43
32
  # For details about allowed parameters see
44
33
  # https://github.com/lnussbaum/vagrant-grid5000/blob/master/lib/vagrant-grid5000/config.rb
45
-
46
34
  end
47
35
 
48
36
  config.vm.define :my_g5k_box do |g5k|
@@ -51,6 +39,24 @@ Vagrant.configure("2") do |config|
51
39
  end
52
40
  ```
53
41
 
42
+ Then try
43
+ ```
44
+ $ vagrant up --provider=grid5000
45
+ $ vagrant ssh
46
+ $ vagrant provision
47
+ $ vagrant destroy
48
+ ```
49
+
50
+ For more details about Vagrantfile configuration parameters, see
51
+ https://github.com/lnussbaum/vagrant-grid5000/blob/master/Vagrantfile
52
+
53
+ ### Synced folders
54
+
55
+ Synced folders are a bit tricky. You need to install 'rsync' (which is not
56
+ installed on jessie-x64-min), and then issue a ''vagrant reload'' to reload the
57
+ configuration. Note that you can also use 'rsync-auto' to auto-synchronize
58
+ changes.
59
+
54
60
  ## License
55
61
 
56
62
  The gem is available as free software under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -71,3 +77,5 @@ execute Vagrant.
71
77
  $ bundle exec vagrant up --provider=grid5000
72
78
  ```
73
79
  etc.
80
+
81
+ To debug stuff, use vagrant --debug.
@@ -3,13 +3,65 @@
3
3
 
4
4
  Vagrant.configure("2") do |config|
5
5
 
6
- # Global configuration for Grid'5000 access
6
+ # Global parameters for the Grid'5000 provider
7
7
  config.vm.provider "grid5000" do |g5k|
8
- # cute_parameters = { :conf_file =>"config file path" }
8
+
9
+ # Grid'5000 authentification parameters for Ruby-Cute
10
+ # see http://www.rubydoc.info/github/ruby-cute/ruby-cute/master/Cute%2FG5K%2FAPI%3Ainitialize
11
+ # default: use ~/.grid5000_api.yml
12
+ #g5k.cute_parameters = { :username => 'jdoe', :password => 'foo' }
13
+
14
+ # Site to reserve on (default: nancy)
15
+ #g5k.site = rennes
16
+
17
+ # OAR queue to use (default: default)
18
+ #g5k.queue = 'default'
9
19
 
20
+ # OAR properties to use (default: none)
21
+ #g5k.properties = "cluster='griffon'"
22
+
23
+ # Walltime (default: reserve until the next end of day (18:55))
24
+ #g5k.walltime = '02:30'
25
+
26
+ # Environment to deploy (default: jessie-x64-min)
27
+ #g5k.env = 'jessie-x64-base'
10
28
  end
11
29
 
12
- config.vm.define :my_g5k_box do |g5k|
13
- g5k.vm.box = "dummy"
30
+ config.vm.define :testbox do |tb|
31
+ # All providers need to provide a box. This is a dummy, empty box for the grid5000 provider.
32
+ tb.vm.box = "dummy"
33
+
34
+ # VM-specific overrides
35
+ tb.vm.provider 'grid5000' do |g5k|
36
+ g5k.site = 'rennes'
37
+ g5k.walltime = '0:15'
38
+ end
14
39
  end
40
+
41
+ config.vm.define :testbox2 do |tb2|
42
+ tb2.vm.box = "dummy"
43
+
44
+ # VM-specific overrides
45
+ tb2.vm.provider 'grid5000' do |g5k|
46
+ g5k.site = 'lyon'
47
+ g5k.walltime = '0:15'
48
+ end
49
+
50
+ # Synced folders configuration, using rsync (you need to install it if you use -min or -base, see below)
51
+ tb2.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: ".git/"
52
+ end
53
+
54
+ # Since we connect as root directly, we don't need to set 'privileged' to true
55
+ # However, it is a good idea to install sudo so that normal provisioning scripts
56
+ # work.
57
+ # rsync is needed for synced folders.
58
+ config.vm.provision "shell", privileged: false, inline: 'apt-get update && apt-get -y install sudo rsync'
59
+
60
+ # privileged: false is no longer required
61
+ config.vm.provision "shell", inline: <<-SHELL
62
+ #!/bin/bash -x
63
+ apt-get -y install less vim ruby
64
+ apt-get -y install git pv
65
+ SHELL
66
+
15
67
  end
@@ -9,50 +9,111 @@ module VagrantPlugins
9
9
  # Include the built-in modules so we can use them as top-level things.
10
10
  include Vagrant::Action::Builtin
11
11
 
12
- def self.action_up
12
+ # TODO def self.action_halt
13
+
14
+ def self.action_destroy
15
+ Vagrant::Action::Builder.new.tap do |b|
16
+ b.use Call, DestroyConfirm do |env, b2|
17
+ if env[:result]
18
+ b2.use ConfigValidate
19
+ b2.use Call, IsCreated do |env2, b3|
20
+ if !env2[:result]
21
+ b3.use MessageNotCreated
22
+ next
23
+ end
24
+ b3.use ConnectGrid5000
25
+ b3.use ReadState
26
+ b3.use DestroyInstance
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # This action is called when `vagrant provision` is called.
34
+ def self.action_provision
13
35
  Vagrant::Action::Builder.new.tap do |b|
14
36
  b.use ConfigValidate
15
- b.use ConnectGrid5000
16
- b.use ReserveAndDeploy
37
+ b.use Call, IsCreated do |env, b2|
38
+ if !env[:result]
39
+ b2.use MessageNotCreated
40
+ next
41
+ end
42
+ b2.use Provision
43
+ end
17
44
  end
18
45
  end
19
46
 
20
- def self.action_ssh
47
+ # This action is called to read the state of the machine. The
48
+ # resulting state is expected to be put into the `:machine_state_id`
49
+ # key.
50
+ def self.action_read_state
21
51
  Vagrant::Action::Builder.new.tap do |b|
52
+ b.use ConfigValidate
22
53
  b.use ConnectGrid5000
23
54
  b.use ReadState
24
- b.use SSHExec
55
+ end
56
+ end
57
+
58
+ def self.action_ssh
59
+ Vagrant::Action::Builder.new.tap do |b|
60
+ b.use ConfigValidate
61
+ b.use Call, IsCreated do |env, b2|
62
+ if !env[:result]
63
+ b2.use MessageNotCreated
64
+ next
65
+ end
66
+ b2.use ConnectGrid5000
67
+ b2.use ReadState
68
+ b2.use SSHExec
69
+ end
25
70
  end
26
71
  end
27
72
 
28
73
  def self.action_ssh_run
29
- return Vagrant::Action::Builder.new.tap do |b|
30
- b.use ConnectGrid5000
31
- b.use ReadState
32
- b.use SSHRun
74
+ Vagrant::Action::Builder.new.tap do |b|
75
+ b.use ConfigValidate
76
+ b.use Call, IsCreated do |env, b2|
77
+ if !env[:result]
78
+ b2.use MessageNotCreated
79
+ next
80
+ end
81
+ b2.use ConnectGrid5000
82
+ b2.use ReadState
83
+ b2.use SSHRun
84
+ end
33
85
  end
34
86
  end
35
87
 
36
- def self.action_destroy
88
+ def self.action_up
37
89
  Vagrant::Action::Builder.new.tap do |b|
90
+ b.use HandleBox
91
+ b.use ConfigValidate
92
+ b.use BoxCheckOutdated
38
93
  b.use ConnectGrid5000
39
- b.use ReadState
40
- b.use Call, DestroyConfirm do |env, b2|
41
- if env[:result]
42
- b2.use DestroyInstance
94
+ b.use Call, IsCreated do |env1, b1|
95
+ if env1[:result]
96
+ b1.use MessageAlreadyCreated # TODO write a better message
97
+ else
98
+ b1.use ReserveAndDeploy
43
99
  end
44
100
  end
45
101
  end
46
102
  end
47
103
 
48
- # This action is called to read the state of the machine. The
49
- # resulting state is expected to be put into the `:machine_state_id`
50
- # key.
51
- def self.action_read_state
104
+ def self.action_reload
52
105
  Vagrant::Action::Builder.new.tap do |b|
53
106
  b.use ConfigValidate
54
107
  b.use ConnectGrid5000
55
- b.use ReadState
108
+ b.use Call, IsCreated do |env, b2|
109
+ if !env[:result]
110
+ b2.use MessageNotCreated
111
+ next
112
+ end
113
+
114
+ # We do almost nothing during reload
115
+ b2.use SyncedFolders
116
+ end
56
117
  end
57
118
  end
58
119
 
@@ -62,6 +123,9 @@ module VagrantPlugins
62
123
  autoload :ReadState, action_root.join("read_state")
63
124
  autoload :ConnectGrid5000, action_root.join("connect_grid5000")
64
125
  autoload :DestroyInstance, action_root.join("destroy_instance")
126
+ autoload :IsCreated, action_root.join("is_created")
127
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
128
+ autoload :MessageNotCreated, action_root.join("message_not_created")
65
129
  end
66
130
  end
67
131
  end
@@ -1,5 +1,7 @@
1
1
  require "log4r"
2
2
 
3
+ $last_check_time = nil
4
+
3
5
  module VagrantPlugins
4
6
  module Grid5000
5
7
  module Action
@@ -13,8 +15,13 @@ module VagrantPlugins
13
15
 
14
16
  def call(env)
15
17
  env[:g5k] = Cute::G5K::API.new(env[:machine].provider_config.cute_parameters || {})
16
- # FIXME customize logger to make it clear that ruby-cute is the one displaying messages
17
- raise "Unable to retrieve the list of sites and find nancy in it" if not env[:g5k].site_uids.include?('nancy')
18
+ env[:g5k].logger = Logger.new(STDOUT)
19
+ env[:g5k].logger.progname = 'ruby-cute'
20
+ env[:g5k].logger.datetime_format = "%Y-%m-%d %H:%M:%S "
21
+ if $last_check_time.nil? or $last_check_time + 60 < Time::now
22
+ raise "Unable to retrieve the list of sites and find nancy in it" if not env[:g5k].site_uids.include?('nancy')
23
+ $last_check_time = Time::now
24
+ end
18
25
  @app.call(env)
19
26
  end
20
27
  end
@@ -0,0 +1,18 @@
1
+ module VagrantPlugins
2
+ module Grid5000
3
+ module Action
4
+ # This can be used with "Call" built-in to check if the machine
5
+ # is created and branch in the middleware.
6
+ class IsCreated
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:result] = env[:machine].state.id != :not_created
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module Grid5000
3
+ module Action
4
+ class MessageAlreadyCreated
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info('Machine already created.')
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module Grid5000
3
+ module Action
4
+ class MessageNotCreated
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info('Machine not created.')
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,8 @@
1
1
  require "log4r"
2
2
 
3
+ $job_cache_data = {}
4
+ $job_cache_time = {}
5
+
3
6
  module VagrantPlugins
4
7
  module Grid5000
5
8
  module Action
@@ -18,19 +21,19 @@ module VagrantPlugins
18
21
  @app.call(env)
19
22
  end
20
23
 
21
- $last_state_read = nil
22
24
  def read_state(env)
23
-
24
25
  return :not_created if not env[:g5k] or not env[:machine]
25
26
  id = env[:machine].id
26
27
  return :not_created if id.nil?
27
28
  site, jobid, node = id.split(':')
28
29
 
29
- if $last_state_read != nil and env[:job] and Time::now < $last_state_read + 60
30
- # skip
30
+ # Very basic caching
31
+ if $job_cache_time.has_key?([site, jobid]) and $job_cache_time[[site, jobid]] + 60 > Time::now
32
+ env[:job] = $job_cache_data[[site, jobid]]
31
33
  else
32
34
  env[:job] = env[:g5k].get_job(site, jobid)
33
- $last_state_read = Time::now
35
+ $job_cache_data[[site, jobid]] = env[:job]
36
+ $job_cache_time[[site, jobid]] = Time::now
34
37
  end
35
38
  env[:machine_ssh_info] = { :host => node, :port => 22, :username => 'root', :proxy_command => "ssh -W #{node}:22 #{env[:g5k].g5k_user}@access.grid5000.fr" }
36
39
  return :running if env[:job]['state'] == 'running'
@@ -1,5 +1,10 @@
1
1
  require "log4r"
2
2
  require 'time'
3
+ require 'fileutils'
4
+
5
+ VAGRANT_INSECURE_PUBLIC_KEY = <<EOF
6
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
7
+ EOF
3
8
 
4
9
  module VagrantPlugins
5
10
  module Grid5000
@@ -14,24 +19,29 @@ module VagrantPlugins
14
19
  cfg = env[:machine].provider_config
15
20
  walltime = cfg.walltime
16
21
  if walltime.nil? # slightly broken: what if the local time doesn't switch DST at the same time as Europe/Paris?
17
- if Time::now.dst?
18
- target = '18:55:00 CEST'
19
- else
20
- target = '18:55:00 CET'
21
- end
22
- walltime = (Time::parse(target) - Time::now).to_i
23
- walltime = format("%02d:%02d:%02d", walltime / (60*60), walltime / 60 % 60, walltime % 60)
22
+ if Time::now.dst?
23
+ target = '18:55:00 CEST'
24
+ else
25
+ target = '18:55:00 CET'
26
+ end
27
+ walltime = (Time::parse(target) - Time::now).to_i
28
+ walltime += 86400 if walltime < 0 # if we are after the deadline, target the next day
29
+ walltime = format("%02d:%02d:%02d", walltime / (60*60), walltime / 60 % 60, walltime % 60)
24
30
  end
25
31
  if ENV['VAGRANT_DEBUG'] == 'REUSE_JOB'
26
- job = env[:g5k].get_my_jobs(cfg.site).first
32
+ job = env[:g5k].get_my_jobs(cfg.site).first
27
33
  else
28
- job = env[:g5k].reserve(:site => cfg.site, :walltime => walltime,
29
- :properties => cfg.properties, :env => cfg.env, :keys => cfg.keys,
30
- :name => "vagrant-grid5000")
34
+ # hack: create a temporary file that holds the Vagrant public key, so that ruby-cute is happy.
35
+ f = `mktemp /tmp/vagrant-grid5000-public-key.XXXXXX.pub`.chomp
36
+ File::open(f, 'w') { |fd| fd.print VAGRANT_INSECURE_PUBLIC_KEY }
37
+ params = { :site => cfg.site, :walltime => walltime, :properties => cfg.properties, :queue => cfg.queue, :env => cfg.env, :keys => f.gsub('.pub', ''), :name => "vagrant-g5k" }
38
+ env[:ui].info("Initiating reservation and deployment with #{params.inspect}")
39
+ job = env[:g5k].reserve(params)
40
+ FileUtils::rm(f)
31
41
  end
32
42
  env[:node] = job['assigned_nodes'].first
33
43
  env[:machine_state_id] = :running
34
- @logger.info("Node #{env[:node]} successfully started.")
44
+ env[:ui].info("Node #{env[:node]} successfully started.")
35
45
  env[:job] = job
36
46
  env[:machine].id = "#{cfg.site}:#{job['uid']}:#{env[:node]}"
37
47
  @app.call(env)
@@ -20,6 +20,10 @@ module VagrantPlugins
20
20
  # @return [String]
21
21
  attr_accessor :properties
22
22
 
23
+ # OAR queue to use when reserving resources. (default: 'default'; other values: production, besteffort)
24
+ # @return [String]
25
+ attr_accessor :queue
26
+
23
27
  # Walltime to use when reserving resources. (default: reserve resources until today at 6:55pm)
24
28
  # @return [String]
25
29
  attr_accessor :walltime
@@ -29,18 +33,12 @@ module VagrantPlugins
29
33
  # @return [String]
30
34
  attr_accessor :env
31
35
 
32
- # SSH keys to copy to the deployed machine. (default: use Ruby-Cute's default, which is to copy
33
- # the public keys found in ~/.ssh/
34
- # @return [String]
35
- attr_accessor :keys
36
-
37
-
38
36
  def initialize()
39
37
  @cute_parameters = UNSET_VALUE
40
38
  @env = UNSET_VALUE
41
39
  @site = UNSET_VALUE
42
- @keys = UNSET_VALUE
43
40
  @properties = UNSET_VALUE
41
+ @queue = UNSET_VALUE
44
42
  @walltime = UNSET_VALUE
45
43
  end
46
44
 
@@ -48,8 +46,8 @@ module VagrantPlugins
48
46
  @cute_parameters = nil if @cute_parameters == UNSET_VALUE
49
47
  @site = 'nancy' if @site == UNSET_VALUE
50
48
  @env = 'jessie-x64-min' if @env == UNSET_VALUE
51
- @keys = nil if @keys == UNSET_VALUE
52
49
  @properties = '' if @properties == UNSET_VALUE
50
+ @queue = 'default' if @queue == UNSET_VALUE
53
51
  @walltime = nil if @walltime == UNSET_VALUE
54
52
  end
55
53
 
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Grid5000
3
- VERSION = "0.0.3"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-grid5000
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Nussbaum
@@ -59,6 +59,7 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - ".gitignore"
62
63
  - Gemfile
63
64
  - LICENSE.txt
64
65
  - README.md
@@ -74,6 +75,9 @@ files:
74
75
  - lib/vagrant-grid5000/action.rb
75
76
  - lib/vagrant-grid5000/action/connect_grid5000.rb
76
77
  - lib/vagrant-grid5000/action/destroy_instance.rb
78
+ - lib/vagrant-grid5000/action/is_created.rb
79
+ - lib/vagrant-grid5000/action/message_already_created.rb
80
+ - lib/vagrant-grid5000/action/message_not_created.rb
77
81
  - lib/vagrant-grid5000/action/read_state.rb
78
82
  - lib/vagrant-grid5000/action/reserve_and_deploy.rb
79
83
  - lib/vagrant-grid5000/config.rb