[Title] // auto restart and upgrade dibs
authordev.sungmin.kim <dev.sungmin.kim@samsung.com>
Tue, 28 Aug 2012 02:13:17 +0000 (11:13 +0900)
committerdev.sungmin.kim <dev.sungmin.kim@samsung.com>
Tue, 28 Aug 2012 02:13:17 +0000 (11:13 +0900)
[Type]      //
[Module]    //
[Priority]  //
[CQ#]       //
[Redmine#]  // 6435
[Problem]   //
[Cause]     //
[Solution]  //
[TestCase]  //

build-svr
package/pkginfo.manifest
src/build_server/BuildServer.rb
src/build_server/BuildServerController.rb
src/build_server/BuildServerOptionParser.rb
src/build_server/SocketJobRequestListener.rb
src/common/utils.rb
upgrade [new file with mode: 0755]

index 42861b692b676145d528ae4273c58a6440c6c015..3a3e458eedb9dc5c72833767ff6cf95980e6790e 100755 (executable)
--- a/build-svr
+++ b/build-svr
@@ -81,9 +81,35 @@ begin
        when "remove"
                BuildServerController.remove_server( option[:name] ) 
        when "start"
-               BuildServerController.start_server( option[:name], option[:port] ) 
+               if( option[:child] ) then # Child Process
+                       BuildServerController.start_server( option[:name], option[:port] ) 
+               else  # Parent Process
+                       while(true)
+                               # Start child process
+                               cmd = Utils.execute_shell_generate("#{File.dirname(__FILE__)}/build-svr start -n #{option[:name]} -p #{option[:port]} --CHILD")
+                               IO.popen(cmd)
+                               pid = Process.wait
+
+                               # End chlid process
+                               puts "Child terminated, pid = # #{pid}, status = #{$?.exitstatus}"
+                               if ($?.exitstatus == 0) then # SERVER STOP COMMAND
+                                       break
+                               elsif ($?.exitstatus == 99) then # DIBS UPGRADE
+                                       puts "Down Build Server for DIBS upgrade. [STATUS:#{$?.exitstatus}]"
+                                       cmd = "#{File.dirname(__FILE__)}/upgrade -l #{File.dirname(__FILE__)} -S -t BUILDSERVER -n #{option[:name]} -p #{option[:port]}" 
+                                       cmd = Utils.execute_shell_generate(cmd)
+                                       puts cmd
+                                       Utils.spawn(cmd)
+                                       break
+                               else
+                                       puts "Down Build Server. Try reboot Build Server.[STATUS:#{$?.exitstatus}]"
+                               end
+                       end
+               end
        when "stop"
                BuildServerController.stop_server( option[:name] ) 
+       when "upgrade"
+               BuildServerController.upgrade_server( option[:name] ) 
        when "add-svr"
                if not option[:domain].nil? then
                svr_result = Utils.parse_server_addr(option[:domain])
index d725739cd725003cc91965c109ad09a6955df5b5..3c883780a2b10ca2d19ee8d1561dc955505c4f67 100644 (file)
@@ -1,5 +1,5 @@
 Source : dibs
-Version :0.99.19
+Version :0.99.20
 Maintainer : taejun ha<taejun.ha@samsung.com>, jiil hyoun <jiil.hyoun@samsung.com>, donghyuk yang <donghyouk.yang@samsung.com>, donghee yang <donghee.yang@samsung.com>, sungmin kim <dev.sungmin.kim@samsung.com
 
 Package : dibs
index cb47347a08ff37470125ed70c7893e07e9f532a7..9de9b93e018c89a8172edfe360b8d86736c06b65 100644 (file)
@@ -57,6 +57,7 @@ class BuildServer
        attr_accessor :transport_path
        attr_accessor :cancel_lock
        attr_accessor :supported_os_list
+       attr_accessor :upgrade
        attr_accessor :remote_pkg_servers
        attr_accessor :pkg_sync_period
 
@@ -107,6 +108,7 @@ class BuildServer
                @supported_os_list = []
 
                @pkg_sync_period=600
+               @upgrade = false
        end
 
 
@@ -180,6 +182,9 @@ class BuildServer
                        @log.error( e.message, Log::USER)
                end
 
+               if(@upgrade)
+                       exit(99)
+               end
                # TODO: something should be done for server down
 
        end
index eef50cbb3ce14f5b33b217ecf4323d41b0282663..4be6726521b7de1b1a2236447b58ae15dbd508de 100644 (file)
@@ -157,6 +157,94 @@ class BuildServerController
                return true
        end
 
+       # upgrade server
+       def self.upgrade_server( id )
+
+               # server
+               server = get_server(id)
+               client = BuildCommClient.create( "127.0.0.1", server.port )
+               if client.nil? then
+                       puts "Server is not running!"
+                       return false
+               end
+
+               # send request
+               upgrade_ok = false
+               if client.send "UPGRADE|#{server.password}" then
+                       # recevie & print
+                       mismatched = false
+                       result = client.read_lines do |l|
+                               puts l
+                               if l.include? "Password mismatched!" then
+                                       mismatched = true
+                               end
+                       end
+                       if result and not mismatched then
+                               upgrade_ok = true
+                       end
+               end
+
+               # terminate     
+               client.terminate
+       
+               if not upgrade_ok then  
+                       puts "Server upgrade failed!"
+               end
+
+               return true
+       end
+
+       # request upgrade friends build server
+       def self.request_upgrade_server( id )
+
+               server = get_server(id)
+               server_dir = "#{BuildServer::CONFIG_ROOT}/#{id}"
+       
+               if File.exist? "#{server_dir}/friends" then
+                       File.open( "#{server_dir}/friends", "r" ) do |f|
+                               f.each_line do |l|
+                                       if l.split(",").count < 2 then next end
+                                       ip = l.split(",")[0].strip
+                                       port = l.split(",")[1].strip
+       
+                                       client = BuildCommClient.create( ip, port )
+                                       if client.nil? then
+                                               puts "Friend Server #{ip}:#{port} is not running!"
+                                               next    
+                                       end
+                                       # send request
+                                       upgrade_ok = false
+                                       if client.send "UPGRADE|#{server.password}" then
+                                               # recevie & print
+                                               mismatched = false
+                                               result = client.read_lines do |l|
+                                                       puts l
+                                                       if l.include? "Password mismatched!" then
+                                                               mismatched = true
+                                                       end
+                                               end
+                                               if result and not mismatched then
+                                                       upgrade_ok = true
+                                               end
+                                       end
+       
+                                       # terminate     
+                                       client.terminate
+       
+                                       if upgrade_ok then      
+                                               puts "Friend Server #{ip}:#{port} upgrade requested!"
+                                       else
+                                               puts "Friend Server #{ip}:#{port} upgrade failed!"
+                                       end
+                               end
+                       end
+               else
+                       puts "No Friend Server."
+               end             
+               
+               return true
+       end
+
 
        # add friend server
        def self.add_friend_server( id, ip, port )
index 14be325103a253888ac656c8788f876834cb1e7d..831cd0cf21214418380526f0a7566b9527063348 100644 (file)
@@ -57,6 +57,11 @@ def option_error_check( options )
             raise ArgumentError, "Usage: build-svr stop -n <server name>"
         end
 
+    when "upgrade"
+        if options[:name].nil? or options[:name].empty? then
+            raise ArgumentError, "Usage: build-svr upgrade -n <server name>"
+        end
+
     when "add-svr"
         if options[:name].nil? or options[:name].empty? or 
                        ((options[:domain].nil? or options[:domain].empty?) and
@@ -100,6 +105,7 @@ def option_parse
        + "\t" + "remove        Remove the build-server." + "\n" \
        + "\t" + "start         Start the build-server." + "\n" \
        + "\t" + "stop          Stop the build-server." + "\n" \
+       + "\t" + "upgrade       Upgrade the build-server include friends." + "\n" \
        + "\t" + "add-svr       Add remote build/package server for support multi-OS or distribute build job." + "\n" \
        + "\t" + "add-prj       Register information for project what you want build berfore building a project." + "\n" \
        + "\t" + "register      Register the package to the build-server." + "\n" \
@@ -190,11 +196,16 @@ def option_parse
             puts "DIBS(Distributed Intelligent Build System) version 1.2.0"
                        exit
         end
+
+               opts.on( '-C', '--CHILD', 'child process' ) do
+            options[:child] = true
+        end
                
     end
     
        cmd = ARGV[0] 
-    if cmd.eql? "create" or cmd.eql? "remove" or cmd.eql? "start" or 
+    if cmd.eql? "create" or cmd.eql? "remove" or 
+               cmd.eql? "start" or cmd.eql? "upgrade" or
                cmd.eql? "stop" or cmd.eql? "add-svr" or
                cmd.eql? "add-prj" or cmd.eql? "add-os" or 
                cmd.eql? "fullbuild" or cmd.eql? "register" or 
index 1278aeecf1e52b1a0e6f1e2821f3da7a8d42315d..9a2e7f2a3de57e11730011dcbce75155491ba44f 100644 (file)
@@ -125,6 +125,8 @@ class SocketJobRequestListener
                        handle_cmd_cancel( req_line, req )
                when "STOP"
                        handle_cmd_stop( req_line, req )
+               when "UPGRADE"
+                       handle_cmd_upgrade( req_line, req )
                when "FULLBUILD"
                        handle_cmd_fullbuild( req_line, req )
                when "REGISTER"
@@ -529,6 +531,29 @@ class SocketJobRequestListener
        end
 
 
+       # "UPGRADE"
+       def handle_cmd_upgrade( line, req )
+               tok = line.split("|").map { |x| x.strip }
+               if tok.count < 2 then 
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end
+       
+               BuildCommServer.send_begin(req)
+               if tok[1] != @parent_server.password then
+                       BuildCommServer.send(req,"Password mismatched!")
+               else
+                       BuildCommServer.send(req,"Server will be down!")
+               end
+               BuildCommServer.send_end(req)
+               BuildCommServer.disconnect(req)
+               if tok[1] == @parent_server.password then
+                       @parent_server.finish = true
+                       @parent_server.upgrade = true
+               end
+       end
+
+
        # "FULLBUILD"
        def handle_cmd_fullbuild( line, req )
                tok = line.split("|").map { |x| x.strip }
index f48ad893ffba867eee1f2dc9595d96deb38d64e2..bf7155eb9360172c6df0cc395e7bd326683ec036 100644 (file)
@@ -27,6 +27,9 @@ Contributors:
 =end
 
 class Utils
+       STARTUP_INFO_SIZE = 68
+       PROCESS_INFO_SIZE = 16
+       NORMAL_PRIORITY_CLASS = 0x00000020
 
        def Utils.identify_current_OS()
                os = "UnsupportedOS"
@@ -134,6 +137,20 @@ class Utils
         return 0
        end
 
+    def Utils.execute_shell_generate(cmd, os_category = nil)
+               result_lines = []
+
+               if os_category.nil? then os_category = get_os_category( HOST_OS ) end
+
+               if os_category == "windows" then
+                       mingw_path = "sh.exe -c "
+                       cmd = cmd.gsub("\"", "\\\"")
+            cmd = mingw_path + "\"#{cmd}\""
+               end
+
+               return cmd
+       end
+
 
     def Utils.execute_shell(cmd, os_category = nil)
         ret = false
@@ -213,6 +230,69 @@ class Utils
                end 
        end
 
+    def Utils.spawn(cmd, os_category = nil)
+               
+               if os_category.nil? then os_category = get_os_category( HOST_OS ) end
+
+               if os_category == "windows" then
+                       create_process(cmd)
+               else
+                       fork do
+                               exec(cmd)
+                       end
+               end
+
+       end
+
+       def Utils.create_process(command,redirStdout="", redirStderr="")
+
+               if redirStdout.length > 0
+                       tmpfile = File.new(redirStdout,"w")
+                       save_stdout = $stdout.clone
+                       $stdout.reopen(tmpfile)
+               end
+
+               if redirStderr.length > 0
+                       tmpfile = File.new(redirStderr,"w")
+                       save_stderr = $stderr.clone
+                       $stderr.reopen(tmpfile)
+               end
+
+               params = [
+                       'L', # IN LPCSTR lpApplicationName
+                       'P', # IN LPSTR lpCommandLine
+                       'L', # IN LPSECURITY_ATTRIBUTES lpProcessAttributes
+                       'L', # IN LPSECURITY_ATTRIBUTES lpThreadAttributes
+                       'L', # IN BOOL bInheritHandles
+                       'L', # IN DWORD dwCreationFlags
+                       'L', # IN LPVOID lpEnvironment
+                       'L', # IN LPCSTR lpCurrentDirectory
+                       'P', # IN LPSTARTUPINFOA lpStartupInfo
+                       'P'  # OUT LPPROCESS_INFORMATION lpProcessInformation
+                       ]
+               returnValue = 'I' # BOOL
+
+               startupInfo = [STARTUP_INFO_SIZE].pack('I') + ([0].pack('I') * (STARTUP_INFO_SIZE - 4))
+               processInfo = [0].pack('I') * PROCESS_INFO_SIZE
+
+               createProcess = Win32API.new("kernel32", "CreateProcess", params, returnValue)
+
+               createProcess.call(0, command, 0, 0, 0, NORMAL_PRIORITY_CLASS, 0, 0, startupInfo, processInfo)
+
+               if redirStdout.length > 0
+                       $stdout.reopen(save_stdout)
+               end
+
+               save_stdout.close if save_stdout
+
+               if redirStderr.length > 0
+                       $stderr.reopen(save_stderr)
+               end
+
+               save_stderr.close if save_stderr
+
+               ($0 == __FILE__ ) ? processInfo : processInfo.unpack("LLLL")[2]
+       end     
 
        def Utils.is_absolute_path(path)
                if is_unix_like_os( HOST_OS ) then  
diff --git a/upgrade b/upgrade
new file mode 100755 (executable)
index 0000000..28887bc
--- /dev/null
+++ b/upgrade
@@ -0,0 +1,232 @@
+#!/usr/bin/ruby -d
+=begin
+ upgrade
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+Sungmin Kim <dev.sungmin.kim@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+require 'optparse'
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/build_server"
+require "utils.rb"
+require "BuildServerController"
+
+def option_error_check( options )
+       if options[:start] then
+       if options[:locate].nil? or options[:type].nil? or options[:name].nil? then
+                       raise ArgumentError, "upgrade upgrade -l <dibs path> -S -t <server type> -n <server name> -p <server port>" + "\n"
+               end
+       else
+       if options[:locate].nil? or options[:url].nil? then
+                       raise ArgumentError, "upgrade upgrade -l <dibs path> -u <package server url>" + "\n" 
+               end
+    end
+end
+
+def option_parse 
+    options = {}
+    banner = "DIBS upgrade service command-line tool." + "\n" \
+       + "\n" + "Usage: upgrade -l <dibs path> -u <package server url>" + "\n" \
+       + "\n" + "Options:" + "\n"
+
+    optparse = OptionParser.new(nil, 32, ' '*8) do|opts|
+               opts.banner = banner 
+
+        opts.on( '-l', '--locate <dibs path>', 'located dibs path' ) do|locate|
+            options[:locate] = locate
+        end
+
+               opts.on( '-u', '--url <package server url>', 'package server url: http://127.0.0.1/dibs/unstable' ) do|url|
+            options[:url] = url 
+        end
+
+               opts.on( '-I', '--install', 'install, internal option' ) do
+            options[:install] = true
+        end
+
+               opts.on( '-S', '--start', 'start server option' ) do
+            options[:start] = true
+        end
+
+        opts.on( '-t', '--type <server type>', 'sever type : BUILDSERVER or PACKAGESERVER' ) do|type|
+            options[:type] = type
+        end
+
+        opts.on( '-n', '--name <server name>', 'build server name or package server  name' ) do|name|
+            options[:name] = name 
+        end
+
+        options[:port] = 2222
+               opts.on( '-p', '--port <port>', 'server port number: 2224' ) do|port|
+            options[:port] = port.strip.to_i
+        end
+
+               opts.on( '-h', '--help', 'display this information' ) do
+            puts opts
+                       exit
+        end
+       end
+
+    optparse.parse!
+
+    option_error_check options
+   
+    return options
+end 
+
+#option parsing 
+begin
+       option = option_parse
+rescue => e
+       puts e.message
+       exit 0
+end
+
+# Upgrade DIBS
+begin
+       install_opt = option[:install]
+       sub_cmd = option[:sub_cmd]
+       dibs_path = option[:locate]
+       pkg_svr_url= option[:url]
+       start_opt = option[:start]
+       svr_type = option[:type]
+       svr_name = option[:name]
+       svr_port = option[:port]
+
+       DIBS_PKG_NAME = "dibs"
+       BACKUP_ROOT = Utils::HOME + "/.build_tools/backup"
+       PREV_VER_PATH = BACKUP_ROOT + "/prev_ver"
+       NEW_VER_PATH = BACKUP_ROOT + "/new_ver"
+       UPGRADE_CMD = "#{PREV_VER_PATH}/upgrade"
+       BUILD_CONFIG_ROOT = "#{Utils::HOME}/.build_tools/build_server/#{svr_name}"
+       BUILD_FRIENDS_FILE = "#{BUILD_CONFIG_ROOT}/friends"
+
+
+       if not install_opt then
+               # Backup current dibs
+               if File.exist? BACKUP_ROOT then FileUtils.rm_rf(BACKUP_ROOT) end
+               FileUtils.mkdir_p(PREV_VER_PATH)
+               FileUtils.mkdir_p(NEW_VER_PATH)
+               FileUtils.cp_r("#{dibs_path}/.", PREV_VER_PATH, :preserve => true)
+               puts "Backup DIBS [#{dibs_path}] -> [#{PREV_VER_PATH}]"
+
+               # Run Upgrade
+               if start_opt then
+                       cmd = "#{UPGRADE_CMD} -I -l #{dibs_path} -S -t #{svr_type} -n #{svr_name} -p #{svr_port}"
+               else
+                       cmd = "#{UPGRADE_CMD} -I -l #{dibs_path} -u #{pkg_svr_url}"
+               end
+
+               cmd = Utils.execute_shell_generate(cmd)
+               puts cmd
+               Utils.spawn(cmd)
+
+       else
+               # Get SERVER INFORMATION
+               if svr_type.eql? "BUILDSERVER" then
+                       build_server = BuildServerController.get_server(svr_name)
+                       pkg_svr_url = build_server.pkgserver_url
+               end
+
+               # Download DIBS Package
+       client = Client.new( pkg_svr_url, NEW_VER_PATH, nil )
+       client.update()
+               client.install( DIBS_PKG_NAME, Utils::HOST_OS, true, true) 
+
+               # Copy Current path
+               if File.exist? "#{dibs_path}" then 
+                       FileUtils.rm_rf("#{dibs_path}") 
+                       FileUtils.mkdir_p("#{dibs_path}")
+               end
+               if File.exist? "#{NEW_VER_PATH}/tools/dibs" then
+                       FileUtils.cp_r("#{NEW_VER_PATH}/tools/dibs/.", "#{dibs_path}", :preserve => true)
+               else
+                       puts "Not installed package error."
+                       exit(1)
+               end
+
+               # Execute start command
+               if svr_type.eql? "BUILDSERVER" then
+                       # get friends server information
+                       if File.exist? BUILD_FRIENDS_FILE then
+                               File.open( BUILD_FRIENDS_FILE, "r" ) do |f|
+                                       f.each_line do |l|
+                                               if l.split(",").count < 2 then 
+                                                       next 
+                                               end
+
+                                               ip = l.split(",")[0].strip
+                                               port = l.split(",")[1].strip
+               
+                                               build_client = BuildCommClient.create( ip, port )
+                                               if build_client.nil? then
+                                                       puts "Friend Server #{ip}:#{port} is not running!"
+                                                       next    
+                                               end
+
+                                               # send request
+                                               if build_client.send "UPGRADE|#{build_server.password}" then
+                                                       # recevie & print
+                                                       mismatched = false
+                                                       result = build_client.read_lines do |l|
+                                                               puts l
+                                                               if l.include? "Password mismatched!" then
+                                                                       mismatched = true
+                                                               end
+                                                       end
+                                                       if result and not mismatched then
+                                                               puts "Friend Server #{ip}:#{port} upgrade failed!"
+                                                       else
+                                                               puts "Friend Server #{ip}:#{port} upgrade requested!"
+                                                       end
+                                               end
+               
+                                               # terminate     
+                                               build_client.terminate
+                                       end
+                               end
+                       else
+                               puts "No Friend Server."
+                       end             
+
+                       # Start Build server
+                       cmd = Utils.execute_shell_generate("#{dibs_path}/build-svr start -n #{svr_name} -p #{svr_port}")
+                       #IO.popen(cmd)
+                       Utils.spawn(cmd)
+
+               else # PACKAGE SERVER
+                       # Start Build server
+                       cmd = Utils.execute_shell_generate("#{dibs_path}/pkg-svr start -n #{svr_name} -p #{svr_port}")
+                       #IO.popen("#{dibs_path}/pkg-svr start -n #{svr_name} -p #{svr_port}")
+                       Utils.spawn(cmd)
+               end
+       puts "Upgrade Complete"
+       end
+rescue => e
+       puts e.message
+end
+