Class: XP5K::XP

Inherits:
Object
  • Object
show all
Includes:
Term::ANSIColor
Defined in:
lib/xp5k/xp.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ XP

Returns a new instance of XP.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/xp5k/xp.rb', line 14

def initialize(options = {})
  @jobs               = []
  @jobs2submit        = []
  @deployments        = []
  @todeploy           = []
  @roles              = []
  @links_deployments  = {"jobs" => {}, "roles" => {}}
  @deployed_nodes     = {"jobs" => {}, "roles" => {}}
  @retries            = options[:retries] || 3
  @starttime          = Time.now
  @logger             = options[:logger] || Logger.new(STDOUT)

  XP5K::Config.load unless XP5K::Config.loaded?

  @connection = Restfully::Session.new(
    :configuration_file => "~/.restfully/api.grid5000.fr.yml",
    :logger => begin
      tmplogger       = ::Logger.new(STDERR)
      tmplogger.level = ::Logger::WARN
      tmplogger
    end
  )
end

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def connection
  @connection
end

#deployed_nodesObject

Returns the value of attribute deployed_nodes.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def deployed_nodes
  @deployed_nodes
end

#deploymentsObject

Returns the value of attribute deployments.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def deployments
  @deployments
end

#jobsObject

Returns the value of attribute jobs.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def jobs
  @jobs
end

#jobs2submitObject

Returns the value of attribute jobs2submit.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def jobs2submit
  @jobs2submit
end

Returns the value of attribute links_deployments.



12
13
14
# File 'lib/xp5k/xp.rb', line 12

def links_deployments
  @links_deployments
end

#rolesObject

Returns the value of attribute roles.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def roles
  @roles
end

#starttimeObject (readonly)

Returns the value of attribute starttime.



12
13
14
# File 'lib/xp5k/xp.rb', line 12

def starttime
  @starttime
end

#todeployObject

Returns the value of attribute todeploy.



11
12
13
# File 'lib/xp5k/xp.rb', line 11

def todeploy
  @todeploy
end

Instance Method Details

#cleanObject



172
173
174
175
176
177
178
# File 'lib/xp5k/xp.rb', line 172

def clean
  self.jobs.each do |job|
    job.delete if (job['state'] =~ /running|waiting/)
    logger.info "Job ##{job["uid"]} deleted !"
  end
  FileUtils.rm(".xp_cache") if File.exists?(".xp_cache")
end

#define_deployment(deployment_hash) ⇒ Object



42
43
44
45
46
# File 'lib/xp5k/xp.rb', line 42

def define_deployment(deployment_hash)
  deployment_hash[:jobs] ||= []
  deployment_hash[:roles] ||= []
  self.todeploy << deployment_hash
end

#define_job(job_hash) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/xp5k/xp.rb', line 79

def define_job(job_hash)
  self.jobs2submit << job_hash

  if File.exists?(".xp_cache")
    datas = JSON.parse(File.read(".xp_cache"))
    uid = datas["jobs"].select { |x| x["name"] == job_hash[:name] }.first["uid"]
    unless uid.nil?
      job = @connection.root.sites[job_hash[:site].to_sym].jobs(:query => { :user => @connection.config.options[:username] || ENV['USER'] })["#{uid}".to_sym]
      if (not job.nil? or job["state"] == "running")
        j = job.reload
        self.jobs << j
        self.roles += Role.create_roles(j, job_hash) unless job_hash[:roles].nil?
      end
    end
    # reload last deployed nodes
    self.deployed_nodes = datas["deployed_nodes"]
  end

end

#deployObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/xp5k/xp.rb', line 48

def deploy()
  # prepare assigned_nodes, goals and retries value
  self.todeploy.each do |x|
    x[:assigned_nodes] = []
    x[:jobs].each do |jobname|
      job = self.job_with_name(jobname)
      self.deployed_nodes["jobs"][jobname] = []
      x[:assigned_nodes] += job["assigned_nodes"]
    end
    x[:roles].each do |rolename|
      role = role_with_name(rolename)
      self.deployed_nodes["roles"][rolename] = []
      x[:assigned_nodes] += role.servers
    end
    # initially all nodes have to be deployed
    x[:nodes] = x[:assigned_nodes]
    # set goal
    x[:goal] = set_goal(x[:goal], x[:assigned_nodes].length)
    # set retries
    x[:retry] ||= false
    x[:retries] ||= x[:retry]?@retries:1
    # Manage vlan on primary interface
    if vlan_from_job = x[:vlan_from_job]
      x[:vlan] = self.job_with_name(vlan_from_job)['resources_by_type']['vlans'].first.to_i
    end
  end
  internal_deploy(@retries)
  print_deploy_summary
end

#get_deployed_nodes(job_or_role_name) ⇒ Object



154
155
156
157
158
159
160
161
# File 'lib/xp5k/xp.rb', line 154

def get_deployed_nodes(job_or_role_name)
  if self.deployed_nodes["jobs"].has_key?(job_or_role_name)
    return self.deployed_nodes["jobs"][job_or_role_name]
  end
  if self.deployed_nodes["roles"].has_key?(job_or_role_name)
    return self.deployed_nodes["roles"][job_or_role_name]
  end
end

#job_with_name(name) ⇒ Object



144
145
146
# File 'lib/xp5k/xp.rb', line 144

def job_with_name(name)
  self.jobs.select { |x| x["name"] == name }.first
end

#role_with_name(name) ⇒ Object



148
149
150
151
152
# File 'lib/xp5k/xp.rb', line 148

def role_with_name(name)
  role = self.roles.select { |x| x.name == name}.first
  logger.debug "Role #{name} not found." if role.nil?
  return role
end

#statusObject



163
164
165
166
167
168
169
170
# File 'lib/xp5k/xp.rb', line 163

def status
  self.jobs.each.with_index do |job, id|
    log = "Job \"#{job["name"]}\" #{job["uid"]}@#{jobs2submit[id][:site]} status : #{job["state"]}"
    log += " (#{Time.at(job['scheduled_at'].to_i).to_datetime})" if job['state'] == 'waiting'
    log += " (until #{Time.at(job['started_at'].to_i + job['walltime'].to_i).to_datetime})" if job['state'] == 'running'
    logger.info log
  end
end

#submitObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/xp5k/xp.rb', line 99

def submit
  self.jobs2submit.each do |job2submit|
    job = self.job_with_name(job2submit[:name])
    if job.nil?
      job = @connection.root.sites[job2submit[:site].to_sym].jobs.submit(job2submit)
      update_cache
      logger.info "Job \"#{job['name']}\" submitted with id #{job['uid']}@#{job2submit[:site]}"
      self.jobs << job
    else
      logger.info "Job \"#{job["name"]}\" already submitted #{job["uid"]}@#{job2submit[:site]}"
    end
  end
  update_cache()
end

#timerObject



38
39
40
# File 'lib/xp5k/xp.rb', line 38

def timer
  Time.now - self.starttime
end

#wait_for_jobsObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/xp5k/xp.rb', line 114

def wait_for_jobs
  logger.info "Waiting for running state (Ctrl+c to stop waiting)"
  ready = false
  jobs_status = []
  trap("SIGINT") do
    logger.info "Stop waiting job."
    exit
  end
  until ready
    self.jobs.each.with_index do |job, id|
      jobs_status[id] = job.reload["state"]
      case jobs_status[id]
      when "running"
        self.roles += Role.create_roles(job, jobs2submit[id]) unless jobs2submit[id][:roles].nil?
        logger.info "Job #{job['uid']}@#{jobs2submit[id][:site]} is running"
      when /terminated|error/
        logger.info "Job #{job['uid']}@#{jobs2submit[id][:site]} is terminated"
      else
        logger.info "Job #{job['uid']}@#{jobs2submit[id][:site]} will be scheduled at #{Time.at(job['scheduled_at'].to_i).to_datetime}"
      end
    end
    ready = true if jobs_status.uniq == ["running"]
    sleep 3
  end
  update_cache()
  trap "SIGINT" do
    raise
  end
end