Class: CondorCloud::DefaultExecutor

Inherits:
Object
  • Object
show all
Defined in:
lib/deltacloud/drivers/condor/condor_client.rb

Constant Summary collapse

CONDOR_Q_CMD =
ENV['CONDOR_Q_CMD'] || "condor_q"
CONDOR_RM_CMD =
ENV['CONDOR_RM_CMD'] || "condor_rm"
CONDOR_SUBMIT_CMD =
ENV['CONDOR_SUBMIT_CMD'] || 'condor_submit'
CONDOR_CONFIG =

This directory needs to be readable for user running Deltacloud API

ENV['CONDOR_CONFIG'] || 'config/condor.yaml'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) {|_self| ... } ⇒ DefaultExecutor

You can use your own IP agent using :ip_agent option. IPAgent should have parent class set to ‘IPAgent’ and implement all methods from this class. You can pass options to ip_agent using :ip_agent_args hash.

Yields:

  • (_self)

Yield Parameters:



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 54

def initialize(opts={}, &block)
  load_config!
  if opts[:ip_agent]
    @ip_agent = opts[:ip_agent]
  else
    default_ip_agent = CondorCloud::const_get(@config[:default_ip_agent])
    @ip_agent = default_ip_agent.new(:config => @config)
  end
  yield self if block_given?
  self
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



47
48
49
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 47

def config
  @config
end

#ip_agentObject

Returns the value of attribute ip_agent.



46
47
48
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 46

def ip_agent
  @ip_agent
end

Instance Method Details

#destroy_instance(instance_id) ⇒ Object



204
205
206
207
208
209
210
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 204

def destroy_instance(instance_id)
  bare_xml = Nokogiri::XML(`#{CONDOR_Q_CMD} -xml`)
  cluster_id = (bare_xml/'/classads/c/a[@n="GlobalJobId"]/s').collect do |id|
    id.text.split('#')[1] if id.text.split('#').last==instance_id
  end.compact.first
  `#{CONDOR_RM_CMD} #{cluster_id}`
end

#hardware_profiles(opts = {}) ⇒ Object

List hardware profiles available for Condor. Basically those profiles are static ‘small’, ‘medium’ and ‘large’

Defined as:

when { :memory => '512', :cpus => '1' } then 'small'
when { :memory => '1024', :cpus => '2' } then 'medium'
when { :memory => '2047', :cpus => '4' } then 'large'


223
224
225
226
227
228
229
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 223

def hardware_profiles(opts={})
  return [
    { :name => 'small', :cpus => 1, :memory => 512 },
    { :name => 'medium', :cpus => 2, :memory => 1024 },
    { :name => 'large', :cpus => 4, :memory => 2048 }
  ]
end

#images(opts = {}) ⇒ Object

List all files in ENV or fallback to ‘/home/cloud/images’ Convert files to CondorCloud::Image class

name’



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 87

def images(opts={})
  Dir["#{@config[:image_storage]}/*"].collect do |file|
    next unless File::file?(file)
    next unless File::readable?(file)
    image = Image.new(
      :name => File::basename(file).downcase.tr('.', '-'),
      :owner_id => Etc.getpwuid(File.stat(file).uid).name,
      :description => file
    )
    next if opts[:id] and opts[:id]!=image.id
    image
  end.compact
end

#instances(opts = {}) ⇒ Object

List instances using ENV command. Retrieve XML from this command and parse it using Nokogiri. Then this XML is converted to CondorCloud::Instance class



76
77
78
79
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 76

def instances(opts={})
  bare_xml = Nokogiri::XML(`#{CONDOR_Q_CMD} -xml`)
  parse_condor_q_output(bare_xml, opts)
end

#launch_instance(image, hardware_profile, opts = {}) ⇒ Object

Launch a new instance in Condor cloud using ENV. Return CondorCloud::Instance.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 122

def launch_instance(image, hardware_profile, opts={})
  raise "Image object must be not nil" unless image
  raise "HardwareProfile object must be not nil" unless hardware_profile
  opts[:name] ||= "i-#{Time.now.to_i}"

  # This needs to be determined by the mac/ip translation stuff.
  # We need to call into it and have it return these variables, or at least the MAC if not the IP.
  mac_addr = @ip_agent.find_free_mac
  ip_addr = @ip_agent.find_ip_by_mac(mac_addr) if mac_addr && !mac_addr.empty?

  libvirt_xml = "+VM_XML=\"<domain type='kvm'>
    <name>{NAME}</name>
    <memory>#{hardware_profile.memory.value.to_i * 1024}</memory>
    <vcpu>#{hardware_profile.cpu.value}</vcpu>
    <os>
      <type arch='x86_64'>hvm</type>
      <boot dev='hd'/>
      <smbios mode='sysinfo'/>
    </os>
    <sysinfo type='smbios'>
      <system>
        <entry name='manufacturer'>#{opts[:config_server_address]}</entry>
        <entry name='product'>#{opts[:uuid]}</entry>
        <entry name='serial'>#{opts[:otp]}</entry>
      </system>
    </sysinfo>
    <features>
      <acpi/><apic/><pae/>
    </features>
    <clock offset='utc'/>
    <on_poweroff>destroy</on_poweroff>
    <on_reboot>restart</on_reboot>
    <on_crash>restart</on_crash>
    <devices>
      <disk type='file' device='disk'>
        <source file='{DISK}'/>
        <target dev='vda' bus='virtio'/>
        <driver name='qemu' type='qcow2'/>
      </disk>
      <interface type='bridge'>
        #{"<mac address='" + mac_addr + "'/>" if mac_addr && !mac_addr.empty?}
        <source bridge='#{@config[:default_bridge]}'/>
      </interface>
      <graphics type='vnc' port='#{@config[:vnc_listen_port]}' autoport='yes' keymap='en-us' listen='#{@config[:vnc_listen_ip]}'/>
    </devices>
  </domain>\"".gsub(/(\s{2,})/, ' ').gsub(/\>\s\</, '><')

  # I use the 2>&1 to get stderr and stdout together because popen3 does not support
  # the ability to get the exit value of the command in ruby 1.8.
  pipe = IO.popen("#{CONDOR_SUBMIT_CMD} 2>&1", "w+")
  pipe.puts "universe=vm"
  pipe.puts "vm_type=kvm"
  pipe.puts "vm_memory=#{hardware_profile.memory.value}"
  pipe.puts "request_cpus=#{hardware_profile.cpu.value}"
  pipe.puts "vm_disk=#{image.description}:null:null"
  pipe.puts "executable=#{image.description}"
  pipe.puts "vm_macaddr=#{mac_addr}"

  # Only set the ip if it is available, and this should depend on the IP mapping used.
  # With the fixed mapping method we know the IP address right away before we start the
  # instance, so fill it in here.  If it is not set I think we should set it to an empty
  # string and we'll fill it in later using a condor tool to update the job.
  pipe.puts "+vm_ipaddr=\"#{ip_addr}\""
  pipe.puts '+HookKeyword="CLOUD"'
  pipe.puts "+Cmd=\"#{opts[:name]}\""
  # Really the image should not be a full path to begin with I think..
  pipe.puts "+cloud_image=\"#{File.basename(image.description)}\""
  pipe.puts libvirt_xml
  pipe.puts "queue"
  pipe.puts ""
  pipe.close_write
  out = pipe.read
  pipe.close

  if $? != 0
    raise "Error starting VM in condor_submit: #{out}"
  end

  bare_xml = Nokogiri::XML(`#{CONDOR_Q_CMD} -xml`)
  parse_condor_q_output(bare_xml, :name => opts[:name])
end

#load_config!Object



66
67
68
# File 'lib/deltacloud/drivers/condor/condor_client.rb', line 66

def load_config!
  @config = YAML::load(File.open(CONDOR_CONFIG))
end