class Application

Constants

APP_NAME_MAX_LENGTH
DEFAULT_NODE_PROFILE
SCALABLE_EMBEDDED_CARTS
UNSCALABLE_FRAMEWORKS

Attributes

aliases[RW]
cart_data[RW]
comp_instance_map[RW]
configure_order[RW]
conn_endpoints_list[RW]
creation_time[RW]
destroyed_gears[RW]
domain[RW]
group_instance_map[RW]
group_override_map[RW]
init_git_url[RW]
ngears[RW]
node_profile[RW]
proxy_cartridge[RW]
scalable[RW]
start_order[RW]
state[RW]
usage_records[RW]
user[RW]
uuid[RW]
working_comp_inst_hash[RW]
working_group_inst_hash[RW]

Public Class Methods

find(user, app_name) click to toggle source

Find an application to which user has access @param [CloudUser] user @param [String] app_name @return [Application]

# File lib/stickshift-controller/app/models/application.rb, line 170
def self.find(user, app_name)
  return nil if app_name.nil? or app_name.empty?
  app = nil
  if user.applications
    user.applications.each do |next_app|
      if next_app.name.downcase == app_name.downcase
        app = next_app
        break
      end
    end
  else
    app = super(user.login, app_name)
    return nil unless app
    app.user = user
    app.reset_state
  end
  app
end
find_all(user) click to toggle source

Find an applications to which user has access @param [CloudUser] user @return [Array<Application>]

# File lib/stickshift-controller/app/models/application.rb, line 192
def self.find_all(user)
  apps = nil
  if user.applications
    apps = user.applications
  else
    apps = super(user.login)
    apps.each do |app|
      app.user = user
      app.reset_state
    end
    user.applications = apps
  end
  apps
end
find_by_gear_uuid(gear_uuid) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 207
def self.find_by_gear_uuid(gear_uuid)
  hash = StickShift::DataStore.instance.find_by_gear_uuid(gear_uuid)
  return nil unless hash
  user = CloudUser.hash_to_obj hash
  user.applications.each do |next_app|
    next_app.gears.each do |gear|
      if gear.uuid == gear_uuid
        return next_app,gear
      end
    end
  end
  return nil
end
find_by_uuid(uuid) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 221
def self.find_by_uuid(uuid)
  hash = StickShift::DataStore.instance.find_by_uuid(self.name,uuid)
  return nil unless hash
  user = CloudUser.hash_to_obj hash
  app  = nil
  user.applications.each do |next_app|
    if next_app.uuid == uuid
      app = next_app
      break
    end
  end
  return app
end
get_available_cartridges(cart_type=nil) click to toggle source

@overload ::get_available_cartridges

@deprecated
Returns List of names of available cartridges of specified type
@param [String] cart_type Must be "standalone" or "embedded" or nil
@return [Array<String>]

@overload ::get_available_cartridges

@return [Array<String>]   
Returns List of names of all available cartridges
# File lib/stickshift-controller/app/models/application.rb, line 253
def self.get_available_cartridges(cart_type=nil)
  cart_names = CartridgeCache.cartridge_names(cart_type)
end
hash_to_obj(hash) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 235
def self.hash_to_obj(hash)
  domain = nil
  if hash["domain"]
    domain = Domain.hash_to_obj(hash["domain"])
  end
  app = super(hash)
  app.domain = domain
  app
end
new(user=nil, app_name=nil, uuid=nil, node_profile=nil, framework=nil, template=nil, will_scale=false, domain=nil) click to toggle source

@param [CloudUser] user @param [String] app_name Application name @param [optional, String] uuid Unique identifier for the application @param [deprecated, String] #node_profile Node profile for the first application gear @param [deprecated, String] framework Cartridge name to use as the framwwork of the application

# File lib/stickshift-controller/app/models/application.rb, line 53
def initialize(user=nil, app_name=nil, uuid=nil, node_profile=nil, framework=nil, template=nil, will_scale=false, domain=nil)
  self.user = user
  self.domain = domain
  self.node_profile = node_profile
  self.creation_time = DateTime::now().strftime
  self.uuid = uuid || StickShift::Model.gen_uuid
  self.scalable = will_scale
  self.ngears = 0
  
  if template.nil?
    if self.scalable
      descriptor_hash = YAML.load(template_scalable_app(app_name, framework))
      from_descriptor(descriptor_hash)
      self.proxy_cartridge = "haproxy-1.4"
    else
      from_descriptor({"Name"=>app_name})
      self.requires_feature = []
      self.requires_feature << framework unless framework.nil?      
    end
  else
    template_descriptor = YAML.load(template.descriptor_yaml)
    template_descriptor["Name"] = app_name
    if not template_descriptor["Configure-Order"]
      requires_list = template_descriptor["Requires"] || []
      template_descriptor["Configure-Order"] = requires_list
    end
    from_descriptor(template_descriptor)
    @init_git_url = template.git_url
  end
  self.categories -= ["cartridge"]
end

Public Instance Methods

add_alias(server_alias) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1001
def add_alias(server_alias)
  if !(server_alias =~ %r\A[\w\-\.]+\z/) or (server_alias =~ %r#{Rails.configuration.ss[:domain_suffix]}$/)
    raise StickShift::UserException.new("Invalid Server Alias '#{server_alias}' specified", 105) 
  end
  
  self.aliases = [] unless self.aliases
  raise StickShift::UserException.new("Alias '#{server_alias}' already exists for '#{@name}'", 255) if self.aliases.include? server_alias
  reply = ResultIO.new
  begin
    self.aliases.push(server_alias)
    self.save      
    reply.append self.container.add_alias(self, self.gear, self.framework, server_alias)
  rescue Exception => e
    Rails.logger.debug e.message
    Rails.logger.debug e.backtrace.inspect
    reply.append self.container.remove_alias(self, self.gear, self.framework, server_alias)      
    self.aliases.delete(server_alias)
    self.save
    raise
  end
  reply
end
add_authorized_ssh_key(ssh_key, key_type=nil, comment=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 815
def add_authorized_ssh_key(ssh_key, key_type=nil, comment=nil)
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.add_authorized_ssh_key(ssh_key, key_type, comment)
  end
  raise f[0][:exception] if(f.length > 0)    
  reply
end
add_broker_key() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 851
def add_broker_key
  iv, token = StickShift::AuthService.instance.generate_broker_key(self)
  
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.add_broker_auth_key(iv,token)
  end
  raise f[0][:exception] if(f.length > 0)    
  reply
end
add_dependency(dep) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1044
def add_dependency(dep)
  reply = ResultIO.new
  self.class.notify_observers(:before_add_dependency, {:application => self, :dependency => dep, :reply => reply})
  # Create persistent storage app entry on configure (one of the first things)
  Rails.logger.debug "DEBUG: Adding embedded app info from persistant storage: #{@name}:#{dep}"
  self.cart_data = {} if @cart_data.nil?
  
  raise StickShift::UserException.new("#{dep} already embedded in '#{@name}'", 101) if self.embedded.include? dep
  if self.scalable
    raise StickShift::UserException.new("#{dep} cannot be embedded in scalable app '#{@name}'. Allowed cartridges: #{SCALABLE_EMBEDDED_CARTS.join(',')}", 108) if not SCALABLE_EMBEDDED_CARTS.include? dep
  end
  add_to_requires_feature(dep)
  begin
    reply.append self.configure_dependencies
    self.execute_connections
  rescue Exception => e
    remove_from_requires_feature(dep)
    self.elaborate_descriptor
    self.save
    raise e
  end

  self.class.notify_observers(:after_add_dependency, {:application => self, :dependency => dep, :reply => reply})
  reply
end
add_dns(appname, namespace, public_hostname) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 902
def add_dns(appname, namespace, public_hostname)
  dns = StickShift::DnsService.instance
  begin
    dns.register_application(appname, namespace, public_hostname)
    dns.publish
  ensure
    dns.close
  end
end
add_env_var(key, value) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 833
def add_env_var(key, value)
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.add_env_var(key, value)
  end
  raise f[0][:exception] if(f.length > 0)  
  reply
end
add_group_override(from, to) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1270
def add_group_override(from, to)
  prof = @profile_name_map[@default_profile]
  prof.group_overrides = [] if prof.group_overrides.nil?
  prof.group_overrides << [from, to]
end
add_node_settings(gears=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 871
def add_node_settings(gears=nil)
  reply = ResultIO.new
  
  gears = self.gears unless gears
  
  if @user.env_vars || @user.ssh_keys || @user.system_ssh_keys
    tag = ""
    handle = RemoteJob.create_parallel_job
    RemoteJob.run_parallel_on_gears(gears, handle) { |exec_handle, gear|
      @user.env_vars.each do |key, value|
        job = gear.env_var_job_add(key, value)
        RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
      end if @user.env_vars
      @user.ssh_keys.each do |key_name, key_info|
        job = gear.ssh_key_job_add(key_info["key"], key_info["type"], key_name)
        RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
      end if @user.ssh_keys
      @user.system_ssh_keys.each do |key_name, key_info|
        job = gear.ssh_key_job_add(key_info, nil, key_name)
        RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
      end if @user.system_ssh_keys
    }
    RemoteJob.get_parallel_run_results(handle) { |tag, gear, output, status|
      if status != 0
        raise StickShift::NodeException.new("Error applying settings to gear: #{gear} with status: #{status} and output: #{output}", 143)
      end
    }
  end
  reply
end
add_to_requires_feature(feature) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 85
def add_to_requires_feature(feature)
  prof = @profile_name_map[@default_profile]
  if self.scalable
    # add to the proxy component
    comp_name = "proxy" if comp_name.nil?
    prof = @profile_name_map[@default_profile]
    cinst = ComponentInstance::find_component_in_cart(prof, self, comp_name, self.get_name_prefix)
    raise StickShift::NodeException.new("Cannot find component '#{comp_name}' in app #{self.name}.", "-101", result_io) if cinst.nil?
    comp,profile,cart = cinst.get_component_definition(self)
    raise StickShift::UserException.new("#{feature} already embedded in '#{@name}'", 101) if comp.depends.include? feature
    fcart = self.framework
    conn = StickShift::Connection.new("#{feature}-web-#{fcart}")
    conn.components = ["proxy/#{feature}", "web/#{fcart}"]
    prof.add_connection(conn)
    conn = StickShift::Connection.new("#{feature}-proxy-#{fcart}")
    conn.components = ["proxy/#{feature}", "proxy/#{fcart}"]
    prof.add_connection(conn)

    #  FIXME: Booya - hacks galore -- fix this to be more generic when
    #         scalable apps allow more components in SCALABLE_EMBEDDED_CARTS
    if feature == "jenkins-client-1.4"
      conn = StickShift::Connection.new("#{feature}-proxy-haproxy-1.4")
      conn.components = ["proxy/#{feature}", "proxy/haproxy-1.4"]
      prof.add_connection(conn)
    end

    comp.depends << feature
  else
    self.requires_feature.each { |cart|
      conn = StickShift::Connection.new("#{feature}-#{cart}")
      conn.components = [cart, feature]
      prof.add_connection(conn)
    }
    self.requires_feature << feature
  end
end
cleanup_and_delete() click to toggle source

convinence method to cleanup an application

# File lib/stickshift-controller/app/models/application.rb, line 314
def cleanup_and_delete
  reply = ResultIO.new
  reply.append self.destroy_dns
  reply.append self.destroy
  self.delete
  reply
end
comp_instances() click to toggle source

Provides an array version of the component instance map for saving in the datastore. @return [Array<Hash>]

# File lib/stickshift-controller/app/models/application.rb, line 1211
def comp_instances
  @comp_instance_map = {} if @comp_instance_map.nil?
  @comp_instance_map.values
end
comp_instances=(data) click to toggle source

Rebuilds the component instance map from an array of hashes or objects @param [Array<Hash>] data

# File lib/stickshift-controller/app/models/application.rb, line 1218
def comp_instances=(data)
  comp_instance_map_will_change!    
  @comp_instance_map = {} if @comp_instance_map.nil?
  data.each do |value|
    if value.class == ComponentInstance
      @comp_instance_map[value.name] = value
    else
      key = value["name"]            
      @comp_instance_map[key] = ComponentInstance.new
      @comp_instance_map[key].attributes=value
    end
  end
end
complete_namespace_update(new_ns, old_ns) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 980
def complete_namespace_update(new_ns, old_ns)
  self.comp_instances.each do |comp_inst|
    comp_inst.cart_properties.each do |prop_key, prop_value|
      comp_inst.cart_properties[prop_key] = prop_value.gsub(%r-#{old_ns}.#{Rails.configuration.ss[:domain_suffix]}/, "-#{new_ns}.#{Rails.configuration.ss[:domain_suffix]}")
    end
  end
  self.embedded.each_key do |framework|
    if self.embedded[framework].has_key?('info')
      info = self.embedded[framework]['info']
      info.gsub!(%r-#{old_ns}.#{Rails.configuration.ss[:domain_suffix]}/, "-#{new_ns}.#{Rails.configuration.ss[:domain_suffix]}")
      self.embedded[framework]['info'] = info
    end
  end

  # elaborate descriptor again to execute connections, because connections need to be renewed
  self.elaborate_descriptor
  self.execute_connections
  self.domain.namespace = new_ns
  self.save
end
conceal_port(dependency=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 748
def conceal_port(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    next if comp_inst.name == "@@app"
    next if comp_inst.parent_cart_name == self.name

    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.conceal_port(comp_inst)
    end

    # Not all cartridges will have this hook.
    f.each do |fail|
      next if fail[:exception].resultIO.exitcode == 127
      raise fail[:exception]
    end

  end
  reply
end
configure_dependencies() click to toggle source

Elaborates the descriptor, configures cartridges that were added to the application dependencies. If a node is empty after removing components, then the gear is destroyed. Errors that occur while removing cartridges are logged but no exception is thrown. If an error occurs while configuring a cartridge, then the cartirdge is deconfigures on all nodes and an exception is thrown.

# File lib/stickshift-controller/app/models/application.rb, line 429
def configure_dependencies
  reply = ResultIO.new
  self.class.notify_observers(:before_application_configure, {:application => self, :reply => reply})

  elaborate_descriptor

  exceptions = []
  Rails.logger.debug "Configure order is #{self.configure_order.inspect}"
  #process new additions
  #TODO: fix configure after framework cartridge is no longer a requirement for adding embedded cartridges
  self.configure_order.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if comp_inst.parent_cart_name == self.name
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    begin
      group_inst.fulfil_requirements(self)
      run_on_gears(group_inst.get_unconfigured_gears(comp_inst), reply) do |gear, r|
        doExpose = false
        if self.scalable and comp_inst.parent_cart_name!=self.proxy_cartridge
          doExpose = true if not gear.configured_components.include? comp_inst.name
        end
        r.append gear.configure(comp_inst, @init_git_url)
        begin
          r.append gear.expose_port(comp_inst) if doExpose
        rescue Exception=>e
        end
        process_cartridge_commands(r)
      end
    rescue Exception => e
      Rails.logger.debug e.message
      Rails.logger.debug e.backtrace.inspect        
      
      successful_gears = []
      successful_gears = e.message[:successful].map{|g| g[:gear]} if e.message[:successful]
      failed_gears = []
      failed_gears = e.message[:failed].map{|g| g[:gear]} if e.message[:failed]
      gear_exception = e.message[:exception]

      #remove failed component from all gears
      run_on_gears(successful_gears, reply, false) do |gear, r|
        r.append gear.deconfigure(comp_inst)
        process_cartridge_commands(r)
      end
      run_on_gears(failed_gears, reply, false) do |gear, r|
        r.append gear.deconfigure(comp_inst, true)
        process_cartridge_commands(r)
      end
      
      # destroy any unused gears
      # TODO : if the destroy fails below... the user still sees the error as configure failure
      #   Then to recover, if we re-elaborate (like in add_dependency), then the group instance will get lost
      #   and any failed gears below will leak (i.e. they exist on node, their destroy failed, but they do not have any handle in Mongo)
      run_on_gears(group_inst.gears, reply, false) do |gear, r|
        r.append group_inst.remove_gear(gear) if gear.configured_components.length == 0
      end

      self.save
      exceptions << gear_exception
    end
  end
  
  unless exceptions.empty?
    raise exceptions.first
  end
  
  self.save
  self.class.notify_observers(:after_application_configure, {:application => self, :reply => reply})
  reply
end
container() click to toggle source

Get the ApplicationContainerProxy object for the first gear the application is running on @return [ApplicationContainerProxy] @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1157
def container
  return nil if self.gear.nil?
  return self.gear.get_proxy
end
create() click to toggle source

Processes the application descriptor and creates all the gears necessary to host the application. Destroys application on all gears if any gear fails @return [ResultIO]

# File lib/stickshift-controller/app/models/application.rb, line 273
def create
  result_io = ResultIO.new
  gears_created = []
  begin
    self.node_profile = DEFAULT_NODE_PROFILE unless self.node_profile
    elaborate_descriptor
    self.class.notify_observers(:before_application_create, {:application => self, :reply => result_io})
    if self.scalable
      raise StickShift::UserException.new("Scalable app cannot be of type #{UNSCALABLE_FRAMEWORKS.join(' ')}", "108", result_io) if UNSCALABLE_FRAMEWORKS.include? framework
      min_gear_count = 0
      group_instances.uniq.each { |gi|
        min_gear_count += gi.min
      }
      if ((user.consumed_gears+min_gear_count) > user.max_gears)
        raise StickShift::UserException.new("#{user.login} has a gear limit of #{user.max_gears} and this app requires #{min_gear_count} gears.", 104) 
      end
    end
    user.applications << self
    Rails.logger.debug "Creating gears"
    group_instances.uniq.each do |ginst|
      create_result, new_gear = ginst.add_gear(self)
      result_io.append create_result
    end

    self.gear.name = self.name unless scalable
    self.class.notify_observers(:application_creation_success, {:application => self, :reply => result_io})              
  rescue Exception => e
    Rails.logger.debug e.message
    Rails.logger.debug e.backtrace.join("\n")
    Rails.logger.debug "Rolling back application gear creation"
    result_io.append self.destroy
    self.class.notify_observers(:application_creation_failure, {:application => self, :reply => result_io})
    raise
  ensure
    save
  end
  self.class.notify_observers(:after_application_create, {:application => self, :reply => result_io})
  result_io
end
create_dns() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 912
def create_dns
  reply = ResultIO.new
  self.class.notify_observers(:before_create_dns, {:application => self, :reply => reply})    
  public_hostname = self.container.get_public_hostname

  add_dns(@name, @domain.namespace, public_hostname)

  self.class.notify_observers(:after_create_dns, {:application => self, :reply => reply})    
  reply
end
delete() click to toggle source

Deletes the application object from the datastore

# File lib/stickshift-controller/app/models/application.rb, line 266
def delete
  super(user.login)
end
destroy() click to toggle source

Destroys all gears. Logs message but does not throw an exception on failure to delete any particular gear.

# File lib/stickshift-controller/app/models/application.rb, line 323
def destroy
  reply = ResultIO.new
  self.class.notify_observers(:before_application_destroy, {:application => self, :reply => reply})

  #only need to destroy if application has been elaborated first
  unless self.configure_order.nil?
    # Destroy in the reverse order of configure.
    group_instances = []
    self.configure_order.reverse.each do |comp_inst_name|
      comp_inst = self.comp_instance_map[comp_inst_name]
      next if comp_inst.parent_cart_name == self.name
      group_inst = self.group_instance_map[comp_inst.group_instance_name]
      group_instances.delete(group_inst)
      group_instances << group_inst
    end

    failures = []
    group_instances.each do |group_inst|
      s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
        r.append group_inst.remove_gear(gear)
      end
      failures += f
    end

    begin
      self.save if self.persisted?
    rescue Exception => e
      # pass on failure... because we maybe wanting a delete here instead anyway
    end

    failures.each do |data|
      Rails.logger.debug("Unable to clean up application on gear #{data[:gear]} due to exception #{data[:exception].message}")
      Rails.logger.debug(data[:exception].backtrace.inspect)
    end

    raise StickShift::NodeException.new("Could not destroy all gears of application.", 1, reply) if failures.length > 0
  end
  self.class.notify_observers(:after_application_destroy, {:application => self, :reply => reply})    
  reply
end
destroy_dns() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 923
def destroy_dns
  reply = ResultIO.new
  self.class.notify_observers(:before_destroy_dns, {:application => self, :reply => reply})
  dns = StickShift::DnsService.instance
  begin
    dns.deregister_application(@name,@domain.namespace)
    if self.scalable
      # find the group instance where the web-cartridge is residing
      self.group_instance_map.keys.each { |ginst_name|
        ginst = self.group_instance_map[ginst_name]
        ginst.gears.each { |gear|
          dns.deregister_application(gear.name,@domain.namespace)
        }
      }
    end
    dns.publish
  ensure
    dns.close
  end
  self.class.notify_observers(:after_destroy_dns, {:application => self, :reply => reply})  
  reply
end
elaborate_descriptor() { |deleted_components_list| ... } click to toggle source

Parse the descriptor and build or update the runtime descriptor structure

# File lib/stickshift-controller/app/models/application.rb, line 1277
def elaborate_descriptor
  self.group_instance_map = {} if group_instance_map.nil?
  self.comp_instance_map = {} if comp_instance_map.nil?
  self.working_comp_inst_hash = {}
  self.working_group_inst_hash = {}
  self.group_override_map = {} 
  self.conn_endpoints_list = [] 
  default_profile = @profile_name_map[@default_profile]

  default_profile.groups.each { |g|
    #gpath = self.name + "." + g.name
    gpath = self.get_name_prefix + g.get_name_prefix
    gi = working_group_inst_hash[gpath]
    if gi.nil?
      gi = self.group_instance_map[gpath]
      if gi.nil?
        gi = GroupInstance.new(self, self.name, self.default_profile, g.name, gpath) 
      else
        gi.merge(self.name, self.default_profile, g.name, gpath)
      end
    else
      gi.merge(self.name, self.default_profile, g.name, gpath)
    end
    self.group_instance_map[gpath] = gi
    self.working_group_inst_hash[gpath] = gi
    gi.elaborate(default_profile, g, self.get_name_prefix, self)
  }
  
  # make connection_endpoints out of provided connections
  default_profile.connections.each { |conn|
    inst1 = ComponentInstance::find_component_in_cart(default_profile, self, conn.components[0], self.get_name_prefix)
    inst2 = ComponentInstance::find_component_in_cart(default_profile, self, conn.components[1], self.get_name_prefix)
    ComponentInstance::establish_connections(inst1, inst2, self)
  }
  # check self.comp_instance_map for component instances
  # check self.group_instance_map for group instances
  # check self.conn_endpoints_list for list of connection endpoints (fully resolved)

  # resolve group co-locations
  colocate_groups
  
  # get configure_order and start_order
  get_exec_order(default_profile)

  deleted_components_list = []
  self.comp_instance_map.each { |k,v| deleted_components_list << k if self.working_comp_inst_hash[k].nil?  }
  
  yield deleted_components_list if block_given?
  
  # delete entries in {group,comp}_instance_map that do 
  # not exist in working_{group,comp}_inst_hash
  self.group_instance_map.delete_if { |k,v| 
    v.component_instances.delete(k) if self.working_comp_inst_hash[k].nil? and v.component_instances.include?(k)
    self.working_group_inst_hash[k].nil?
  }
  self.comp_instance_map.delete_if { |k,v| self.working_comp_inst_hash[k].nil?  }
end
embedded() click to toggle source

Provide a list of direct dependencies of the application that are hosted on the same gear as the "framework" cartridge. @return [Array<String>] @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1186
def embedded
  embedded_carts = CartridgeCache.cartridge_names('embedded')
  retval = {}
  self.comp_instance_map.values.each do |comp_inst|
    if embedded_carts.include?(comp_inst.parent_cart_name)
      if comp_inst.cart_data.first.nil?
        retval[comp_inst.parent_cart_name] = comp_inst.cart_properties
      else
        retval[comp_inst.parent_cart_name] = comp_inst.cart_properties.merge({"info" => comp_inst.cart_data.first})
      end
    end
  end
  retval
end
execute_connections() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 499
def execute_connections
  return if not self.scalable

  self.conn_endpoints_list.each { |conn|
    pub_inst = self.comp_instance_map[conn.from_comp_inst]
    pub_ginst = self.group_instance_map[pub_inst.group_instance_name]

    tag = ""
    handle = RemoteJob.create_parallel_job
    RemoteJob.run_parallel_on_gears(pub_ginst.gears, handle) { |exec_handle, gear|
      appname = gear.name
      connector_name = conn.from_connector.name
      cart = pub_inst.parent_cart_name
      input_args = [appname, self.domain.namespace, gear.uuid]
      
      job = gear.get_execute_connector_job(cart, connector_name, input_args)
      RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
    }
    pub_out = []
    RemoteJob.get_parallel_run_results(handle) { |tag, gear, output, status|
      if status==0
        pub_out.push("'#{gear}'='#{output}'")
      end
    }
    input_to_subscriber = Shellwords::shellescape(pub_out.join(' '))
    Rails.logger.debug "Output of publisher - '#{pub_out}'"

    sub_inst = self.comp_instance_map[conn.to_comp_inst]
    sub_ginst = self.group_instance_map[sub_inst.group_instance_name]
    handle = RemoteJob.create_parallel_job
    RemoteJob.run_parallel_on_gears(sub_ginst.gears, handle) { |exec_handle, gear|
      appname = gear.name
      connector_name = conn.to_connector.name
      cart = sub_inst.parent_cart_name
      input_args = [appname, self.domain.namespace, gear.uuid, input_to_subscriber]
      
      job = gear.get_execute_connector_job(cart, connector_name, input_args)
      RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
    }
    # we dont care about subscriber's output/status
  }
end
expose_port(dependency=nil) click to toggle source

Invokes #expose_port for a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge

# File lib/stickshift-controller/app/models/application.rb, line 726
def expose_port(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    next if comp_inst.name == "@@app"
    next if comp_inst.parent_cart_name == self.name

    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.expose_port(comp_inst)
    end

    # Not all cartridges will have this hook.
    f.each do |fail|
      next if fail[:exception].resultIO.exitcode == 127
      raise fail[:exception]
    end

  end
  reply
end
extended_validator() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 44
def extended_validator
  notify_observers(:validate_application)
end
force_stop(dependency=nil, throw_exception_on_failure=true) click to toggle source

Force stop a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge to stop. Set to nil for all dependencies. @param [Boolean] throw_exception_on_failure

# File lib/stickshift-controller/app/models/application.rb, line 598
def force_stop(dependency=nil, throw_exception_on_failure=true)
  reply = ResultIO.new
  self.class.notify_observers(:before_force_stop, {:application => self, :reply => reply, :dependency => dependency})
  self.start_order.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)

    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.force_stop(comp_inst)
    end

    raise f[0][:exception] if(f.length > 0 and throw_exception_on_failure)
  end
  self.class.notify_observers(:after_force_stop, {:application => self, :reply => reply, :dependency => dependency})
  reply    
end
framework() click to toggle source

Get the name of framework cartridge in use by the application @return [String] @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1174
def framework
  framework_carts = CartridgeCache.cartridge_names('standalone')
  self.comp_instance_map.each { |cname, cinst|
    cartname = cinst.parent_cart_name
    return cartname if framework_carts.include? cartname
  }
  return nil
end
framework_cartridge() click to toggle source

Get the name of framework cartridge in use by the application without the version suffix @return [String] @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1165
def framework_cartridge  
  fcart = self.framework
  return fcart.split('-')[0..-2].join('-') unless fcart.nil?
  return nil
end
gear() click to toggle source

Returns the first Gear object on which the application is running @return [Gear] @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1121
def gear
  if self.group_instances.nil?
    elaborate_descriptor
  end
  
  if scalable
    self.group_instance_map.keys.each { |ginst_name|
      return self.group_instance_map[ginst_name].gears.first if ginst_name.include? self.proxy_cartridge
    }
  end

  group_instance = self.group_instances.first
  return nil unless group_instance
  
  return group_instance.gears.first
end
gears() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 368
def gears
  self.group_instances.uniq.map{ |ginst| ginst.gears }.flatten
end
get_name_prefix() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1266
def get_name_prefix
  return "@@app"
end
get_public_ip_address() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1109
def get_public_ip_address
  begin
    return self.container.get_public_ip_address
  rescue Exception=>e
    Rails.logger.debug e.backtrace.inspect
    return nil
  end
end
group_instances() click to toggle source

Provides an array version of the group instance map for saving in the datastore. @return [Array<Hash>]

# File lib/stickshift-controller/app/models/application.rb, line 1234
def group_instances
  @group_instance_map = {} if @group_instance_map.nil?
  values = @group_instance_map.values.uniq
  keys   = @group_instance_map.keys
  
  values.each do |group_inst|
    group_inst.reused_by = keys.clone.delete_if{ |k| @group_instance_map[k] != group_inst }
  end
  
  values
end
group_instances=(data) click to toggle source

Rebuilds the group instance map from an array of hashes or objects @param [Array<Hash>] data

# File lib/stickshift-controller/app/models/application.rb, line 1248
def group_instances=(data)
  group_instance_map_will_change!    
  @group_instance_map = {} if @group_instance_map.nil?
  data.each do |value|
    if value.class == GroupInstance
      value.reused_by.each do |k|
        @group_instance_map[k] = value
      end
    else
      ginst = GroupInstance.new(self)
      ginst.attributes=value
      ginst.reused_by.each do |k|
        @group_instance_map[k] = ginst
      end
    end
  end
end
health_check_path() click to toggle source

Get path for checking application health @return [String]

# File lib/stickshift-controller/app/models/application.rb, line 1337
def health_check_path
  case self.framework_cartridge
    when 'php'
      page = 'health_check.php'
    when 'perl'
      page = 'health_check.pl'
    else
      page = 'health'
  end
end
prepare_namespace_update(dns_service, new_ns, old_ns) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 961
def prepare_namespace_update(dns_service, new_ns, old_ns)
  updated = true
  result_io = ResultIO.new
  begin
    self.gears.each do |gear|
      gear_result_io = gear.prepare_namespace_update(dns_service, new_ns, old_ns)
      updated = false unless gear_result_io.exitcode == 0
      result_io.append gear_result_io
    end
  rescue Exception => e
    result_io.append e.resultIO if e.respond_to?('resultIO')
    updated = false
    Rails.logger.debug "Exception caught updating namespace #{e.message}"
    Rails.logger.debug "DEBUG: Exception caught updating namespace #{e.message}"
    Rails.logger.debug e.backtrace
  end 
  return { :success => updated, :result_io => result_io }
end
process_cartridge_commands(result) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1348
def process_cartridge_commands(result)
  commands = result.cart_commands
  commands.each do |command_item|
    case command_item[:command]
    when "SYSTEM_SSH_KEY_ADD"
      key = command_item[:args][0]
      self.user.add_system_ssh_key(self.name, key)
    when "SYSTEM_SSH_KEY_REMOVE"
      self.user.remove_system_ssh_key(self.name)
    when "ENV_VAR_ADD"
      key = command_item[:args][0]
      value = command_item[:args][1]
      self.user.add_env_var(key,value)
    when "ENV_VAR_REMOVE"
      key = command_item[:args][0]
      self.user.remove_env_var(key)
    when "BROKER_KEY_ADD"
      iv, token = StickShift::AuthService.instance.generate_broker_key(self)
      self.user.add_save_job('adds', 'broker_auth_keys', [self.uuid, iv, token])
    when "BROKER_KEY_REMOVE"
      self.user.add_save_job('removes', 'broker_auth_keys', [self.uuid])
    end
  end
  if user.save_jobs
    user.save
  end
  commands.clear
end
recreate_dns() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 946
def recreate_dns
  reply = ResultIO.new
  self.class.notify_observers(:before_recreate_dns, {:application => self, :reply => reply})    
  dns = StickShift::DnsService.instance
  begin
    public_hostname = self.container.get_public_hostname
    dns.modify_application(@name, @domain.namespace, public_hostname)
    dns.publish
  ensure
    dns.close
  end
  self.class.notify_observers(:after_recreate_dns, {:application => self, :reply => reply})    
  reply
end
reload(dependency=nil) click to toggle source

Reload a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge to reload. Set to nil for all dependencies.

# File lib/stickshift-controller/app/models/application.rb, line 638
def reload(dependency=nil)
  reply = ResultIO.new
  self.class.notify_observers(:before_reload, {:application => self, :reply => reply, :dependency => dependency})
  self.start_order.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.reload(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)
  end
  self.class.notify_observers(:after_reload, {:application => self, :reply => reply, :dependency => dependency})
  reply
end
remove_alias(server_alias) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1024
def remove_alias(server_alias)
  self.aliases = [] unless self.aliases
  reply = ResultIO.new
  begin
    reply.append self.container.remove_alias(self, self.gear, self.framework, server_alias)
  rescue Exception => e
    Rails.logger.debug e.message
    Rails.logger.debug e.backtrace.inspect
    raise
  ensure
    if self.aliases.include? server_alias
      self.aliases.delete(server_alias)
      self.save
    else
      raise StickShift::UserException.new("Alias '#{server_alias}' does not exist for '#{@name}'", 255, reply)
    end      
  end
  reply
end
remove_authorized_ssh_key(ssh_key, comment=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 824
def remove_authorized_ssh_key(ssh_key, comment=nil)
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.remove_authorized_ssh_key(ssh_key, comment)
  end
  raise f[0][:exception] if(f.length > 0)    
  reply
end
remove_broker_key() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 862
def remove_broker_key
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.remove_broker_auth_key
  end
  raise f[0][:exception] if(f.length > 0)    
  reply
end
remove_dependency(dep) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1070
def remove_dependency(dep)
  reply = ResultIO.new
  self.class.notify_observers(:before_remove_dependency, {:application => self, :dependency => dep, :reply => reply})
  self.embedded = {} unless self.embedded
      
  raise StickShift::UserException.new("#{dep} not embedded in '#{@name}', try adding it first", 101) unless self.embedded.include? dep
  raise StickShift::UserException.new("#{dep} is not allowed to be removed from '#{@name}'. It is a required dependency for a scalable application.", 101) if (self.scalable and self.proxy_cartridge==dep)
  remove_from_requires_feature(dep)
  elaborate_descriptor { |removed_component_instances|
    #remove unused components
    removed_component_instances.each do |comp_inst_name|
      comp_inst = self.comp_instance_map[comp_inst_name]
      next if comp_inst.parent_cart_name == self.name
      group_inst = self.group_instance_map[comp_inst.group_instance_name]
      s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
        unless gear.configured_components.length == 1 && gear.configured_components.first == comp_inst.name
          reply.append gear.deconfigure(comp_inst)
          process_cartridge_commands(r)
        end
      end

      f.each do |failed_data|
        Rails.logger.debug("Failed to deconfigure cartridge #{comp_inst.parent_cart_name} on gear #{failed_data[:gear].server_identity}:#{failed_data[:gear].uuid}")
        Rails.logger.debug("Exception #{failed_data[:exception].message}")
        Rails.logger.debug("#{failed_data[:exception].backtrace.inspect}")
      end

      run_on_gears(group_inst.gears, reply, false) do |gear, r|
        if gear.configured_components.empty? || (gear.configured_components.length == 1 && gear.configured_components.first == comp_inst.name)
          reply.append group_inst.remove_gear(gear)
        end
      end
    end
  }
  self.save
  self.class.notify_observers(:after_remove_dependency, {:application => self, :dependency => dep, :reply => reply})
  reply
end
remove_env_var(key) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 842
def remove_env_var(key)
  reply = ResultIO.new
  s,f = run_on_gears(nil,reply,false) do |gear,r|
    r.append gear.remove_env_var(key)
  end
  raise f[0][:exception] if(f.length > 0)    
  reply
end
remove_from_requires_feature(feature) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 148
def remove_from_requires_feature(feature)
  prof = @profile_name_map[@default_profile]
  if prof.connection_name_map
    prof.connection_name_map.delete_if {|k,v| v.components[0].include? feature or v.components[1].include? feature }
  end
  if self.scalable
    comp_name = "proxy" if comp_name.nil?
    prof = @profile_name_map[@default_profile]
    cinst = ComponentInstance::find_component_in_cart(prof, self, comp_name, self.get_name_prefix)
    raise StickShift::NodeException.new("Cannot find component '#{comp_name}' in app #{self.name}.", "-101", result_io) if cinst.nil?
    comp,profile,cart = cinst.get_component_definition(self)
    raise StickShift::UserException.new("#{feature} not embedded in '#{@name}', try adding it first", 101) if not comp.depends.include? feature
    comp.depends.delete(feature)
  else
    self.requires_feature.delete feature
  end
end
restart(dependency=nil) click to toggle source

Restart a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge to restart. Set to nil for all dependencies.

# File lib/stickshift-controller/app/models/application.rb, line 618
def restart(dependency=nil)
  reply = ResultIO.new
  self.class.notify_observers(:before_restart, {:application => self, :reply => reply, :dependency => dependency})
  self.start_order.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.restart(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)
  end
  self.class.notify_observers(:after_restart, {:application => self, :reply => reply, :dependency => dependency})
  reply    
end
save() click to toggle source

Saves the application object in the datastore

# File lib/stickshift-controller/app/models/application.rb, line 258
def save
  super(user.login)
  self.ngears = 0
  self.usage_records = nil
  self.destroyed_gears = []
end
scaledown(comp_name=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 394
def scaledown(comp_name=nil)
  result_io = ResultIO.new
  if not self.scalable
    raise StickShift::UserException.new("Cannot scale a non-scalable application", 255, result_io)
  end
  comp_name = "web" if comp_name.nil?
  prof = @profile_name_map[@default_profile]
  cinst = ComponentInstance::find_component_in_cart(prof, self, comp_name, self.get_name_prefix)
  raise StickShift::NodeException.new("Cannot find #{comp_name} in app #{self.name}.", 1, result_io) if cinst.nil?
  ginst = self.group_instance_map[cinst.group_instance_name]
  raise StickShift::NodeException.new("Cannot find group #{cinst.group_instance_name} for #{comp_name} in app #{self.name}.", 1, result_io) if ginst.nil?
  # remove any gear out of this ginst
  raise StickShift::UserException.new("Cannot scale below minimum gear requirements for group '#{ginst.min}'", 1, result_io) if ginst.gears.length <= ginst.min

  gear = ginst.gears.first

  dns = StickShift::DnsService.instance
  begin
    dns.deregister_application(gear.name, @domain.namespace)
    dns.publish
  ensure
    dns.close
  end

  result_io.append ginst.remove_gear(gear)

  # inform anyone who needs to know that this gear is no more
  self.configure_dependencies
  self.execute_connections
  result_io
end
scaleup(comp_name=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 372
def scaleup(comp_name=nil)
  result_io = ResultIO.new

  if not self.scalable
    raise StickShift::UserException.new("Cannot scale a non-scalable application", 255, result_io)
  end

  comp_name = "web" if comp_name.nil?
  prof = @profile_name_map[@default_profile]
  cinst = ComponentInstance::find_component_in_cart(prof, self, comp_name, self.get_name_prefix)
  raise StickShift::NodeException.new("Cannot find #{comp_name} in app #{self.name}.", 1, result_io) if cinst.nil?
  ginst = self.group_instance_map[cinst.group_instance_name]
  raise StickShift::NodeException.new("Cannot find group #{cinst.group_instance_name} for #{comp_name} in app #{self.name}.", 1, result_io) if ginst.nil?
  raise StickShift::UserException.new("Cannot scale up beyond maximum gear limit '#{ginst.max}' in app #{self.name}.", 104, result_io) if ginst.gears.length >= ginst.max and ginst.max > 0
  raise StickShift::UserException.new("Cannot scale up beyond gear limit '#{user.max_gears}'", 104, result_io) if user.consumed_gears >= user.max_gears
  result, new_gear = ginst.add_gear(self)
  result_io.append result
  result_io.append self.configure_dependencies
  self.execute_connections
  result_io
end
scaling_limits(dependency=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1138
def scaling_limits(dependency=nil)
  if dependency.nil?
    if self.scalable
      dependency = "web" 
    else
      dependency = self.framework
    end
  end
  prof = @profile_name_map[@default_profile]
  cinst = ComponentInstance::find_component_in_cart(prof, self, dependency, self.get_name_prefix)
  raise StickShift::NodeException.new("Cannot find #{dependency} component in app #{self.name}.", "-101", result_io) if cinst.nil?

  ginst = self.group_instance_map[cinst.group_instance_name]
  return ginst.min,ginst.max
end
set_embedded_cart_info(cart_name, info) click to toggle source

Provide a way of updating the component information for a given cartridge @deprecated

# File lib/stickshift-controller/app/models/application.rb, line 1203
def set_embedded_cart_info(cart_name, info)
  self.comp_instance_map.values.each do |comp_inst|
    comp_inst.cart_data = [info] if cart_name == comp_inst.parent_cart_name
  end
end
show_port(dependency=nil) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 770
def show_port(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    next if comp_inst.name == "@@app"
    next if comp_inst.parent_cart_name == self.name

    Rails.logger.debug( comp_inst.inspect )
    Rails.logger.debug( "\n" )

    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.show_port(comp_inst)
    end

    # Not all cartridges will have this hook.
    f.each do |fail|
      next if fail[:exception].resultIO.exitcode == 127
      raise fail[:exception]
    end

  end
  reply
end
show_state() click to toggle source

Get the state of the application on all gears.

# File lib/stickshift-controller/app/models/application.rb, line 796
def show_state()
  gear_states = {}
  tag = ""
  handle = RemoteJob.create_parallel_job
  RemoteJob.run_parallel_on_gears(self.gears, handle) { |exec_handle, gear|
    job = gear.app_state_job_show()
    RemoteJob.add_parallel_job(exec_handle, tag, gear, job)
  }
  RemoteJob.get_parallel_run_results(handle) { |tag, gear, output, status|
    if status != 0
      Rails.logger.error("Error getting application state from gear: '#{gear}' with status: '#{status}' and output: #{output}", 143)
      gear_states[gear] = 'unknown'
    else
      gear_states[gear] = output
    end
  }
  gear_states
end
start(dependency=nil, stop_on_failure=true) click to toggle source

Start a particular dependency on all gears that host it. If unable to start a component, the application is stopped on all gears @param [String] dependency Name of a cartridge to start. Set to nil for all dependencies. @param [Boolean] force_stop_on_failure

# File lib/stickshift-controller/app/models/application.rb, line 546
def start(dependency=nil, stop_on_failure=true)
  reply = ResultIO.new
  self.class.notify_observers(:before_start, {:application => self, :reply => reply, :dependency => dependency})
  self.start_order.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    next if comp_inst.parent_cart_name == self.name
    
    begin
      group_inst = self.group_instance_map[comp_inst.group_instance_name]
      run_on_gears(group_inst.gears, reply) do |gear, r|
        r.append gear.start(comp_inst)
      end
    rescue Exception => e
      gear_exception = e.message[:exception]
      self.stop(dependency,false,false) if stop_on_failure
      raise gear_exception
    end
  end
  self.class.notify_observers(:after_start, {:application => self, :reply => reply, :dependency => dependency})
  reply
end
status(dependency=nil) click to toggle source

Retrieves status for a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge

# File lib/stickshift-controller/app/models/application.rb, line 658
def status(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.status(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)      
  end
  reply
end
stop(dependency=nil, force_stop_on_failure=true, throw_exception_on_failure=true) click to toggle source

Stop a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge to start. Set to nil for all dependencies. @param [Boolean] force_stop_on_failure @param [Boolean] throw_exception_on_failure

# File lib/stickshift-controller/app/models/application.rb, line 573
def stop(dependency=nil, force_stop_on_failure=true, throw_exception_on_failure=true)
  reply = ResultIO.new
  self.class.notify_observers(:before_stop, {:application => self, :reply => reply, :dependency => dependency})
  self.start_order.reverse.each do |comp_inst_name|
    comp_inst = self.comp_instance_map[comp_inst_name]
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    next if comp_inst.parent_cart_name == self.name
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.stop(comp_inst)
    end

    if(f.length > 0)
      self.force_stop(dependency,false) if(force_stop_on_failure)
      raise f[0][:exception] if(throw_exception_on_failure)
    end
  end
  self.class.notify_observers(:after_stop, {:application => self, :reply => reply, :dependency => dependency})
  reply
end
system_messages(dependency=nil) click to toggle source

Invokes #system_messages for a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge

# File lib/stickshift-controller/app/models/application.rb, line 709
def system_messages(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.system_messages(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)      
  end
  reply
end
template_scalable_app(app_name, framework) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 122
  def template_scalable_app(app_name, framework)
    return "
Name: #{app_name}
Components:
  proxy:
    Dependencies: [#{framework}, \"haproxy-1.4\"]
  web:
    Dependencies: [#{framework}]
Groups:
  proxy:
    Components:
      proxy: proxy
  web:
    Components:
      web: web
GroupOverrides: 
  - [\"proxy\", \"proxy/haproxy-1.4\"]
  - [\"proxy\", \"proxy/#{framework}\"]
  - [\"web\", \"web/#{framework}\"]
Connections:
  auto-scale:
    Components: [\"proxy/haproxy-1.4\", \"web/#{framework}\"]
Configure-Order: [\"proxy/#{framework}\", \"proxy/haproxy-1.4\"]
"
  end
threaddump(dependency=nil) click to toggle source

Invokes threaddump for a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge

# File lib/stickshift-controller/app/models/application.rb, line 692
def threaddump(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.threaddump(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)      
  end
  reply
end
tidy(dependency=nil) click to toggle source

Invokes tidy for a particular dependency on all gears that host it. @param [String] dependency Name of a cartridge

# File lib/stickshift-controller/app/models/application.rb, line 675
def tidy(dependency=nil)
  reply = ResultIO.new
  self.comp_instance_map.each do |comp_inst_name, comp_inst|
    next if !dependency.nil? and (comp_inst.parent_cart_name != dependency)
    
    group_inst = self.group_instance_map[comp_inst.group_instance_name]
    s,f = run_on_gears(group_inst.gears, reply, false) do |gear, r|
      r.append gear.tidy(comp_inst)
    end
    
    raise f[0][:exception] if(f.length > 0)      
  end
  reply
end
track_usage(gear, event, usage_type=UsageRecord::USAGE_TYPES[:gear_usage]) click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 1377
def track_usage(gear, event, usage_type=UsageRecord::USAGE_TYPES[:gear_usage])
  if Rails.configuration.usage_tracking[:datastore_enabled]
    now = Time.now.utc
    uuid = StickShift::Model.gen_uuid
    self.usage_records = [] unless usage_records
    usage_record = UsageRecord.new(event, user, now, uuid, usage_type)
    case usage_type
    when UsageRecord::USAGE_TYPES[:gear_usage]
      usage_record.gear_uuid = gear.uuid
      usage_record.gear_size = gear.node_profile
    when UsageRecord::USAGE_TYPES[:addtl_fs_gb]
      usage_record.gear_uuid = gear.uuid
      usage_record.addtl_fs_gb = gear.group_instance.addtl_fs_gb
    end
    self.usage_records << usage_record
    
    self.class.notify_observers(:track_usage, {:gear_uuid => gear.uuid, :login => gear.app.user.login, :event => event, :time => now, :uuid => uuid, :usage_type => usage_type, :gear_size => gear.node_profile, :addtl_fs_gb => gear.group_instance.addtl_fs_gb})
  end
  if Rails.configuration.usage_tracking[:syslog_enabled]
    usage_string = "User: #{user.login}  Event: #{event}"
    case usage_type
    when UsageRecord::USAGE_TYPES[:gear_usage]
      usage_string += "   Gear: #{gear.uuid}   Gear Size: #{gear.node_profile}"
    when UsageRecord::USAGE_TYPES[:addtl_fs_gb]
      usage_string += "   Gear: #{gear.uuid}   Addtl File System GB: #{gear.group_instance.addtl_fs_gb}"
    end
    begin
      Syslog.open('openshift_usage', Syslog::LOG_PID) { |s| s.notice usage_string }
    rescue Exception => e
      # Can't fail because of a secondary logging error
      Rails.logger.error e.message
      Rails.logger.error e.backtrace
    end
  end
end
web_cart() click to toggle source
# File lib/stickshift-controller/app/models/application.rb, line 364
def web_cart
  return framework 
end