module Publisher class Dweb attr_accessor :staging_host attr_accessor :ssh_key_file attr_accessor :siteid # possible commands: # patch # uploadreq [patch] [content_only|config_only] [overwrite|activate] # [tomcatrestart] [description|desc=text description] # list [describe] # revisions [describe] # tomcatrestart # activatereq # view apache # view tomcat # view userdefined # move current logs # debug with: # ssh -i apps/deploy_engine/etc/ssh/id_rsa.deployadmin dwebuser@dei[iup]2s.dweb.intranet.db.com # > 'enter command' def send_command(command, options={}) Helper.validates_presence_of staging_host, "Staging Host not set" Helper.validates_presence_of ssh_key_file, "SSH keyfile not set" Helper.validates_presence_of siteid, "Siteid not set" result = '' joined_filename = File.join(File.dirname($exec_file_path), ssh_key_file) ssh_key_file = joined_filename # overwrite siteid for multi target deployments if not options[:siteid].nil? self.siteid = options[:siteid] end # check ssh keyfile if not File.file? ssh_key_file $log.writer.error "Can not find SSH keyfile #{ssh_key_file}" exit 1 end ### Probleme auf UAT und PROD if command.include? "list" return result end Net::SSH.start(staging_host, "dwebuser", \ :auth_methods => ['publickey'], \ :forward_agent => false, \ :keys => ssh_key_file, \ :timeout => 90 ) do |session| session.open_channel do |ch| ch.exec "/scripts/dwebuser #{siteid}" do |ch, success| if not success $log.writer.error "Can not execute dwebuser command" exit 1 end ch.on_data do |ch, data| if not data.empty? result << data if command.include? "list" result_a = result.split("\n") test = result_a.last if not test.nil? and test.length > 0 $log.writer.info "Deployment Status: #{test}" end end end end # something on stderr? ch.on_extended_data do |ch, type, data| # dirty filter for non critical return messages if data =~ /^ERROR.*/ $log.writer.error \ "Received error from dwebuser command: #{data}" exit 1 else $log.writer.debug \ "Received output from dwebuser command: #{data}" end end ch.on_close do |ch| result << "all done, closing ssh channel!" end ch.send_data command + "\n" end ch.wait end end $log.writer.debug result return result end def upload(source, target, options={}) Helper.validates_presence_of staging_host, "Staging Host not set" Helper.validates_presence_of ssh_key_file, "SSH keyfile not set" result = '' joined_filename = File.join(File.dirname($exec_file_path), ssh_key_file) ssh_key_file = joined_filename # overwrite siteid for multi target deployments if not options[:siteid].nil? self.siteid = options[:siteid] end Helper.validates_presence_of siteid, "Siteid not set" # check ssh keyfile if not File.file? ssh_key_file $log.writer.error "Can not find SSH keyfile #{ssh_key_file}" exit 1 end # first connection to delete files begin if not options[:cleanup] == false Net::SFTP.start(staging_host, siteid + 'f', \ :auth_methods => ['publickey'], \ :forward_agent => false, \ :keys => ssh_key_file, \ :timeout => 90 ) do |session| # delete all files in target, but not the target-dir itself $log.writer.debug "Cleaning remote directory #{target}" session.rm_r!(target) end end # second connection to upload files processing_file = "" Net::SCP.start(staging_host, siteid + 'f', \ :auth_methods => ['publickey'], \ :forward_agent => false, \ :keys => ssh_key_file, \ :timeout => 90 ) do |session| Dir.glob(File.join(source, '/*'), File::FNM_DOTMATCH) do |entry| if not entry =~ /\.$/ processing_file = entry if not options[:excludes].nil? if options[:excludes].any? {|term| entry.include? term } $log.writer.debug "Exclude #{entry} from upload" else $log.writer.debug "Upload #{entry}" session.upload!(entry, File.join(target, '/'), \ :recursive => true) end else $log.writer.debug "Upload #{entry}" session.upload!(entry, File.join(target, '/'), \ :recursive => true) end end end end rescue Exception => e $log.writer.error "Can not upload file #{processing_file} to #{target}" $log.writer.error e.message $log.writer.error e.backtrace.join("\n") exit 1 end end def remote_symlink(source, symlink, options={}) Helper.validates_presence_of staging_host, "Staging Host not set" Helper.validates_presence_of ssh_key_file, "SSH keyfile not set" result = '' joined_filename = File.join(File.dirname($exec_file_path), ssh_key_file) ssh_key_file = joined_filename # overwrite siteid for multi target deployments if not options[:siteid].nil? self.siteid = options[:siteid] end Helper.validates_presence_of siteid, "Siteid not set" # check ssh keyfile if not File.file? ssh_key_file $log.writer.error "Can not find SSH keyfile #{ssh_key_file}" exit 1 end begin Net::SFTP.start(staging_host, siteid + 'f', \ :auth_methods => ['publickey'], \ :forward_agent => false, \ :keys => ssh_key_file, \ :timeout => 90 ) do |session| begin if session.lstat!(symlink).type == Net::SFTP::Protocol::V01::Attributes::T_SYMLINK $log.writer.debug "Delete already existing link #{symlink}" session.remove!(symlink) end rescue # maybe the link does not exist yet, or the remove faild # anyway, we try to create it end session.symlink!(source, symlink) end rescue Exception => e $log.writer.error "Can not create remote symlink #{symlink} to #{source} " $log.writer.error e.message $log.writer.error e.backtrace.join("\n") exit 1 end true end end end class Net::SFTP::Session def rm_r!(path, options={}) @rm_depth = 0 if @rm_depth.nil? self.dir.entries(path).each do |entry| next if entry.name == '.' or entry.name == '..' child_path = File.join(path, entry.name) if self.lstat!(child_path).directory? @rm_depth = @rm_depth + 1 self.rm_r!(child_path) @rm_depth = @rm_depth - 1 else self.remove!(child_path) end end if @rm_depth != 0 or options[:delete_root] self.rmdir!(path) end end end