DIBS: Added -x option 96/15696/1
authorjonghwan2.park <jonghwan2.park@samsung.com>
Mon, 27 Jan 2014 07:36:42 +0000 (16:36 +0900)
committerjonghwan2.park <jonghwan2.park@samsung.com>
Mon, 27 Jan 2014 07:36:42 +0000 (16:36 +0900)
Build cli command line tool can make sdk image with exception package list.

Change-Id: I43083583aaf8d03af1217de51e31a34a6ce0bb87
Signed-off-by: jonghwan2.park <jonghwan2.park@samsung.com>
package/changelog
package/pkginfo.manifest
pkg-cli
src/pkg_server/client.rb
src/pkg_server/clientOptParser.rb

index 5221be2..0b76b16 100644 (file)
@@ -1,3 +1,6 @@
+* 2.1.58
+- Added make-image option [-x] for except packages
+== jonghwan park <jonghwan2.park@samsung.com> 2014-01-27
 * 2.1.57
 - Fixed marshar error bug and some minor bugs
 == donghee yang <donghee.yang@samsung.com> 2014-01-23
index c7d4c03..a127315 100644 (file)
@@ -1,6 +1,6 @@
 Source : dibs
-Version :2.1.57
-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
+Version :2.1.58
+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, jonghwan park <jonghwan2.park@samsung.com>
 
 Package : tizen-dibs-test
 Label : DIBS Test Tools
diff --git a/pkg-cli b/pkg-cli
index b524f30..f82b80c 100755 (executable)
--- a/pkg-cli
+++ b/pkg-cli
@@ -44,210 +44,209 @@ require "packageServer"
 
 #option parsing
 begin
-       option = option_parse
+    option = option_parse
 rescue => e
-       # if option parse error print help message
-       puts e.message
-       exit 0
+    # if option parse error print help message
+    puts e.message
+    exit 0
 end
 
 # check HOST OS
 if not Utils.check_host_OS() then
 
-       if Utils.is_linux_like_os Utils::HOST_OS then
-               Utils.set_default_linux_host_os
-               puts "Warning: Your host OS is not supported!\nWe assume your host OS as #{Utils::HOST_OS} !!!"
-       else
-               puts "Error: Your host OS is not supported!"
-               exit 1
-       end
+    if Utils.is_linux_like_os Utils::HOST_OS then
+        Utils.set_default_linux_host_os
+        puts "Warning: Your host OS is not supported!\nWe assume your host OS as #{Utils::HOST_OS} !!!"
+    else
+        puts "Error: Your host OS is not supported!"
+        exit 1
+    end
 end
 #if "--os" is not specfied, use host os type
 if option[:os].nil? then
-       option[:os] = Utils::HOST_OS
+    option[:os] = Utils::HOST_OS
 end
 
 case option[:cmd]
 when "clean" then
-       client = Client.create( nil, option[:loc], nil, false )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.clean(option[:f])
+    client = Client.create( nil, option[:loc], nil, false )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.clean(option[:f])
 when "download" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       file_loc = client.download( option[:pkg], option[:os], option[:t] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    file_loc = client.download( option[:pkg], option[:os], option[:t] )
 when "make-img" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end
-       client.make_img( option[:os], option[:info] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.make_img( option[:os], option[:info], option[:el] )
 when "dep-graph" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end
-       client.gen_dep_graph( option[:os], option[:type] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.gen_dep_graph( option[:os], option[:type] )
 when "install" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.install( option[:pkg], option[:os], option[:t], option[:f] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.install( option[:pkg], option[:os], option[:t], option[:f] )
 when "install-file" then
-       if option[:t] then
-               client = Client.create( option[:url], option[:loc], nil )
-               if client.nil? then
-                       puts "Error: Cannot create package client!"
-                       exit 1
-               end                     
-               client.install_local_pkg( option[:pkg], option[:t], option[:f] )
-       else
-               client = Client.create( nil, option[:loc], nil, false )
-               if client.nil? then
-                       puts "Error: Cannot create package client!"
-                       exit 1
-               end                     
-               client.install_local_pkg( option[:pkg], option[:t], option[:f] )
-       end                     
+    if option[:t] then
+        client = Client.create( option[:url], option[:loc], nil )
+        if client.nil? then
+            puts "Error: Cannot create package client!"
+            exit 1
+        end
+        client.install_local_pkg( option[:pkg], option[:t], option[:f] )
+    else
+        client = Client.create( nil, option[:loc], nil, false )
+        if client.nil? then
+            puts "Error: Cannot create package client!"
+            exit 1
+        end
+        client.install_local_pkg( option[:pkg], option[:t], option[:f] )
+    end
 when "uninstall" then
-       client = Client.create( nil, option[:loc], nil, false )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.uninstall( option[:pkg], option[:t] )
+    client = Client.create( nil, option[:loc], nil, false )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.uninstall( option[:pkg], option[:t] )
 when "upgrade" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.upgrade( option[:os], option[:t] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.upgrade( option[:os], option[:t] )
 when "check-upgrade" then
-       client = Client.create( option[:url], option[:loc], nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.check_upgrade( option[:os] )
+    client = Client.create( option[:url], option[:loc], nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.check_upgrade( option[:os] )
 when "show-rpkg" then
-       client = Client.create( option[:url], nil, nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       puts client.show_pkg_info( option[:pkg], option[:os] )
+    client = Client.create( option[:url], nil, nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    puts client.show_pkg_info( option[:pkg], option[:os] )
 when "list-rpkg" then
-       client = Client.create( option[:url], nil, nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       result = client.show_pkg_list( option[:os] )
-       if not result.nil? and not result.empty? then
-               result.each do |i|
-                       name = i[0].strip
-                       version = i[1].strip
-                       desc = i[2].strip
-                       puts name + "  (" + version + ")"
-               end
-       end
+    client = Client.create( option[:url], nil, nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    result = client.show_pkg_list( option[:os] )
+    if not result.nil? and not result.empty? then
+        result.each do |i|
+            name = i[0].strip
+            version = i[1].strip
+            desc = i[2].strip
+            puts name + "  (" + version + ")"
+        end
+    end
 when "show-lpkg" then
-       client = Client.create( nil, option[:loc], nil, false )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       puts client.show_installed_pkg_info( option[:pkg] )
+    client = Client.create( nil, option[:loc], nil, false )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    puts client.show_installed_pkg_info( option[:pkg] )
 when "list-lpkg" then
-       client = Client.create( nil, option[:loc], nil, false )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       result = client.show_installed_pkg_list()
-       if not result.nil? and not result.empty? then
-               result.each do |i|
-                       name = i[0].strip
-                       version = i[1].strip
-                       desc = i[2].strip
-                       puts name + "  (" + version + ")"
-               end
-       else
-               puts "Info: There is no any package."
-       end
+    client = Client.create( nil, option[:loc], nil, false )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    result = client.show_installed_pkg_list()
+    if not result.nil? and not result.empty? then
+        result.each do |i|
+            name = i[0].strip
+            version = i[1].strip
+            desc = i[2].strip
+            puts name + "  (" + version + ")"
+        end
+    else
+        puts "Info: There is no any package."
+    end
 when "build-dep" then
-       client = Client.create( option[:url], nil, nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       result = client.get_build_dependent_packages( option[:pkg], option[:os], true )
-       if result.nil? then
-               puts "Error: Failed to get remote package list. try update first."
-               exit 1
-       end                     
-       ret = ""
-       result.each do |i|
-               ret = ret + i + " --> "
-       end
-       ret = ret.strip
-       ret[-3..-1] = ""
-       puts ret
+    client = Client.create( option[:url], nil, nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    result = client.get_build_dependent_packages( option[:pkg], option[:os], true )
+    if result.nil? then
+        puts "Error: Failed to get remote package list. try update first."
+        exit 1
+    end
+    ret = ""
+    result.each do |i|
+        ret = ret + i + " --> "
+    end
+    ret = ret.strip
+    ret[-3..-1] = ""
+    puts ret
 when "install-dep" then
-       client = Client.create( option[:url], nil, nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       result = client.get_install_dependent_packages( option[:pkg], option[:os], true, false )
-       if result.nil? then
-               puts "Error: Failed to get remote package list. try update first."
-               exit 1
-       end                     
-       ret = ""
-       result.each do |i|
-               ret = ret + i + " --> "
-       end
-       ret = ret.strip
-       ret[-3..-1] = ""
-       puts ret
+    client = Client.create( option[:url], nil, nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    result = client.get_install_dependent_packages( option[:pkg], option[:os], true, false )
+    if result.nil? then
+        puts "Error: Failed to get remote package list. try update first."
+        exit 1
+    end
+    ret = ""
+    result.each do |i|
+        ret = ret + i + " --> "
+    end
+    ret = ret.strip
+    ret[-3..-1] = ""
+    puts ret
 when "register" then
-       client = Client.create( nil, nil, nil )
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.register(option[:address], option[:dist], option[:pkg], option[:passwd])
+    client = Client.create( nil, nil, nil )
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.register(option[:address], option[:dist], option[:pkg], option[:passwd])
 when "snapshotlist" then
-       client = Client.create(option[:url],nil,nil);
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       client.printSnapshotList(option[:all]);
+    client = Client.create(option[:url],nil,nil);
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    client.printSnapshotList(option[:all]);
 when "changelog" then
-       client = Client.create(option[:url], nil, nil);
-       if client.nil? then
-               puts "Error: Cannot create package client!"
-               exit 1
-       end                     
-       if option[:snapshot].nil?() then
-       client.printChangeLog();
-       else
-       client.printChangeLog(option[:snapshot][0], option[:snapshot][1]);
-       end
+    client = Client.create(option[:url], nil, nil);
+    if client.nil? then
+        puts "Error: Cannot create package client!"
+        exit 1
+    end
+    if option[:snapshot].nil?() then
+        client.printChangeLog();
+    else
+        client.printChangeLog(option[:snapshot][0], option[:snapshot][1]);
+    end
 else
-       raise RuntimeError, "Input is incorrect : #{option[:cmd]}"
+    raise RuntimeError, "Input is incorrect : #{option[:cmd]}"
 end
-
index 0007fa5..b4b5749 100644 (file)
@@ -54,335 +54,335 @@ $get_snapshot_mutex = Mutex.new
 $cache_mutex = Mutex.new
 class Client
 
-       # constant
-       PKG_LIST_FILE_PREFIX = "pkg_list_"
-       INSTALLED_PKG_LIST_FILE = "installedpackage.list"
-       CONFIG_PATH = "#{PackageServerConfig::CONFIG_ROOT}/client"
-       PACKAGE_INFO_DIR = ".info"
-       DEFAULT_INSTALL_DIR = "#{Utils::HOME}/build_root"
-       #DEFAULT_SERVER_ADDR = "http://172.21.17.55/dibs/unstable"
-       OS_INFO_FILE = "os_info"
-       ARCHIVE_PKG_LIST_FILE = "archive_pkg_list"
-
-       attr_accessor :server_addr, :location, :pkg_hash_os, :is_server_remote, :installed_pkg_hash_loc, :archive_pkg_list, :all_dep_list, :log, :support_os_list, :config_dist_path, :download_path, :tmp_path, :snapshot_path, :snapshots_path, :snapshot_url
-       private_class_method :new
-
-       public
-       # initialize
-       # create "remote package hash" and "installed package hash"
-       # @server_addr = server address (can be included distribution, snapshot)
-       # @location = client location (download and install file to this location)
-       def initialize(server_addr, location, logger, access_svr = true)
-
-               # set log
-               if logger.nil? or logger.class.to_s.eql? "String" then
-                       @log = DummyLog.new()
-               else
-                       @log = logger
-               end
-
-               # create directory
-               if not File.exist? CONFIG_PATH then FileUtils.mkdir_p "#{CONFIG_PATH}" end
-               # set location
-               if location.nil? then location = get_default_inst_dir() end
-
-               @location = location
-               @snapshot_path = nil
-               @snapshot_url = false
-               @pkg_hash_os = {}
-               @installed_pkg_hash_loc = {}
-               @archive_pkg_list = []
-               @all_dep_list = []
-               @support_os_list = []
-               @server_addr = nil
-
-
-               # if client should access remote server, set server information
-               if access_svr then
-                       if not server_addr.nil? then
-                               # chop server address, if end with "/"
-                               if server_addr.strip.end_with? "/" then server_addr = server_addr.chop end
-                               server_addr.strip!
-
-                               if is_snapshot_url(server_addr) then
-                                       @snapshot_url = true
-                                       @server_addr, @snapshot_path = split_addr_and_snapshot(server_addr)
-                               else
-                                       @server_addr = server_addr
-                               end
-                               @is_server_remote = Utils.is_url_remote(server_addr)
-                               @config_dist_path = CONFIG_PATH + "/" + get_flat_serveraddr
-                               @download_path = @config_dist_path + "/downloads"
-                               @tmp_path = @config_dist_path + "/tmp"
-                               @snapshots_path = @config_dist_path + "/snapshots"
-       
-                               # create directory
-                               if not File.exist? @config_dist_path then FileUtils.mkdir_p "#{@config_dist_path}" end
-                               if not File.exist? @download_path then FileUtils.mkdir_p "#{@download_path}" end
-                               if not File.exist? @snapshots_path then FileUtils.mkdir_p "#{@snapshots_path}" end
-                               if not File.exist? @tmp_path then FileUtils.mkdir_p "#{@tmp_path}" end
-                       end             
-               end
-
-               @configs = {}
-               #default cache size = 8G
-               @configs[:CACHE_SIZE] = "8000"
-       end
-
-
-       public
-       def self.create(server_addr, location, logger, access_svr = true)
-               new_client = new(server_addr, location, logger, access_svr )
-               if new_client.init(access_svr) then
-                       return new_client
-               else
-                       return nil
-               end
-       end
-
-
-       public
-       def init(access_svr)
-               if access_svr then
-                       # read remote pkg list, and hash list
-                       @log.info "Update remote package list and supported os list.."
-                       if update() then 
-                               @log.info "Initialize - #{@server_addr}, #{@location}" 
-                       else 
-                               @log.error "Failed to update remote package list."
-                               return false
-                       end
-               end
-
-               # read installed pkg list, and create hash
-               if not File.exist? @location then FileUtils.mkdir_p "#{@location}" end
-               @log.info "Update local package list.. [#{@location}]"
-               read_installed_pkg_list()
-
-               return true
-       end
-
-
-       # make cache clean
-       private
-       def remove_old_files_in_cache
-               #get dir info
-               cache_list = get_cache_dir_list
-               cache_info_list = Utils.get_sub_files_info(cache_list).sort {|a,b| a[3] <=> b[3]} # [path,size,ctime,mtime]
-               cache_size = 0
-               cache_info_list.each {|file| cache_size += file[1]}
-
-               read_configs
-               max_cache_size = get_config_max_cache_size
-
-               extra_size = cache_size - max_cache_size
-
-               if extra_size < 0 then return end
-
-               remove_list = []
-               while extra_size > 0 do
-                       old_package = cache_info_list.shift
-                       remove_list.push old_package[0]
-                       extra_size -= old_package[1]
-               end
-
-               if not remove_list.empty? then
-                       @log.info "Removed oldest package files.. (Now not fully caching)"
-                       @log.info "  * #{remove_list.map{|path| File.basename(path)}.join(", ")}"
-                       FileUtils.rm_rf remove_list
-               end
-       end
-
-       private
-       def get_cache_dir_list
-               return Dir.entries(CONFIG_PATH).select{|dir| not dir.start_with? "." and File.directory? CONFIG_PATH + "/#{dir}/downloads" }.map{|dir| CONFIG_PATH + "/#{dir}/downloads"}
-       end
-
-       private
-       def get_config_max_cache_size
-               return (@configs[:CACHE_SIZE] =~ /^([0-9][0-9]*)$/i)?  ($1.to_i * 1024 * 1024)  :  (8 * 1024 * 1024 * 1024) #default size 4G : unit = MB
-       end
-
-       private
-       def read_configs
-               file_path = CONFIG_PATH + "/config"
-               if not File.exist? file_path then return end
-
-               File.open file_path, "r" do |f|
-                       f.each_line do |l|
-                               row = l.split(":")
-                               @configs[row[0].strip.to_sym] = row[1..-1].join(":").strip
-                       end
-               end
-       end
-
-
-       public
-       # update package list from server
-       def update()
-
-               if @server_addr.nil? then
-                       @log.warn "Server address is null"
-                       return false
-               end                             
-
-               if not @snapshot_url then
-                       $get_snapshot_mutex.synchronize do
-                               @snapshot_path = get_lastest_snapshot(@is_server_remote)
-                       end
-               end
-               @log.info "The lastest snapshot : #{@snapshot_path}"
-               if @snapshot_path.nil? then
-                       @log.warn "Failed to get the lastest package list."
-                       @snapshot_path = ""
-               end
-
-               exists_snapshot = false
-               if is_snapshot_exist(@snapshot_path) then
-                       @log.info "Snapshot information is already cached [#{get_pkglist_path()}]"
-                       exists_snapshot = true
-               else
-                       @log.info "Snapshot information is not cached."
-               end
-
-               list_path = get_pkglist_path()
-               if list_path.nil? then
-                       @log.error "Failed to get package list path."
-                       return false
-               end
-
-               clean_list()
-
-               if exists_snapshot then
-                       read_supported_os_list(list_path)
-                       read_remote_pkg_list(list_path)
-                       read_archive_pkg_list(list_path)
-               else
-                       $update_mutex.synchronize do
-                               uniq_name = Utils.create_uniq_name
-                               tmp_dir = File.join(@config_dist_path, uniq_name)
-                               FileUtils.mkdir_p tmp_dir
-                               if not download_os_list(@is_server_remote, tmp_dir) then
-                                       @log.error "\"#{@server_addr}\" does not have supported os list file properly."
-                                       Utils.execute_shell("rm -rf #{tmp_dir}")
-                                       return false
-                               else read_supported_os_list(tmp_dir) end
-
-                               if not download_pkg_list(@is_server_remote, tmp_dir) then
-                                       @log.error "\"#{@server_addr}\" does not have package list file properly."
-                                       Utils.execute_shell("rm -rf #{tmp_dir}")
-                                       return false
-                               else read_remote_pkg_list(tmp_dir) end
-
-                               if not download_archive_pkg_list(@is_server_remote, tmp_dir) then
-                                       @log.error "\"#{@server_addr}\" does not have archive package list file properly. This error can be ignored"
-                               else read_archive_pkg_list(tmp_dir)     end
-                               Utils.execute_shell("mv #{tmp_dir} #{list_path}")
-                               @log.info "Moved \"#{tmp_dir}\" to"
-                               @log.info "  \"#{list_path}\""
-                               # tmp_dir should be removed  whether mv command is failed
-                               Utils.execute_shell("rm -rf #{tmp_dir}")
-                               remove_snapshots()
-                       end
-               end
-
-               @log.info "Update package list from \"#{@server_addr}\".. OK"
-
-               return true
-       end
-
-       private
-       def clean_list()
-               @pkg_hash_os.clear
-               @archive_pkg_list.clear
-               @support_os_list.clear
-               @log.info "Cleard package list, supported os list.. OK"
-       end
-
-       public
-       # download package
-       def download(pkg_name, os, trace, loc = nil)
-
-               if loc.nil? then loc = @location end
-
-               if not File.exist? loc then FileUtils.mkdir_p "#{loc}" end
-
-               dependent_pkg_list = []
-
-               # get dependent list
-               if trace then
-                       dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, true)
-                       if dependent_pkg_list.nil? then
-                               @log.error "Failed to get dependency for \"#{pkg_name}\" package"
-                               return nil
-                       end
-               else dependent_pkg_list = [pkg_name] end
-
-               surl = @server_addr
-               # download files
-               file_local_path = []
-               dependent_pkg_list.each do |p|
-                       pkg_name = get_attr_from_pkg(p, os, "name")
-                       pkg_path = get_attr_from_pkg(p, os, "path")
-                       pkg_ver = get_attr_from_pkg(p, os, "version")
-                       pkg_checksum = get_attr_from_pkg(p, os, "checksum")
-                       pkg_size = get_attr_from_pkg(p, os, "size")
-                       if pkg_path.nil? or pkg_ver.nil? then
-                               @log.error "\"#{p}\" package does not exist in package server. Check if it exist in package server"
-                               return nil
-                       end
-                       url = surl + pkg_path
-                       filename = File.basename pkg_path
-
-                       file_path = get_file_from_cache(filename, pkg_checksum, pkg_size, loc)
-                       if file_path.nil? then
-
-                               file_path = File.join(loc, filename)
-
-                               result = FileDownLoader.download(url, loc, @log)
-                               if not result or not File.exist? file_path then
-                                       @log.error "File Download Failed!!"
-                                       @log.error "* #{url} -> #{loc}"
-                                       return nil
-                               end
-
-                               if Utils.validatePkgFile(file_path, pkg_checksum, pkg_size) then
-                                       add_file_to_cache(file_path)
-                               else
-                                       @log.error "File Validation Failed!!"
-                                       @log.info "Valiate : file path : #{file_path}, shasum : #{pkg_checksum}, size : #{pkg_size}", Log::LV_USER
-                                       return nil
-                               end
-                       else
-                               @log.info "Cached #{pkg_name} package file.. OK"
-                       end
-                       file_local_path.push(file_path)
-               end
-
-               if trace then
-                       @log.info "Downloaded \"#{pkg_name}\" package with all dependent packages.. OK"
-               end
-               @log.info "  [path: #{file_local_path.join(", ")}]"
-
-               return file_local_path
-       end
+    # constant
+    PKG_LIST_FILE_PREFIX = "pkg_list_"
+    INSTALLED_PKG_LIST_FILE = "installedpackage.list"
+    CONFIG_PATH = "#{PackageServerConfig::CONFIG_ROOT}/client"
+    PACKAGE_INFO_DIR = ".info"
+    DEFAULT_INSTALL_DIR = "#{Utils::HOME}/build_root"
+    #DEFAULT_SERVER_ADDR = "http://172.21.17.55/dibs/unstable"
+    OS_INFO_FILE = "os_info"
+    ARCHIVE_PKG_LIST_FILE = "archive_pkg_list"
+
+    attr_accessor :server_addr, :location, :pkg_hash_os, :is_server_remote, :installed_pkg_hash_loc, :archive_pkg_list, :all_dep_list, :log, :support_os_list, :config_dist_path, :download_path, :tmp_path, :snapshot_path, :snapshots_path, :snapshot_url
+    private_class_method :new
+
+    public
+    # initialize
+    # create "remote package hash" and "installed package hash"
+    # @server_addr = server address (can be included distribution, snapshot)
+    # @location = client location (download and install file to this location)
+    def initialize(server_addr, location, logger, access_svr = true)
+
+        # set log
+        if logger.nil? or logger.class.to_s.eql? "String" then
+            @log = DummyLog.new()
+        else
+            @log = logger
+        end
+
+        # create directory
+        if not File.exist? CONFIG_PATH then FileUtils.mkdir_p "#{CONFIG_PATH}" end
+        # set location
+        if location.nil? then location = get_default_inst_dir() end
+
+        @location = location
+        @snapshot_path = nil
+        @snapshot_url = false
+        @pkg_hash_os = {}
+        @installed_pkg_hash_loc = {}
+        @archive_pkg_list = []
+        @all_dep_list = []
+        @support_os_list = []
+        @server_addr = nil
+
+
+        # if client should access remote server, set server information
+        if access_svr then
+            if not server_addr.nil? then
+                # chop server address, if end with "/"
+                if server_addr.strip.end_with? "/" then server_addr = server_addr.chop end
+                server_addr.strip!
+
+                if is_snapshot_url(server_addr) then
+                    @snapshot_url = true
+                    @server_addr, @snapshot_path = split_addr_and_snapshot(server_addr)
+                else
+                    @server_addr = server_addr
+                end
+                @is_server_remote = Utils.is_url_remote(server_addr)
+                @config_dist_path = CONFIG_PATH + "/" + get_flat_serveraddr
+                @download_path = @config_dist_path + "/downloads"
+                @tmp_path = @config_dist_path + "/tmp"
+                @snapshots_path = @config_dist_path + "/snapshots"
+
+                # create directory
+                if not File.exist? @config_dist_path then FileUtils.mkdir_p "#{@config_dist_path}" end
+                if not File.exist? @download_path then FileUtils.mkdir_p "#{@download_path}" end
+                if not File.exist? @snapshots_path then FileUtils.mkdir_p "#{@snapshots_path}" end
+                if not File.exist? @tmp_path then FileUtils.mkdir_p "#{@tmp_path}" end
+            end
+        end
+
+        @configs = {}
+        #default cache size = 8G
+        @configs[:CACHE_SIZE] = "8000"
+    end
+
+
+    public
+    def self.create(server_addr, location, logger, access_svr = true)
+        new_client = new(server_addr, location, logger, access_svr )
+        if new_client.init(access_svr) then
+            return new_client
+        else
+            return nil
+        end
+    end
+
+
+    public
+    def init(access_svr)
+        if access_svr then
+            # read remote pkg list, and hash list
+            @log.info "Update remote package list and supported os list.."
+            if update() then 
+                @log.info "Initialize - #{@server_addr}, #{@location}" 
+            else 
+                @log.error "Failed to update remote package list."
+                return false
+            end
+        end
+
+        # read installed pkg list, and create hash
+        if not File.exist? @location then FileUtils.mkdir_p "#{@location}" end
+        @log.info "Update local package list.. [#{@location}]"
+        read_installed_pkg_list()
+
+        return true
+    end
+
+
+    # make cache clean
+    private
+    def remove_old_files_in_cache
+        #get dir info
+        cache_list = get_cache_dir_list
+        cache_info_list = Utils.get_sub_files_info(cache_list).sort {|a,b| a[3] <=> b[3]} # [path,size,ctime,mtime]
+        cache_size = 0
+        cache_info_list.each {|file| cache_size += file[1]}
+
+        read_configs
+        max_cache_size = get_config_max_cache_size
+
+        extra_size = cache_size - max_cache_size
+
+        if extra_size < 0 then return end
+
+        remove_list = []
+        while extra_size > 0 do
+            old_package = cache_info_list.shift
+            remove_list.push old_package[0]
+            extra_size -= old_package[1]
+        end
+
+        if not remove_list.empty? then
+            @log.info "Removed oldest package files.. (Now not fully caching)"
+            @log.info "  * #{remove_list.map{|path| File.basename(path)}.join(", ")}"
+            FileUtils.rm_rf remove_list
+        end
+    end
+
+    private
+    def get_cache_dir_list
+        return Dir.entries(CONFIG_PATH).select{|dir| not dir.start_with? "." and File.directory? CONFIG_PATH + "/#{dir}/downloads" }.map{|dir| CONFIG_PATH + "/#{dir}/downloads"}
+    end
+
+    private
+    def get_config_max_cache_size
+        return (@configs[:CACHE_SIZE] =~ /^([0-9][0-9]*)$/i)?  ($1.to_i * 1024 * 1024)  :  (8 * 1024 * 1024 * 1024) #default size 4G : unit = MB
+    end
+
+    private
+    def read_configs
+        file_path = CONFIG_PATH + "/config"
+        if not File.exist? file_path then return end
+
+        File.open file_path, "r" do |f|
+            f.each_line do |l|
+                row = l.split(":")
+                @configs[row[0].strip.to_sym] = row[1..-1].join(":").strip
+            end
+        end
+    end
+
+
+    public
+    # update package list from server
+    def update()
+
+        if @server_addr.nil? then
+            @log.warn "Server address is null"
+            return false
+        end
+
+        if not @snapshot_url then
+            $get_snapshot_mutex.synchronize do
+                @snapshot_path = get_lastest_snapshot(@is_server_remote)
+            end
+        end
+        @log.info "The lastest snapshot : #{@snapshot_path}"
+        if @snapshot_path.nil? then
+            @log.warn "Failed to get the lastest package list."
+            @snapshot_path = ""
+        end
+
+        exists_snapshot = false
+        if is_snapshot_exist(@snapshot_path) then
+            @log.info "Snapshot information is already cached [#{get_pkglist_path()}]"
+            exists_snapshot = true
+        else
+            @log.info "Snapshot information is not cached."
+        end
+
+        list_path = get_pkglist_path()
+        if list_path.nil? then
+            @log.error "Failed to get package list path."
+            return false
+        end
+
+        clean_list()
+
+        if exists_snapshot then
+            read_supported_os_list(list_path)
+            read_remote_pkg_list(list_path)
+            read_archive_pkg_list(list_path)
+        else
+            $update_mutex.synchronize do
+                uniq_name = Utils.create_uniq_name
+                tmp_dir = File.join(@config_dist_path, uniq_name)
+                FileUtils.mkdir_p tmp_dir
+                if not download_os_list(@is_server_remote, tmp_dir) then
+                    @log.error "\"#{@server_addr}\" does not have supported os list file properly."
+                    Utils.execute_shell("rm -rf #{tmp_dir}")
+                    return false
+                else read_supported_os_list(tmp_dir) end
+
+                if not download_pkg_list(@is_server_remote, tmp_dir) then
+                    @log.error "\"#{@server_addr}\" does not have package list file properly."
+                    Utils.execute_shell("rm -rf #{tmp_dir}")
+                    return false
+                else read_remote_pkg_list(tmp_dir) end
+
+                if not download_archive_pkg_list(@is_server_remote, tmp_dir) then
+                    @log.error "\"#{@server_addr}\" does not have archive package list file properly. This error can be ignored"
+                else read_archive_pkg_list(tmp_dir)    end
+                Utils.execute_shell("mv #{tmp_dir} #{list_path}")
+                @log.info "Moved \"#{tmp_dir}\" to"
+                @log.info "  \"#{list_path}\""
+                # tmp_dir should be removed  whether mv command is failed
+                Utils.execute_shell("rm -rf #{tmp_dir}")
+                remove_snapshots()
+            end
+        end
+
+        @log.info "Update package list from \"#{@server_addr}\".. OK"
+
+        return true
+    end
+
+    private
+    def clean_list()
+        @pkg_hash_os.clear
+        @archive_pkg_list.clear
+        @support_os_list.clear
+        @log.info "Cleard package list, supported os list.. OK"
+    end
+
+    public
+    # download package
+    def download(pkg_name, os, trace, loc = nil)
+
+        if loc.nil? then loc = @location end
+
+        if not File.exist? loc then FileUtils.mkdir_p "#{loc}" end
+
+        dependent_pkg_list = []
+
+        # get dependent list
+        if trace then
+            dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, true)
+            if dependent_pkg_list.nil? then
+                @log.error "Failed to get dependency for \"#{pkg_name}\" package"
+                return nil
+            end
+        else dependent_pkg_list = [pkg_name] end
+
+        surl = @server_addr
+        # download files
+        file_local_path = []
+        dependent_pkg_list.each do |p|
+            pkg_name = get_attr_from_pkg(p, os, "name")
+            pkg_path = get_attr_from_pkg(p, os, "path")
+            pkg_ver = get_attr_from_pkg(p, os, "version")
+            pkg_checksum = get_attr_from_pkg(p, os, "checksum")
+            pkg_size = get_attr_from_pkg(p, os, "size")
+            if pkg_path.nil? or pkg_ver.nil? then
+                @log.error "\"#{p}\" package does not exist in package server. Check if it exist in package server"
+                return nil
+            end
+            url = surl + pkg_path
+            filename = File.basename pkg_path
+
+            file_path = get_file_from_cache(filename, pkg_checksum, pkg_size, loc)
+            if file_path.nil? then
+
+                file_path = File.join(loc, filename)
+
+                result = FileDownLoader.download(url, loc, @log)
+                if not result or not File.exist? file_path then
+                    @log.error "File Download Failed!!"
+                    @log.error "* #{url} -> #{loc}"
+                    return nil
+                end
+
+                if Utils.validatePkgFile(file_path, pkg_checksum, pkg_size) then
+                    add_file_to_cache(file_path)
+                else
+                    @log.error "File Validation Failed!!"
+                    @log.info "Valiate : file path : #{file_path}, shasum : #{pkg_checksum}, size : #{pkg_size}", Log::LV_USER
+                    return nil
+                end
+            else
+                @log.info "Cached #{pkg_name} package file.. OK"
+            end
+            file_local_path.push(file_path)
+        end
+
+        if trace then
+            @log.info "Downloaded \"#{pkg_name}\" package with all dependent packages.. OK"
+        end
+        @log.info "  [path: #{file_local_path.join(", ")}]"
+
+        return file_local_path
+    end
     public
     def gen_dep_graph(os, type)
-               if (os == "all") then
+        if (os == "all") then
             puts "==graph explain=="
             puts "  box : package name"
             puts "  red arrow : install dependency"
             puts "  blue arrow : build dependency"
             puts "execute below graph generate command on your shell\n"
-                       @support_os_list.each do |os| make_dep_graph(os, type) end
-               else
+            @support_os_list.each do |os| make_dep_graph(os, type) end
+        else
             if(@support_os_list.include? os)
                 puts "execute below command on your shell\n"
-                           make_dep_graph(os, type)
+                make_dep_graph(os, type)
             else
                 @log.error "not support os name : #{os}\n server supports #{@support_os_list.join(',')}"
             end
-               end
+        end
     end
 
     def dot_ident(string)
@@ -419,50 +419,102 @@ class Client
         puts "dot -Tpng -o #{type}_dep_#{os}.png #{type}_dep_#{os}.dot"
     end
 
-       public
-       def make_img(os, img_info)
-               if (os == "all") then
-                       @support_os_list.each do |os| image_generator(os, img_info) end
-               else
-                       image_generator(os, img_info)
-               end
-       end
-
-       private
-       # make sdk image
-       def  image_generator(os, img_info)
-               # get package list
-               all_pkg_list = @pkg_hash_os[os].values
-
-               # select meta and install-type packages
-               img_pkg_list = []
-               all_pkg_list.each { |pkg|
-                       attr = get_attr_from_pkg(pkg.package_name, os, "attribute")
-                       if attr.nil? or attr.empty? then next end
-                       if attr[0].strip.upcase.eql? "ROOT" or attr[0].strip.upcase.eql? "INSTALL" then
-                               dependent_pkg_list = get_install_dependent_packages(pkg.package_name, os, true, true)
-                               img_pkg_list = img_pkg_list + dependent_pkg_list
-                       end
-               }
-               img_pkg_list.uniq!
-
-               # init workspace
-               workspace = @location+"/temp_for_tizen_sdk_imgs_#{os}"
-               if File.directory? workspace then FileUtils.remove_dir(workspace, true) end
-
-               # download packages
-               img_pkg_list.each do |pkg| download(pkg, os, false, "#{workspace}/binary") end
-
-               # write pkg_list_os file
-               FileUtils.cp("#{get_pkglist_path}/pkg_list_#{os}", "#{workspace}")
-
-               # write os_info file
-               File.open("#{workspace}/#{OS_INFO_FILE}", 'w') do |f| f.puts os end
+    public
+    def make_img(os, img_info, remove_list = nil)
+        if (os == "all") then
+            @support_os_list.each { |os| image_generator(os, img_info, remove_list) }
+        else
+            image_generator(os, img_info, remove_list)
+        end
+    end
+
+    private
+    # make sdk image
+    def  image_generator(os, img_info, user_input_list)
+        # select meta and install-type packages
+        metapackage_list = []
+        installtype_list = []
+        @pkg_hash_os[os].values.each { |pkg|
+            attr = get_attr_from_pkg(pkg.package_name, os, "attribute")
+            if attr.nil? or attr.empty? then next end
+            if attr[0].strip.upcase.eql? "ROOT" or attr[0].strip.upcase.eql? "MANDATORY" then
+                metapackage_list.push(pkg.package_name)
+            elsif  attr[0].strip.upcase.eql? "INSTALL" then
+               installtype_list.push(pkg.package_name) 
+            end
+        }
+
+        @log.info "<< Meta-Package List >>"
+        @log.info " - #{metapackage_list.sort}"
+        @log.info "<< Install Type Package List >>"
+        @log.info " - #{installtype_list}"
+        @log.info ""
+
+        # validate user input
+        if user_input_list.empty? or user_input_list.nil? then
+            user_input_list = []
+        else
+            user_input_list.each { |i|
+                flag = false
+                metapackage_list.each { |j| if "#{i}" == "#{j}" then flag = true end}
+                if flag == false then
+                    @log.info "[#{i}] is not in package server. please check it (We are case-sensitive)."
+                    return false
+                end
+            }
+            # get all meta-packages in user input
+            remove_metapackage_list = []
+            user_input_list.each { |i|
+                get_install_dependent_packages(i, os, true, true).each { |j|
+                    attr = get_attr_from_pkg(j, os, "attribute")
+                    if attr.nil? or attr.empty? then next end
+                    if attr[0].strip.upcase.eql? "ROOT" then
+                        remove_metapackage_list.push(j)
+                    end
+                }
+            }
+            @log.info "<< User Input List>>"
+            @log.info " - #{user_input_list}"
+            @log.info " - #{remove_metapackage_list}"
+            @log.info ""
+        end
+
+        # get final package list
+        img_pkg_list = []
+        if user_input_list.empty? then
+            metapackage_list.each { |pkg|
+                img_pkg_list = img_pkg_list + get_install_dependent_packages(pkg, os, true, true)
+            }
+        else
+            metapackage_list = metapackage_list - remove_metapackage_list
+            metapackage_list.each { |pkg|
+                img_pkg_list = img_pkg_list + get_install_dependent_packages_with_except(pkg, os, true, true, user_input_list)
+            }
+        end
+
+        img_pkg_list.uniq!
+        img_pkg_list = img_pkg_list + installtype_list
+        @log.info "<< Final Package List >>"
+        @log.info " - #{img_pkg_list.sort}"
+        @log.info ""
+
+        # init workspace
+        workspace = @location+"/temp_for_tizen_sdk_imgs_#{os}"
+        if File.directory? workspace then FileUtils.remove_dir(workspace, true) end
+
+        # download packages
+        img_pkg_list.each do |pkg| download(pkg, os, false, "#{workspace}/binary") end
+
+        # write pkg_list_os file
+        FileUtils.cp("#{get_pkglist_path}/pkg_list_#{os}", "#{workspace}")
+
+        # write os_info file
+        File.open("#{workspace}/#{OS_INFO_FILE}", 'w') do |f| f.puts os end
 
         # set image.info
         message = "";
         message = img_info;
-        
+
         if message.to_s.eql? "" then
             server = @server_addr;
             origin = File.dirname( server );
@@ -473,1615 +525,1691 @@ class Client
             message.strip!
             server = message;
             origin = File.dirname( server );
-            dist = File.basename( server ); 
-        end        
+            dist = File.basename( server );
+        end
 
         # write image.info
         f = File.new("#{workspace}/image.info", "w");
         f.write("origin : #{origin}\ndistribution : #{dist}\n");
         f.close
 
-               # compress files
-               snapshot = snapshot_path.split('/')[-1]
-               img_name = "TIZEN-SDK-IMG_#{snapshot}_#{os}.zip"
-               cmd = "cd #{workspace}; zip -q -r #{@location}/TIZEN-SDK-IMG_#{snapshot_path.split('/')[-1]}_#{os}.zip *;"
-               Utils.execute_shell_with_log(cmd, @log.path)
-
-               # clean workspace
-               FileUtils.remove_dir(workspace, true)
-               @log.info "<< SDK-Image Info. >>"
-               @log.info " - server addr : #{@server_addr}"
-               @log.info " - snapshot : #{snapshot}"
-               @log.info " - os : #{os}"
-               @log.info " - location : #{location}/"
-               @log.info " - name : #{img_name}"
-
-               return
-       end
-
-       private
-       def get_file_from_cache(filename, pkg_checksum, pkg_size, location)
-               if not File.directory? location then return nil end
-               downloaded_file_path = nil
-               @log.info "Wait for cache sync",Log::LV_USER
-               begin
-                       lock = Utils.file_lock(File.join(CONFIG_PATH,".cache_lock"))
-                       @log.info "Entering cache sync",Log::LV_USER
-                       cached_filepath = get_cached_filepath(filename, pkg_checksum, pkg_size)
-                       if not cached_filepath.nil? and File.exist? cached_filepath then
-                               #FileUtils.ln(cached_filepath, location, :force => true)
-                               if (FileUtil.safeLink(cached_filepath, location)) then
-                                       downloaded_file_path = File.join(location, File.basename(cached_filepath))
-                               end                                     
-                       end
-               ensure
-                       Utils.file_unlock(lock) if not lock.nil?
-               end
-               @log.info "Cache sync done",Log::LV_USER
-               if not downloaded_file_path.nil? and not File.exist? downloaded_file_path then
-                       downloaded_file_path = nil
-               end
-               return downloaded_file_path
-       end
-
-       private
-       def add_file_to_cache(filepath)
-               if filepath.nil? or filepath.empty? or not File.exist? filepath then return end
-               if not File.exist? @download_path then FileUtils.mkdir_p "#{@download_path}" end
-
-               filename = File.basename(filepath)
-               cachefile = File.join(@download_path, filename)
-
-               @log.info "Moving \"#{filename}\" to download cache directory"
-               @log.info "  [path: #{@download_path}]"
-
-               if not File.exist? cachefile then
-                       #FileUtils.ln(filepath, @download_path, :force => true)
-                       if not FileUtil.safeLink(filepath, @download_path) then
-                               @log.info "Failed to link file [#{filepath}] to "
-                               @log.info "  [#{@download_path}]"
-                       end                                     
-               end
-
-               if not File.exist? cachefile then
-                       @log.info "Failed to move [#{filename}] to "
-                       @log.info "  [#{@download_path}]"
-               end
-
-               begin
-                       lock = Utils.file_lock(File.join(CONFIG_PATH,".cache_lock"))
-
-                       remove_old_files_in_cache
-               ensure 
-                       Utils.file_unlock(lock) if not lock.nil?
-               end
-       end
-
-       private
-       def remove_snapshots()
-               listing_prefix = "#{@snapshots_path}/*"
-               dirs = Dir[listing_prefix].sort_by { |f| File.mtime(f) }.reverse
-
-               if not dirs.nil? and dirs.length >= 20 then
-                       Utils.execute_shell("rm -rf #{dirs[19..-1].join(" ")}")
-                       @log.info "Removed old snapshots.."
-                       @log.info "  * #{dirs[19]} ~ "
-               end
-       end
-
-       private
-       def get_cached_filepath(pkg_filename, pkg_checksum, pkg_size)
-               cached_filepath = "#{@download_path}/#{pkg_filename}"
-               if File.exist? cached_filepath then
-                       if Utils.validatePkgFile(cached_filepath, pkg_checksum, pkg_size) then
-                               FileUtils.touch cached_filepath                                 
-                               return cached_filepath
-                       else
-                               return nil
-                       end
-               end
-               return nil
-       end
-
-       public
-       # download dependent source
-       def download_dep_source(file_name)
-
-               file_url = @server_addr + "/source/#{file_name}"
-               if not FileDownLoader.download(file_url, @location, @log) then
-                       @log.error "Failed download #{file_name}"
-                       return nil
-               end
-               file_local_path = File.join(@location, file_name)
-               @log.info "Downloaded \"#{file_name}\" source file.. OK"
-               @log.info "  [path: #{file_local_path}]"
-
-               return file_local_path
-       end
-
-       private
-       def upload_request(ip, port, dock, transporter, binary_path_list)
-               binary_path_list.each do |bpath|
-                       client2 = BuildCommClient.create(ip, port, @log)
-                       begin
-                               if client2.nil? then
-                                       raise RuntimeError, "Failed to create BuildCommClient instance.."
-                               end
-                
-                               @log.info "Send UPLOAD REQ..  [UPLOAD|#{dock}]"
-                               result = client2.send("UPLOAD|#{dock}")
-                               if not result then
-                                       raise RuntimeError, "Failed to send ready REQ.."
-                               end
-                               result = client2.send_file(bpath, transporter)
-                       ensure
-                               client2.terminate
-                       end
-               end
-       end
-
-       public
-       # upload package
-       def upload(ip, port, binary_path_list, ftp_addr=nil, ftp_port=nil, ftp_username=nil, ftp_passwd=nil, password="")
-
-               # check ip and port
-               if ip.nil? or port.nil? then
-                       @log.error "Ip and port should be set."
-                       return nil
-               end
-
-               # check binary path list
-               if binary_path_list.nil? or binary_path_list.empty? then
-                       @log.error "Binary package path should be set."
-                       return nil
-               end
-
-               begin
-                       if not ftp_addr.nil? then
-                               transporter=FileTransferFTP.new(@log, ftp_addr, ftp_port, ftp_username, ftp_passwd)
-                       else
-                               transporter=FileTransferDirect.new(@log)
-                       end
-               rescue => e
-                       @log.error "FTP failed to put file (exception)"
-                       @log.error "#{e.message}"
-                       @log.error e.backtrace.inspect
-                       return nil
-               end
-                       
-               binary_list = []
-               binary_path_list.each do |binary_path|
-                       if File.exist? binary_path then
-                               binary_list.push(File.basename(binary_path))
-                       else
-                               @log.error "Binary file does not exist"
-                               return nil
-                       end
-               end
-
-               client = BuildCommClient.create(ip, port, @log)
-               if client.nil? then
-                       @log.error "Can't access server #{ip}:#{port}"
-                       return nil
-               end
-
-               begin
-                       # create unique dock number
-                       dock = Utils.create_uniq_name()
-                       
-                       dist = get_distribution
-                       if dist.empty? then
-                               @log.error "Distribution is empty.."
-                               return nil
-                       end
-
-                       @log.info "Send register message..  [REGISTER|#{dist}|#{password}|DOCK|#{dock}|#{binary_list.join("|")}]"
-                       snapshot = nil
-
-                       client.send "REGISTER|#{dist}|#{password}|DOCK|#{dock}|#{binary_list.join("|")}" 
-
-                       client.read_lines do |line|
-                               if line.eql?("WAITFORUPLOAD") then
-                                       # upload
-                                       @log.info "Get WAITFORUPLOAD message"
-                                       thread = Thread.new do
-                                               begin 
-                                                       upload_request(ip, port, dock, transporter, binary_path_list)
-                                               rescue => e
-                                                       puts "Transfering file failed!"
-                                                       puts e.message
-                                               end
-                                       end
-            
-                                       thread.join
-                                       client.send("REGISTERCONTINUE")
-                               elsif line.start_with? "SUCC" then
-                                       snapshot = line.split("|")[1]
-                               elsif line.start_with? "ERROR" then
-                                       @log.error line.strip
-                                       return nil
-                               else
-                                       @log.error "Unknown message received : #{l}"
-                               end
-                       end
-               ensure
-                       client.terminate
-               end
-
-               if not snapshot.nil? and not snapshot.empty? then
-                       snapshot = @server_addr + "/snapshots/" + snapshot
-                       @log.info "Registered successfully!  [#{binary_path_list.join("|")}]"
-                       if snapshot.empty? then
-                               @log.error "Failed to generate snapshot"
-                       end
-            
-                       return snapshot
-               else
-                       return nil
-               end
-       end
-
-       private
-       # verify package before uploading
-       def verify_upload(pkg_name, pkg_path)
-
-               manifest_file = "pkginfo.manifest"
-               uniq_name = Utils.create_uniq_name
-               path = Utils::HOME + "/tmp/#{uniq_name}"
-               if not File.exist? path then FileUtils.mkdir_p "#{path}" end
-               begin
-                       if not FileInstaller.extract_a_file(pkg_path, manifest_file, path, @log) then
-                               @log.error "The \"pkginfo.manifest\" file does not exist in \"#{pkg_path}\""
-                               return false
-                       end
-                       manifest_path = File.join(path, manifest_file)
-                       pkg = Parser.read_single_pkginfo_from manifest_path
-                       if File.exists? manifest_path then FileUtils.rm_f(manifest_path) end
-                       FileUtils.remove_dir(path, true)
-               rescue Interrupt
-                       @log.error "Client: Interrupted.."
-                       FileUtils.remove_dir(path, true)
-                       @log.info "Removed #{path}"
-                       raise Interrupt
-               rescue RuntimeError => e
-                       @log.error( e.message, Log::LV_USER)
-                       FileUtils.remove_dir(path, true)
-                       @log.info "Removed #{path}"
-                       return false
-               end
-               new_pkg_ver = pkg.version
-               new_pkg_install_dep_list = pkg.install_dep_list
-               os = pkg.os
-
-               list = get_all_reverse_install_dependent_packages_remote(pkg_name, os, true)
-
-               if not list.nil? then
-                       list.each do |p|
-                               ilist = get_attr_from_pkg(p, os, "install_dep_list")
-                               if ilist.nil? then next end
-                               ilist.each do |l|
-                                       if l.package_name.eql? pkg_name then
-                                               if not l.match? new_pkg_ver then
-                                                       @log.error "\"#{p}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
-                                                       return false
-                                               end
-                                       end
-                               end
-                       end
-               end
-
-               if not new_pkg_install_dep_list.nil? then
-                       new_pkg_install_dep_list.each do |l|
-                               if not check_remote_pkg(l.package_name, os) then
-                                       @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version}), but \"#{l.package_name}\" is not exist on server"
-                                       return false
-                               end
-                               rver = get_attr_from_pkg(l.package_name, os, "version")
-                               if not l.match? rver then
-                                       @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
-                                       return false
-                               end
-                       end
-               end
-
-               @log.info "Passed to verify packages for uploading.. OK"
-               return true
-       end
-
-       private
-       # get distribution
-       def get_distribution()
-               server = @server_addr
-               if server.nil? or server.empty? then
-                       @log.error "Server addr is nil"
-                       return nil
-               end
-
-               dist = ""
-               dist = File.basename(server)
-
-               return dist
-       end
-
-       private
-       def get_flat_serveraddr()
-               server = @server_addr
-               if server.nil? or server.empty? then
-                       @log.error "Server addr is nil"
-                       @log.error "check sync_pkg_servers table pkgsvr_url column is null"
-                       return "nil"
-               end
-
-               server = server.delete ".:/@"
-               return server
-       end
-
-       public
-       # install package
-       # install all install dependency packages
-       def install(pkg_name, os, trace, force)
-
-               ret = install_internal( pkg_name, os, trace, force )
-               return ret
-       end
-
-
-       private
-       def install_internal(pkg_name, os, trace, force)
-
-               if trace.nil? then trace = true end
-               if force.nil? then force = false end
-
-               # check meta package
-               is_meta_pkg = check_meta_pkg(pkg_name, os)
-               if is_meta_pkg then trace = true end
-
-               # compare package version with installed package's
-               pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
-               if pkg_ver.nil? or pkg_ver.empty? then
-                       @log.error "#{pkg_name} package does not exist in remote package list"
-                       return false
-               end
-
-
-               compare_result = compare_version_with_installed_pkg(pkg_name, pkg_ver)
-               if not force then
-                       case compare_result
-                       when -1 then
-                               @log.warn "Checked \"#{pkg_name}\" package version : it is bigger then remote package version"
-                               return true
-                       when 0 then
-                               @log.warn "Checked \"#{pkg_name}\" package version : it is same with remote package version"
-                               return true
-                       when 1, 2 then
-                       end
-               end
-
-               # if enable trace, create all dependent package list
-               if trace then
-                       dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, force)
-                       if dependent_pkg_list.nil? then
-                               @log.error "Failed to get dependency for \"#{pkg_name}\" package"
-                               return false
-                       end
-               else
-                       dependent_pkg_list = [pkg_name]
-               end
-
-               # TODO: need to compare dependent package version
-               # install packages including dependent packages
-               dependent_pkg_list.each do |pkg|
-                       if not install_pkg(pkg, os, force) then
-                               @log.error "#{pkg} does not exist"
-                               return false
-                       end
-                       add_pkg_info(pkg, os)
-               end
-
-               # write installed package information to file
-               write_pkg_hash_to_file(nil)
-
-               if trace then
-                       @log.info "Installed \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
-                       @log.info "  [#{dependent_pkg_list.join(" -> ")}]"
-               else
-                       @log.info "Install only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
-               end
-
-               return true
-       end
-
-
-       public
-       # install local package (ignore dependent packages)
-       def install_local_pkg(pkg_path, trace, force, repos_paths = nil)
-
-               ret = install_local_pkg_internal(pkg_path, trace, force, repos_paths)
-               return ret
-       end
-
-
-       private
-       def install_local_pkg_internal(pkg_path, trace, force, repos_paths)
-
-               pkg_name = Utils.get_package_name_from_package_file( pkg_path )
-               pkg_os = Utils.get_os_from_package_file( pkg_path )
-
-               if not File.exist? pkg_path then
-                       @log.error "\"#{pkg_path}\" file does not exist"
-                       return false
-               end
-               filename = File.basename(pkg_path)
-               ext = File.extname(filename)
-               if not ext.eql? ".zip" then
-                       @log.error "\"#{filename}\" is not zip file. binary package file should have .zip ext"
-                       return false
-               end
-               pkg_name = filename.split("_")[0]
-               manifest_file = "pkginfo.manifest"
-
-               uniq_name = Utils.create_uniq_name
-               path = Utils::HOME + "/tmp/#{uniq_name}"
-               if not File.exist? path then FileUtils.mkdir_p "#{path}" end
-               begin
-                       if not FileInstaller.extract_a_file(pkg_path, manifest_file, path, @log) then
-                               @log.error "pkginfo.manifest file does not exist in #{pkg_path}"
-                               return false
-                       end
-                       manifest_path = File.join(path, manifest_file)
-                       pkg = Parser.read_single_pkginfo_from manifest_path
-                       new_pkg_ver = pkg.version
-                       pkg_conflicts = pkg.conflicts
-                       FileUtils.remove_dir(path, true)
-               rescue Interrupt
-                       @log.error "Client: Interrupted.."
-                       FileUtils.remove_dir(path, true)
-                       @log.info "Removed #{path}"
-                       raise Interrupt
-               rescue RuntimeError => e
-                       @log.error( e.message, Log::LV_USER)
-                       FileUtils.remove_dir(path, true)
-                       @log.info "Removed #{path}"
-                       return false
-               end
-
-               compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
-               if not force then
-                       case compare_result
-                       when -1 then
-                               @log.warn "Installed \"#{pkg_name}\" package version is bigger.."
-                               return true
-                       when 0 then
-                               @log.warn "Checked \"#{pkg_name}\" package version : it is same with installed package version"
-                               return true
-                       when 1, 2 then
-                       end
-               end
-
-               if check_installed_pkg(pkg_name) then
-                       uninstall(pkg_name, false)
-               end
-
-               # TODO: Resolve conflicts
-               if not resolve_conflicts_internal(pkg_conflicts) then
-                       @log.error "Failed to resolve conflicts [#{pkg_name}]"
-                       return false
-               end             
-
-
-               if trace then
-                       install_dep_pkgs = pkg.install_dep_list
-                       new_pkg_os = pkg_os
-                       install_dep_pkgs.each do |p|
-                               # check local path first
-                               if not repos_paths.nil? then
-                                       # search
-                                       binpkgs = []
-                                       repos_paths.each do  |repos_path|
-                                               binpkgs += Dir.glob("#{repos_path}/#{p.package_name}_*_#{new_pkg_os}.zip")
-                                       end
-                                       if not binpkgs.empty? then
-                                               if not install_local_pkg_internal(binpkgs[0], true, false, repos_paths) then
-                                                       @log.warn "#{p} package is not installed"
-                                               end
-                                       else
-                                               if not install_internal(p.package_name, new_pkg_os, true, false) then
-                                                       @log.warn "#{p} package is not installed"
-                                               end
-                                       end
-                               else
-                                       if not install_internal(p.package_name, new_pkg_os, true, false) then
-                                               @log.warn "#{p} package is not installed"
-                                       end
-                               end
-                       end
-               end
-
-               # install package
-               ret = FileInstaller.install(pkg_name, pkg_path, "binary", @location, @log)
-
-               if not ret then
-                       @log.error "Install failed \"#{pkg_path} [#{new_pkg_ver}]\" file.. "
-                       return false
-               end
-
-               add_local_pkg_info(pkg_name)
-               write_pkg_hash_to_file(nil)
-
-               @log.info "Installed \"#{pkg_path} [#{new_pkg_ver}]\" file.. OK"
-               return true
-       end
-
-
-       public
-       # upgrade package
-       def upgrade(os, trace)
-
-               if trace.nil? then trace = true end
-               list = check_upgrade(os)
-
-               if list.empty? or list.nil? then
-                       @log.info "There is no packages for upgrading.."
-                       return false
-               end
-
-               list.each do |p|
-                       if check_installed_pkg(p) then
-                               if not uninstall(p, trace) then
-                                       @log.error "Failed to uninstall \"#{p}\" package.."
-                                       return false
-                               end
-                       end
-
-                       if not install_internal(p, os, trace, false) then
-                               @log.error "Failed to install \"#{p}\" package.."
-                               return false
-                       end
-               end
-
-               @log.info "Upgraded packages from #{@server_addr}.. OK"
-               return true
-       end
-
-       public
-       # check package which will be upgraded
-       def check_upgrade(os)
-
-               update_pkgs = []
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               installed_pkg_hash = installed_pkg_hash_loc[installed_pkg_hash_key]
-               remote_pkg_hash = pkg_hash_os[os]
-
-               if remote_pkg_hash.nil? then
-                       @log.error "There is no remote package list for #{os}."
-                       return nil
-               end
-
-               if installed_pkg_hash.nil? then
-                       @log.warn "There is no any installed package in \"#{@location}\""
-                       return remote_pkg_hash.keys
-               end
-
-               arr_keys = installed_pkg_hash.keys
-               arr_keys.each do |k|
-                       installed_ver = get_attr_from_installed_pkg(k, "version")
-                       if not check_remote_pkg(k, os) then next end
-                       remote_ver = get_attr_from_pkg(k, os, "version")
-                       compare_result = compare_version_with_installed_pkg(k, remote_ver)
-                       case compare_result
-                       when -1 then next
-                       when 0 then next
-                       when 1 then
-                               @log.output "\"#{k}\" package : #{installed_ver} -> #{remote_ver}"
-                               update_pkgs.push(k)
-                       end
-               end
-
-               @log.info "Checked packages for upgrading.. OK"
-               return update_pkgs
-       end
-
-       public
-       # get default path for installing
-       def get_default_inst_dir()
-               return Dir.pwd
-       end
-
-       public
-       # uninstall package
-       # trace : if true, uninstall all dependent packages
-       def uninstall(pkg_name, trace)
-
-               type = "binary"
-               pkg_list = []
-               pkg_hash = nil
-
-               if not check_installed_pkg(pkg_name) then
-                       @log.error "\"#{pkg_name}\" package is not installed."
-                       return false
-               end
-
-               pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
-
-               if trace then
-                       pkg_list = get_all_reverse_install_dependent_packages(pkg_name, true)
-                       if pkg_list.nil? then
-                               @log.error "Failed to get \"#{pkg_name}\" package dependency information."
-                               return false
-                       end
-               else
-                       pkg_list.push(pkg_name)
-               end
-
-               pkg_list.each do |p|
-                       if not check_installed_pkg(p) then next end
-                       if not FileInstaller.uninstall(p, type, @location, @log) then
-                               @log.error "Failed uninstall \"#{pkg_name}\" package"
-                               return false
-                       end
-                       pkg_hash = remove_pkg_info(p)
-               end
-
-               if trace then
-                       @log.info "Uninstalled \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
-                       @log.info "  [#{pkg_list.join(" -> ")}]"
-               else
-                       @log.info "Uninstalled only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
-               end
-
-               write_pkg_hash_to_file(nil)
-               return true
-       end
-
-       public
-       # clean
-       def clean(force)
-               if not force then
-                       puts "Do you really want to remove \"#{@location}\" path? [yes]"
-                       input = $stdin.gets.strip
-                       if input.upcase.eql? "YES" then
-                               @log.info "Removed \"#{@location}\""
-                       else
-                               @log.info "Canceled"
-                               return
-                       end
-               end
-               if File.exist? @location then FileUtils.rm_rf(@location) end
-               FileUtils.mkdir_p(@location)
-               #@pkg_hash_os.clear
-               @installed_pkg_hash_loc.clear
-               #@archive_pkg_list.clear
-               @log.info "Cleaned \"#{@location}\" path.. OK"
-       end
-
-       public
-       # get reverse build dependent packages (just 1 depth)
-       def get_reverse_build_dependent_packages(pkg_name, os)
-
-               result = []
-               pkg_hash = @pkg_hash_os[os]
-               if pkg_hash.nil? then return [] end
-               pkg_list = pkg_hash.values
-               pkg_list.each do |pkg|
-                       pkg.build_dep_list.each do |dep|
-                               if dep.package_name.eql? pkg_name and
-                                       not dep.target_os_list.nil? and
-                                       dep.target_os_list.include? os then
-                                       result.push(pkg)
-                               end
-                       end
-               end
-
-               return result
-       end
-
-       public
-       # get reverse source dependent packages (just 1 depth)
-       def get_reverse_source_dependent_packages(pkg_name)
-
-               result = []
-               @support_os_list.each do |os|
-                       pkg_hash = @pkg_hash_os[os]
-                       pkg_list = pkg_hash.values
-                       pkg_list.each do |pkg|
-                               pkg.source_dep_list.each do |p|
-                                       if p.package_name.eql? pkg_name then
-                                               result.push(pkg)
-                                       end
-                               end
-                       end
-               end
-
-               return result
-       end
-
-       public
-       # get reverse install dependent packages (jush 1 depth)
-       def get_reverse_install_dependent_packages(pkg_name, os)
-
-               result = []
-               pkg_hash = @pkg_hash_os[os]
-               pkg_list = pkg_hash.values
-               pkg_list.each do |pkg|
-                       pkg.install_dep_list.each do |p|
-                               if p.package_name.eql? pkg_name then
-                                       result.push(pkg.package_name)
-                               end
-                       end
-               end
-
-               return result
-       end
-
-       public
-       # get all build dependent packages (considered build priority, and reverse)
-       def get_build_dependent_packages(pkg_name, os, reverse)
-
-               if not check_remote_pkg(pkg_name, os) then return nil end
-               if reverse.nil? then reverse = true end
-
-               @all_dep_list.clear
-               begin
-                       get_build_dependency_arr(pkg_name, os, 0)
-                       # in case of cross build dependency
-               rescue SystemStackError
-                       @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
-                       return nil
-               end
-
-               max = 0
-               @all_dep_list.each do |p|
-                       if p[0].to_i > max then
-                               max = p[0].to_i
-                       else next end
-               end
-
-               result = []
-               i = 0
-               while i <= max
-                       @all_dep_list.each do |p|
-                               if p[0].to_i.eql? i then
-                                       d = p[1]
-                                       remote_os = get_attr_from_pkg(d.package_name, os, "os")
-                                       remote_ver = get_attr_from_pkg(d.package_name, os, "version")
-                                       if not d.target_os_list.include? remote_os then
-                                               @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.target_os_list.to_s}, but \"#{d.package_name}\" (#{remote_os}) package is in server"
-                                               return nil
-                                       end
-                                       if not d.match? remote_ver then
-                                               @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
-                                               return nil
-                                       else result.push(d.package_name) end
-                               end
-                       end
-                       i = i + 1
-               end
-
-               @log.info "Get build dependent packages for #{pkg_name} package.. OK"
-               if reverse then return result.reverse.uniq.push(pkg_name)
-               else return result.uniq.insert(0, pkg_name) end
-       end
-
-       public
-       # get all install dependent packages (considered install priority, reverse, and force)
-       # reverse : return reverse result
-       # force : install package force
-       def get_install_dependent_packages(pkg_name, os, reverse, force)
-
-               if not check_remote_pkg(pkg_name, os) then return nil end
-               if reverse.nil? then reverse = true end
-
-               @all_dep_list.clear
-               begin
-                       get_install_dependency_arr(pkg_name, os, force, 0)
-                       # in case of cross build dependency
-               rescue SystemStackError
-                       @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
-                       return nil
-               end
-
-               max = 0
-               @all_dep_list.each do |p|
-                       if p[0].to_i > max then
-                               max = p[0].to_i
-                       else next end
-               end
-
-               result = []
-               i = 0
-               while i <= max
-                       @all_dep_list.each do |p|
-                               if p[0].to_i.eql? i then
-                                       d = p[1]
-                                       remote_ver = get_attr_from_pkg(d.package_name, os, "version")
-                                       if not d.match? remote_ver then
-                                               @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
-                                               return nil
-                                       else result.push(d.package_name) end
-                               end
-                       end
-                       i = i + 1
-               end
-
-               @log.info "Get install dependent packages for \"#{pkg_name}\" package.. OK"
-               if reverse then return result.reverse.uniq.push(pkg_name)
-               else return result.uniq.insert(0, pkg_name) end
-       end
-
-       public
-       # get all reverse install dependent packages (considered reverse install priority for tracing uninstall)
-       def get_all_reverse_install_dependent_packages(pkg_name, reverse)
-
-               if not check_installed_pkg(pkg_name) then return nil end
-               if reverse.nil? then reverse = true end
-
-               begin
-                       res = get_all_reverse_install_dependency_arr(pkg_name, 0)
-               rescue SystemStackError
-                       @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
-                       return nil
-               end
-               res2 = res.split("::")
-               result = []
-               res2.each do |r|
-                       result.push(r.split(':')[1])
-               end
-
-               @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
-               if reverse then return result.reverse.uniq
-               else return result end
-       end
-
-       public
-       # get all reverse remote dependent packages (considered reverse install priority for tracing uninstall)
-       def get_all_reverse_install_dependent_packages_remote(pkg_name, os, reverse)
-               #if not check_remote_pkg(pkg_name, os) then return nil end
-               if reverse.nil? then reverse = true end
-
-               begin
-                       res = get_all_reverse_install_dependency_arr_remote(pkg_name, os, 0)
-               rescue SystemStackError
-                       @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
-                       return nil
-               end
-               res2 = res.split("::")
-               result = []
-               res2.each do |r|
-                       result.push(r.split(':')[1])
-               end
-
-               @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
-               if reverse then return result.reverse
-               else return result end
-       end
-
-       public
-       # check package whether to exist in remote server
-       def check_remote_pkg(pkg_name, os)
-
-               pkg_hash = @pkg_hash_os[os]
-               if pkg_hash.nil? then return false end
-               pkg = pkg_hash[pkg_name]
-               if pkg.nil? then
-                       #@log.warn "There is no \"#{pkg_name}\" remote package information in list"
-                       return false
-               end
-
-               return true
-       end
-
-       public
-       # check package whether to exist in installed packages
-       def check_installed_pkg(pkg_name)
-
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-               if pkg_hash.nil? then return false end
-               pkg = pkg_hash[pkg_name]
-
-               if pkg.nil? then return false end
-               return true
-       end
-
-       public
-       # get attribute from installed package
-       def get_attr_from_installed_pkg(pkg_name, attr)
-
-               if not check_installed_pkg(pkg_name) then return nil end
-               pkg = get_installed_pkg_from_list(pkg_name)
-
-               if pkg.nil? then return nil end
-
-               case attr
-               when "version" then return pkg.version
-               when "source" then return pkg.source
-               when "src_path" then return pkg.src_path
-               when "os" then return pkg.os
-               when "build_dep_list" then return pkg.build_dep_list
-               when "install_dep_list" then return pkg.install_dep_list
-               when "attribute" then return pkg.attribute
-               end
-       end
-
-       public
-       # get attribute from remote package
-       def get_attr_from_pkg(pkg_name, os, attr)
-
-               if not check_remote_pkg(pkg_name, os) then return nil end
-               pkg = get_pkg_from_list(pkg_name, os)
-
-               if pkg.nil? then return nil end
-
-               case attr
-               when "name" then return pkg.package_name
-               when "path" then return pkg.path
-               when "source" then return pkg.source
-               when "version" then return pkg.version
-               when "src_path" then return pkg.src_path
-               when "os" then return pkg.os
-               when "build_dep_list" then return pkg.build_dep_list
-               when "install_dep_list" then return pkg.install_dep_list
-               when "attribute" then return pkg.attribute
-               when "checksum" then return pkg.checksum
-               when "size" then return pkg.size
-               when "conflicts" then return pkg.conflicts                              
-
-               end
-       end
-
-       public
-       # show a package information
-       def show_pkg_info(pkg_name, os)
-               if not check_remote_pkg(pkg_name, os) then
-                       @log.error "\"#{pkg_name}\" package does not exist"
-                       return ""
-               end
-
-               pkg = get_pkg_from_list(pkg_name, os)
-               return pkg.to_s
-       end
-
-       public
-       # show all packages information
-       def show_pkg_list(os)
-               pkg_hash = @pkg_hash_os[os]
-               if pkg_hash.nil? then
-                       @log.error "\"#{os}\" package list does not exist"
-                       return ""
-               end
-
-               pkg_all_list = []
-               pkg_list = pkg_hash.values
-               pkg_list.each do |p|
-                       pkg_all_list.push([p.package_name, p.version, p.description])
-               end
-               return pkg_all_list.sort
-       end
-
-       public
-       # show installed package information
-       def show_installed_pkg_info(pkg_name)
-
-               if not check_installed_pkg(pkg_name) then
-                       @log.error "\"#{pkg_name}\" package does not exist"
-                       return ""
-               end
-
-               pkg = get_installed_pkg_from_list(pkg_name)
-               return pkg.to_s
-       end
-
-       public
-       # show all installed packages information
-       def show_installed_pkg_list()
-
-               file_path = get_installed_pkg_list_file_path()
-               pkg_hash = @installed_pkg_hash_loc[file_path]
-               if pkg_hash.nil? then
-                       @log.error "Installed package list does not exist"
-                       return nil
-               end
-               pkg_all_list = []
-               pkg_list = pkg_hash.values
-               pkg_list.each do |p|
-                       pkg_all_list.push([p.package_name, p.version, p.description])
-               end
-               return pkg_all_list.sort
-       end
-
-       private
-       def get_build_dependency_arr(pkg_name, os, n)
-               pkg_hash = @pkg_hash_os[os]
-               pkg = pkg_hash[pkg_name]
-
-               if pkg.nil? then
-                       @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
-                       return
-               end
-
-               # if package is already installed, skip tracing dependency
-               if check_installed_pkg(pkg_name) then
-                       # compare version with installed package version
-                       new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
-                       compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
-                       if compare_result == -1 or compare_result == 0 then return end
-               end
-
-               pkg.build_dep_list.each do |l|
-                       @all_dep_list.push([n, l])
-                       get_build_dependency_arr(l.package_name, os, n+1)
-               end
-
-               return
-       end
-
-       private
-       def get_install_dependency_arr(pkg_name, os, force, n)
-
-               pkg_hash = @pkg_hash_os[os]
-               pkg = pkg_hash[pkg_name]
-
-               if pkg.nil? then
-                       @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
-                       return
-               end
-
-               # if package is already installed, skip tracing dependency
-               if check_installed_pkg(pkg_name) then
-                       # compare version with installed package version
-                       new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
-                       compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
-                       if not force then
-                               if compare_result == -1 or compare_result == 0 then return end
-                       end
-               end
-
-               pkg.install_dep_list.each do |l|
-                       @all_dep_list.push([n, l])
-                       get_install_dependency_arr(l.package_name, os, force, n+1)
-               end
-
-               return
-       end
-
-       private
-       def get_all_reverse_install_dependency_arr(pkg_name, n)
-
-               s = "#{n}:#{pkg_name}"
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-               pkg_list = pkg_hash.values
-               pkg_list.each do |pkg|
-                       pkg.install_dep_list.each do |l|
-                               if l.package_name.eql? pkg_name then
-                                       s = s + "::" + get_all_reverse_install_dependency_arr(pkg.package_name, n+1)
-                               end
-                       end
-               end
-
-               return s
-       end
-
-       private
-       def get_all_reverse_install_dependency_arr_remote(pkg_name, os, n)
-
-               s = "#{n}:#{pkg_name}"
-               pkg_hash = @pkg_hash_os[os]
-               pkg_list = pkg_hash.values
-               pkg_list.each do |pkg|
-                       pkg.install_dep_list.each do |l|
-                               if l.package_name.eql? pkg_name then
-                                       s = s + "::" + get_all_reverse_install_dependency_arr_remote(pkg.package_name, os, n+1)
-                               end
-                       end
-               end
-
-               return s
-       end
-
-       public
-       def get_pkg_from_list(pkg_name, os)
-
-               pkg_hash = @pkg_hash_os[os]
-               if pkg_hash.nil? then return nil end
-
-               pkg = pkg_hash[pkg_name]
-
-               return pkg
-       end
-
-       private
-       def get_installed_pkg_from_list(pkg_name)
-
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-               pkg = pkg_hash[pkg_name]
-               if pkg.nil? then return nil end
-
-               return pkg
-       end
-
-       private
-       def resolve_conflicts_internal(conflicts_pkgs)
-               if conflicts_pkgs.nil? then return true end                     
-               conflicts_pkgs.each do |pkg|
-                       if check_installed_pkg(pkg.package_name) then                           
-                               if not uninstall(pkg.package_name, true) then
-                                       @log.error "Failed to uninstall [#{pkg.package_name}] package for resolving"                                    
-                                       return false
-                               else
-                                       @log.info "Resolved conflict package [#{pkg.package_name}]"                                     
-                               end
-                       end                             
-               end     
-               return true
-       end                     
-
-       private
-       def resolve_conflicts(pkg_name, os)
-               conflicts = get_attr_from_pkg(pkg_name, os, "conflicts")
-               return resolve_conflicts_internal(conflicts)
-       end     
-
-       private
-       # install a package to @location after uninstalling and downloading
-       def install_pkg(pkg_name, os, force)
-
-               new_pkg_ver = ""
-
-               # install remote server package file
-               if not check_remote_pkg(pkg_name, os) then
-                       @log.error "\"#{pkg_name}\" package does not exist in remote server"
-                       return false
-               end
-               path = get_attr_from_pkg(pkg_name, os, "path")
-               # type should be binary. type = "binary"
-               # below code should be changed
-               type = path.split('/')[-2]
-               new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
-
-               # compare version with installed package versiona
-               compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
-               if not force then
-                       case compare_result
-                       when -1 then
-                               @log.warn "Checked \"#{pkg_name}\" package version : it is bigger then remote package version"
-                               return true
-                       when 0 then
-                               @log.warn "Checked \"#{pkg_name}\" package version : it is same with remote package version"
-                               return true
-                       end
-               end
-
-               # if package is already installed, then uninstall it
-               if check_installed_pkg(pkg_name) then
-                       if not uninstall(pkg_name, false) then
-                               @log.error "Failed to uninstall \"#{pkg_name}\""
-                               return false
-                       end
-               end
-
-               # resolve conflict packages
-               if not resolve_conflicts(pkg_name, os) then
-                       @log.error "Failed to resolve conflicts [#{pkg_name}]"
-                       return false
-               end
-
-               # install package
-               #download
-               tmp_location = nil
-               begin
-                       tmp_location = File.join(@tmp_path,Utils.create_uniq_name)
-                       filepath = download(pkg_name, os, false, tmp_location)
-                       if filepath.nil? or filepath[0].nil? then
-                               return false
-                       end
-
-                       #install
-                       ret = FileInstaller.install(pkg_name, filepath[0], type, @location, @log)
-               ensure
-                       #remove garbage
-                       FileUtils.rm_rf tmp_location if not tmp_location.nil? and File.exist? tmp_location
-               end
-
-               return ret
-       end
-
-       private
-       def compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
-
-               if check_installed_pkg_list_file() then
-                       read_installed_pkg_list()
-                       if check_installed_pkg(pkg_name) then
-                               installed_pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
-                               compare_result = Utils.compare_version(installed_pkg_ver, new_pkg_ver)
-                               return compare_result
-                       end
-               end
-
-               return 2
-       end
-
-       private
-       def remove_pkg_info(pkg_name)
-
-               pkg_hash = {}
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
-                       pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-                       if pkg_hash.include? pkg_name then
-                               pkg_hash.delete(pkg_name)
-                       end
-                       @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
-               else return nil end
-
-               @log.info "Removed information for \"#{pkg_name}\" package.. OK"
-               return pkg_hash
-       end
-
-       private
-       def add_pkg_info(pkg_name, os)
-
-               pkg_hash = {}
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
-                       pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-                       pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os)
-               else pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os) end
-               @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
-
-               #@log.info "Added information for \"#{pkg_name}\" package.. OK"
-               return pkg_hash
-       end
-
-       private
-       # add package manifest info
-       def add_local_pkg_info(pkg_name)
-
-               config_path = File.join(@location, PACKAGE_INFO_DIR, "#{pkg_name}")
-               pkg = read_pkginfo_file(pkg_name, config_path)
-
-               if pkg.nil? then
-                       @log.error "Failed to read pkginfo.manifest file"
-                       return nil
-               end
-
-               pkg_hash = {}
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
-                       pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
-                       pkg_hash[pkg_name] = pkg
-               else pkg_hash[pkg_name] = pkg end
-               @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
-
-               #@log.info "Added information for \"#{pkg_name}\" package.. OK"
-               return pkg_hash
-       end
-
-       private
-       # read package manifet info
-       def read_pkginfo_file(pkg_name, path)
-
-               file_path = File.join(path, "pkginfo.manifest")
-               begin
-                       pkg = Parser.read_single_pkginfo_from file_path
-               rescue => e
-                       @log.error( e.message, Log::LV_USER)
-                       return nil
-               end
-
-               if pkg.nil? then
-                       @log.error "Failed to read manifest file : #{file_path}"
-                       return nil
-               end
-
-               @log.info "Read information for \"#{pkg_name}\" package.. OK"
-               return pkg
-       end
-
-       # get the lastest snapshot
-       # from_server : if true, update from server
-       def get_lastest_snapshot(from_server)
-               ssinfo_file = "snapshot.info"
-               file_url = File.join(@server_addr, ssinfo_file)
-               if from_server then
-                       if not FileDownLoader.download(file_url, @config_dist_path, @log) then
-                               @log.error "Server does not have \"#{ssinfo_file}\" file."
-                               return nil 
-                       end
-               else
-                       if File.exist? file_url then 
-                               FileUtils.cp(file_url, @config_dist_path)
-                       else 
-                               @log.error "Server does not have \"#{ssinfo_file}\" file."
-                               return nil 
-                       end
-               end
-
-               file_path = File.join(@config_dist_path, ssinfo_file)
-               if not File.exist? file_path then return nil end
-
-               contents = File.open(file_path, "r").read
-
-               _list = contents.split("\n\n")
-               if _list.nil? or _list == "" or _list.empty? then return nil end
-               list = _list[-1].split("\n")
-               if list.nil? or list == "" or list.empty? then return nil end
-               _path = list[-1].split(":")
-               if _path.nil? or _path == ""  or _path.length != 2 then return nil end
-               path = _path[1].strip
-               if path == nil or path == "" then return nil end
-
-               return path
-       end
-
-       def get_pkglist_path()
-               return File.join(@config_dist_path, @snapshot_path)
-       end
-
-       # if url includes snapshot infomation, retuen true
-       def is_snapshot_url(addr = nil)
-               if addr.nil? then addr = @server_addr end
-               addr_arr = addr.split('/')
-               if addr_arr[-2].eql? "snapshots" then
-                       return true
-               else
-                       return false
-               end
-       end
-
-       def split_addr_and_snapshot(addr = nil)
-               if addr.nil? then addr = @server_addr end
-               addr_arr = addr.split('/')
-               if addr_arr[-2].eql? "snapshots" then
-                       return addr_arr[0..-3].join("/"), "/"+addr_arr[-2..-1].join("/")
-               else
-                       return nil
-               end
-       end
-
-       def is_snapshot_exist(ss_path = nil)
-               if ss_path.nil? then ss_path = @snapshot_path
-               elsif ss_path == "" then return false end
-
-               local_snapshot_path = File.join(@config_dist_path, ss_path)
-               if File.directory? local_snapshot_path then return true
-               else return false end
-       end
-
-       def read_remote_pkg_list(list_path)
-               @support_os_list.each do |os|
-                       filename = PKG_LIST_FILE_PREFIX + os
-                       local_file_path = File.join(list_path, filename)
-                       if File.exist? local_file_path then
-                               begin
-                                       pkg_hash = Parser.read_repo_pkg_list_from local_file_path
-                                       @pkg_hash_os[os] = pkg_hash
-                                       @log.info "Get package information for #{os}.. OK"
-                               rescue => e
-                                       @log.error( e.message, Log::LV_USER)
-                                       @pkg_hash_os[os] = {}
-                               end
-                       else
-                               @log.warn "Failed to read pkg_list_#{os} file"
-                               @pkg_hash_os[os] = {}
-                       end
-               end
-       end
-
-       def read_supported_os_list(list_path)
-               local_file_path = File.join(list_path, OS_INFO_FILE)
-               if File.exist? local_file_path then
-                       File.open(local_file_path, "r") do |f|
-                               f.each_line do |l|
-                                       os = l.strip
-                                       if @support_os_list.index(os).nil? then @support_os_list.push(os) end
-                               end
-                       end
-                       @log.info "Get supported os infomation.. OK"
-               else
-                       @log.warn "Failed to get supported os infomation"
-               end
-       end
-
-       def download_os_list(from_server, dist = nil)
-               if dist.nil? then dist = get_pkglist_path end
-               file_url = File.join(@server_addr, OS_INFO_FILE)
-               if from_server then
-                       if not FileDownLoader.download(file_url, dist, @log) then return false end
-               else
-                       if File.exist? file_url then FileUtils.cp(file_url, dist)
-                       else return false end
-               end
-
-               return true
-       end
-
-       def read_archive_pkg_list(list_path)
-               local_file_path = File.join(list_path, ARCHIVE_PKG_LIST_FILE)
-               if File.exist? local_file_path then
-                       File.open(local_file_path, "r") do |f|
-                               f.each_line do |l|
-                                       pkg = l.strip
-                                       if @archive_pkg_list.index(pkg).nil? then @archive_pkg_list.push(pkg) end
-                               end
-                       end
-                       @log.info "Get archive package infomation.. OK"
-               else
-                       @log.warn "Failed to get archive package infomation"
-               end
-       end
-
-       def download_archive_pkg_list(from_server, dist = nil)
-               if dist.nil? then dist = get_pkglist_path end
-               file_url = File.join(@server_addr, @snapshot_path, ARCHIVE_PKG_LIST_FILE)
-               if from_server then
-                       if not FileDownLoader.download(file_url, dist, @log) then return false end
-               else
-                       if File.exist? file_url then FileUtils.cp(file_url, dist)
-                       else return false end
-               end
-
-               return true
-       end
-
-       def download_pkg_list(from_server, dist = nil)
-               if dist.nil? then dist = get_pkglist_path end
-               @support_os_list.each do |os|
-                       filename = PKG_LIST_FILE_PREFIX + os
-                       file_url = File.join(@server_addr, @snapshot_path, filename)
-                       if from_server then
-                               if not FileDownLoader.download(file_url, dist, @log) then return false end
-                       else
-                               if File.exist? file_url then FileUtils.cp(file_url, dist)
-                               else return false end
-                       end
-               end
-
-               return true
-       end
-
-       private
-       # create installed package hash
-       def read_installed_pkg_list()
-
-               config_path = File.join(@location, PACKAGE_INFO_DIR)
-               if not File.directory? config_path then return end
-
-               installed_pkg_hash_key = get_installed_pkg_list_file_path()
-               if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then return
-               else
-                       file_path = installed_pkg_hash_key
-                       if not File.exist? file_path then
-                               #raise RuntimeError, "#{file_path} file does not exist"
-                               return
-                       end
-                       begin
-                               pkg_hash = Parser.read_repo_pkg_list_from file_path
-                       rescue => e
-                               @log.error( e.message, Log::LV_USER)
-                               return
-                       end
-                       @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
-               end
-       end
-
-       private
-       # check to exist installed package list file
-       def check_installed_pkg_list_file()
-
-               if @location.nil? then raise RuntimeError, "#{@location} path does not exist" end
-               file_path = get_installed_pkg_list_file_path()
-               if File.exist? file_path then return true
-               else return false end
-       end
-
-       private
-       # get installed package list file path
-       def get_installed_pkg_list_file_path()
-
-               file_full_path = File.join(@location, PACKAGE_INFO_DIR, INSTALLED_PKG_LIST_FILE)
-               return file_full_path
-       end
-
-       private
-       # write package hash to file
-       def write_pkg_hash_to_file(pkg_hash)
-
-               file_path = get_installed_pkg_list_file_path()
-               if pkg_hash.nil? then
-                       pkg_hash = @installed_pkg_hash_loc[file_path]
-               end
-               if not pkg_hash.nil? then
-                       config_path = File.join(@location, PACKAGE_INFO_DIR)
-                       if not File.exist? config_path then FileUtils.mkdir_p "#{config_path}" end
-                       if File.exist? file_path then File.delete(file_path) end
-                       File.open(file_path, "a+") do |file|
-                               pkg_list = pkg_hash.values
-                               pkg_list.each do |pkg|
-                                       pkg.print_to_file(file)
-                                       file.puts "\n"
-                               end
-                       end
-               end
-               @log.info "Write package informations to \"#{file_path}\".. OK"
-       end
-
-       private
-       def check_meta_pkg(pkg_name, os)
-               if not check_remote_pkg(pkg_name, os) then return false end
-
-               attr = get_attr_from_pkg(pkg_name, os, "attribute")
-               if attr.nil? or attr.empty? then return false end
-               if attr[0].strip.upcase.eql? "ROOT" then return true
-               else return false end
-       end
-
-       public
-       def register(address, distribution, pkg_file_path, password)
-               # check file exist
-               if not File.exist? pkg_file_path then
-                       puts "The file does not exist!.. #{pkg_file_path}"
-                       return false
-               end
-    
-               result = Utils.parse_server_addr(address)
-               if result.nil? then
-                       puts "Server address is incorrect. (#{address})"
-                       puts "Tune as following format."
-                       puts " <ip>:<port>"
-                       exit 1
-               end
-               bs_ip = result[0]
-               bs_port = result[1]
-
-               pkg_file_path_list = []
-               pkg_file_path_list.push(pkg_file_path)
-               # set distribution
-               @server_addr = distribution
-               ret = upload(bs_ip, bs_port, pkg_file_path_list, nil, nil, nil, nil, password)
-
-               if ret then @log.info "Snapshot is generated : #{ret}" end
-       end
-       
-       ##Print change log to console.
-       public
-       def printChangeLog(snapshot1 = nil, snapshot2 = nil)
-   snapshotPath = File.join(@config_dist_path, PackageServerConstants::SNAPSHOT_INFO_FILE_NAME)
-         @log.info("Read information of snapshot from " + snapshotPath);
-         
-   ssController = SnapshotController.new(snapshotPath);
-         changeLogController = ChangeLogController.new(@server_addr, ssController)
-         
-         if (snapshot1.nil?()) then
-           changeLog = changeLogController.getLatestChangeLog();
-         elsif snapshot2.nil?() then
-           changeLog = changeLogController.getChangeLog(snapshot1);
-         else
-           changeLog = changeLogController.getTotalChangeLog(snapshot1, snapshot2);
-         end
-         
-         puts changeLog
-       end
-       
-       ##Print snapshot list to console.
-       public
-       def printSnapshotList(showAll=false)
-         snapshotPath = File.join(@config_dist_path, PackageServerConstants::SNAPSHOT_INFO_FILE_NAME)
-         @log.info("Read information of snapshot from " + snapshotPath);
-         
-         ssController = SnapshotController.new(snapshotPath);
-         if showAll then
-           result = ssController.getAllSnapshotList;
-         else
-           result = ssController.getManualSnapshotList ;
-         end
-         
-         result.each() do |snapshot|
-           puts PackageServerConstants::SNAPSHOT_NAME_FIELD + ": " + snapshot.getName()
-           puts PackageServerConstants::SNAPSHOT_TIME_FIELD + ": " + snapshot.getTime()
-           puts
-         end
-           
-       end
+        # compress files
+        snapshot = snapshot_path.split('/')[-1]
+        img_name = "TIZEN-SDK-IMG_#{snapshot}_#{os}.zip"
+        cmd = "cd #{workspace}; zip -q -r #{@location}/TIZEN-SDK-IMG_#{snapshot_path.split('/')[-1]}_#{os}.zip *;"
+        Utils.execute_shell_with_log(cmd, @log.path)
+
+        # clean workspace
+        FileUtils.remove_dir(workspace, true)
+        @log.info "<< SDK-Image Info. >>"
+        @log.info " - server addr : #{@server_addr}"
+        @log.info " - snapshot : #{snapshot}"
+        @log.info " - os : #{os}"
+        @log.info " - location : #{location}/"
+        @log.info " - name : #{img_name}"
+
+        return
+    end
+
+    private
+    def get_file_from_cache(filename, pkg_checksum, pkg_size, location)
+        if not File.directory? location then return nil end
+        downloaded_file_path = nil
+        @log.info "Wait for cache sync",Log::LV_USER
+        begin
+            lock = Utils.file_lock(File.join(CONFIG_PATH,".cache_lock"))
+            @log.info "Entering cache sync",Log::LV_USER
+            cached_filepath = get_cached_filepath(filename, pkg_checksum, pkg_size)
+            if not cached_filepath.nil? and File.exist? cached_filepath then
+                #FileUtils.ln(cached_filepath, location, :force => true)
+                if (FileUtil.safeLink(cached_filepath, location)) then
+                    downloaded_file_path = File.join(location, File.basename(cached_filepath))
+                end
+            end
+        ensure
+            Utils.file_unlock(lock) if not lock.nil?
+        end
+        @log.info "Cache sync done",Log::LV_USER
+        if not downloaded_file_path.nil? and not File.exist? downloaded_file_path then
+            downloaded_file_path = nil
+        end
+        return downloaded_file_path
+    end
+
+    private
+    def add_file_to_cache(filepath)
+        if filepath.nil? or filepath.empty? or not File.exist? filepath then return end
+        if not File.exist? @download_path then FileUtils.mkdir_p "#{@download_path}" end
+
+        filename = File.basename(filepath)
+        cachefile = File.join(@download_path, filename)
+
+        @log.info "Moving \"#{filename}\" to download cache directory"
+        @log.info "  [path: #{@download_path}]"
+
+        if not File.exist? cachefile then
+            #FileUtils.ln(filepath, @download_path, :force => true)
+            if not FileUtil.safeLink(filepath, @download_path) then
+                @log.info "Failed to link file [#{filepath}] to "
+                @log.info "  [#{@download_path}]"
+            end
+        end
+
+        if not File.exist? cachefile then
+            @log.info "Failed to move [#{filename}] to "
+            @log.info "  [#{@download_path}]"
+        end
+
+        begin
+            lock = Utils.file_lock(File.join(CONFIG_PATH,".cache_lock"))
+
+            remove_old_files_in_cache
+        ensure 
+            Utils.file_unlock(lock) if not lock.nil?
+        end
+    end
+
+    private
+    def remove_snapshots()
+        listing_prefix = "#{@snapshots_path}/*"
+        dirs = Dir[listing_prefix].sort_by { |f| File.mtime(f) }.reverse
+
+        if not dirs.nil? and dirs.length >= 20 then
+            Utils.execute_shell("rm -rf #{dirs[19..-1].join(" ")}")
+            @log.info "Removed old snapshots.."
+            @log.info "  * #{dirs[19]} ~ "
+        end
+    end
+
+    private
+    def get_cached_filepath(pkg_filename, pkg_checksum, pkg_size)
+        cached_filepath = "#{@download_path}/#{pkg_filename}"
+        if File.exist? cached_filepath then
+            if Utils.validatePkgFile(cached_filepath, pkg_checksum, pkg_size) then
+                FileUtils.touch cached_filepath
+                return cached_filepath
+            else
+                return nil
+            end
+        end
+        return nil
+    end
+
+    public
+    # download dependent source
+    def download_dep_source(file_name)
+
+        file_url = @server_addr + "/source/#{file_name}"
+        if not FileDownLoader.download(file_url, @location, @log) then
+            @log.error "Failed download #{file_name}"
+            return nil
+        end
+        file_local_path = File.join(@location, file_name)
+        @log.info "Downloaded \"#{file_name}\" source file.. OK"
+        @log.info "  [path: #{file_local_path}]"
+
+        return file_local_path
+    end
+
+    private
+    def upload_request(ip, port, dock, transporter, binary_path_list)
+        binary_path_list.each do |bpath|
+            client2 = BuildCommClient.create(ip, port, @log)
+            begin
+                if client2.nil? then
+                    raise RuntimeError, "Failed to create BuildCommClient instance.."
+                end
+
+                @log.info "Send UPLOAD REQ..  [UPLOAD|#{dock}]"
+                result = client2.send("UPLOAD|#{dock}")
+                if not result then
+                    raise RuntimeError, "Failed to send ready REQ.."
+                end
+                result = client2.send_file(bpath, transporter)
+            ensure
+                client2.terminate
+            end
+        end
+    end
+
+    public
+    # upload package
+    def upload(ip, port, binary_path_list, ftp_addr=nil, ftp_port=nil, ftp_username=nil, ftp_passwd=nil, password="")
+
+        # check ip and port
+        if ip.nil? or port.nil? then
+            @log.error "Ip and port should be set."
+            return nil
+        end
+
+        # check binary path list
+        if binary_path_list.nil? or binary_path_list.empty? then
+            @log.error "Binary package path should be set."
+            return nil
+        end
+
+        begin
+            if not ftp_addr.nil? then
+                transporter=FileTransferFTP.new(@log, ftp_addr, ftp_port, ftp_username, ftp_passwd)
+            else
+                transporter=FileTransferDirect.new(@log)
+            end
+        rescue => e
+            @log.error "FTP failed to put file (exception)"
+            @log.error "#{e.message}"
+            @log.error e.backtrace.inspect
+            return nil
+        end
+
+        binary_list = []
+        binary_path_list.each do |binary_path|
+            if File.exist? binary_path then
+                binary_list.push(File.basename(binary_path))
+            else
+                @log.error "Binary file does not exist"
+                return nil
+            end
+        end
+
+        client = BuildCommClient.create(ip, port, @log)
+        if client.nil? then
+            @log.error "Can't access server #{ip}:#{port}"
+            return nil
+        end
+
+        begin
+            # create unique dock number
+            dock = Utils.create_uniq_name()
+
+            dist = get_distribution
+            if dist.empty? then
+                @log.error "Distribution is empty.."
+                return nil
+            end
+
+            @log.info "Send register message..  [REGISTER|#{dist}|#{password}|DOCK|#{dock}|#{binary_list.join("|")}]"
+            snapshot = nil
+
+            client.send "REGISTER|#{dist}|#{password}|DOCK|#{dock}|#{binary_list.join("|")}" 
+
+            client.read_lines do |line|
+                if line.eql?("WAITFORUPLOAD") then
+                    # upload
+                    @log.info "Get WAITFORUPLOAD message"
+                    thread = Thread.new do
+                        begin 
+                            upload_request(ip, port, dock, transporter, binary_path_list)
+                        rescue => e
+                            puts "Transfering file failed!"
+                            puts e.message
+                        end
+                    end
+
+                    thread.join
+                    client.send("REGISTERCONTINUE")
+                elsif line.start_with? "SUCC" then
+                    snapshot = line.split("|")[1]
+                elsif line.start_with? "ERROR" then
+                    @log.error line.strip
+                    return nil
+                else
+                    @log.error "Unknown message received : #{l}"
+                end
+            end
+        ensure
+            client.terminate
+        end
+
+        if not snapshot.nil? and not snapshot.empty? then
+            snapshot = @server_addr + "/snapshots/" + snapshot
+            @log.info "Registered successfully!  [#{binary_path_list.join("|")}]"
+            if snapshot.empty? then
+                @log.error "Failed to generate snapshot"
+            end
+
+            return snapshot
+        else
+            return nil
+        end
+    end
+
+    private
+    # verify package before uploading
+    def verify_upload(pkg_name, pkg_path)
+
+        manifest_file = "pkginfo.manifest"
+        uniq_name = Utils.create_uniq_name
+        path = Utils::HOME + "/tmp/#{uniq_name}"
+        if not File.exist? path then FileUtils.mkdir_p "#{path}" end
+        begin
+            if not FileInstaller.extract_a_file(pkg_path, manifest_file, path, @log) then
+                @log.error "The \"pkginfo.manifest\" file does not exist in \"#{pkg_path}\""
+                return false
+            end
+            manifest_path = File.join(path, manifest_file)
+            pkg = Parser.read_single_pkginfo_from manifest_path
+            if File.exists? manifest_path then FileUtils.rm_f(manifest_path) end
+            FileUtils.remove_dir(path, true)
+        rescue Interrupt
+            @log.error "Client: Interrupted.."
+            FileUtils.remove_dir(path, true)
+            @log.info "Removed #{path}"
+            raise Interrupt
+        rescue RuntimeError => e
+            @log.error( e.message, Log::LV_USER)
+            FileUtils.remove_dir(path, true)
+            @log.info "Removed #{path}"
+            return false
+        end
+        new_pkg_ver = pkg.version
+        new_pkg_install_dep_list = pkg.install_dep_list
+        os = pkg.os
+
+        list = get_all_reverse_install_dependent_packages_remote(pkg_name, os, true)
+
+        if not list.nil? then
+            list.each do |p|
+                ilist = get_attr_from_pkg(p, os, "install_dep_list")
+                if ilist.nil? then next end
+                ilist.each do |l|
+                    if l.package_name.eql? pkg_name then
+                        if not l.match? new_pkg_ver then
+                            @log.error "\"#{p}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
+                            return false
+                        end
+                    end
+                end
+            end
+        end
+
+        if not new_pkg_install_dep_list.nil? then
+            new_pkg_install_dep_list.each do |l|
+                if not check_remote_pkg(l.package_name, os) then
+                    @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version}), but \"#{l.package_name}\" is not exist on server"
+                    return false
+                end
+                rver = get_attr_from_pkg(l.package_name, os, "version")
+                if not l.match? rver then
+                    @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
+                    return false
+                end
+            end
+        end
+
+        @log.info "Passed to verify packages for uploading.. OK"
+        return true
+    end
+
+    private
+    # get distribution
+    def get_distribution()
+        server = @server_addr
+        if server.nil? or server.empty? then
+            @log.error "Server addr is nil"
+            return nil
+        end
+
+        dist = ""
+        dist = File.basename(server)
+
+        return dist
+    end
+
+    private
+    def get_flat_serveraddr()
+        server = @server_addr
+        if server.nil? or server.empty? then
+            @log.error "Server addr is nil"
+            @log.error "check sync_pkg_servers table pkgsvr_url column is null"
+            return "nil"
+        end
+
+        server = server.delete ".:/@"
+        return server
+    end
+
+    public
+    # install package
+    # install all install dependency packages
+    def install(pkg_name, os, trace, force)
+
+        ret = install_internal( pkg_name, os, trace, force )
+        return ret
+    end
+
+
+    private
+    def install_internal(pkg_name, os, trace, force)
+
+        if trace.nil? then trace = true end
+        if force.nil? then force = false end
+
+        # check meta package
+        is_meta_pkg = check_meta_pkg(pkg_name, os)
+        if is_meta_pkg then trace = true end
+
+        # compare package version with installed package's
+        pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+        if pkg_ver.nil? or pkg_ver.empty? then
+            @log.error "#{pkg_name} package does not exist in remote package list"
+            return false
+        end
+
+
+        compare_result = compare_version_with_installed_pkg(pkg_name, pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+                @log.warn "Checked \"#{pkg_name}\" package version : it is bigger then remote package version"
+                return true
+            when 0 then
+                @log.warn "Checked \"#{pkg_name}\" package version : it is same with remote package version"
+                return true
+            when 1, 2 then
+            end
+        end
+
+        # if enable trace, create all dependent package list
+        if trace then
+            dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, force)
+            if dependent_pkg_list.nil? then
+                @log.error "Failed to get dependency for \"#{pkg_name}\" package"
+                return false
+            end
+        else
+            dependent_pkg_list = [pkg_name]
+        end
+
+        # TODO: need to compare dependent package version
+        # install packages including dependent packages
+        dependent_pkg_list.each do |pkg|
+            if not install_pkg(pkg, os, force) then
+                @log.error "#{pkg} does not exist"
+                return false
+            end
+            add_pkg_info(pkg, os)
+        end
+
+        # write installed package information to file
+        write_pkg_hash_to_file(nil)
+
+        if trace then
+            @log.info "Installed \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
+            @log.info "  [#{dependent_pkg_list.join(" -> ")}]"
+        else
+            @log.info "Install only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
+        end
+
+        return true
+    end
+
+
+    public
+    # install local package (ignore dependent packages)
+    def install_local_pkg(pkg_path, trace, force, repos_paths = nil)
+
+        ret = install_local_pkg_internal(pkg_path, trace, force, repos_paths)
+        return ret
+    end
+
+
+    private
+    def install_local_pkg_internal(pkg_path, trace, force, repos_paths)
+
+        pkg_name = Utils.get_package_name_from_package_file( pkg_path )
+        pkg_os = Utils.get_os_from_package_file( pkg_path )
+
+        if not File.exist? pkg_path then
+            @log.error "\"#{pkg_path}\" file does not exist"
+            return false
+        end
+        filename = File.basename(pkg_path)
+        ext = File.extname(filename)
+        if not ext.eql? ".zip" then
+            @log.error "\"#{filename}\" is not zip file. binary package file should have .zip ext"
+            return false
+        end
+        pkg_name = filename.split("_")[0]
+        manifest_file = "pkginfo.manifest"
+
+        uniq_name = Utils.create_uniq_name
+        path = Utils::HOME + "/tmp/#{uniq_name}"
+        if not File.exist? path then FileUtils.mkdir_p "#{path}" end
+        begin
+            if not FileInstaller.extract_a_file(pkg_path, manifest_file, path, @log) then
+                @log.error "pkginfo.manifest file does not exist in #{pkg_path}"
+                return false
+            end
+            manifest_path = File.join(path, manifest_file)
+            pkg = Parser.read_single_pkginfo_from manifest_path
+            new_pkg_ver = pkg.version
+            pkg_conflicts = pkg.conflicts
+            FileUtils.remove_dir(path, true)
+        rescue Interrupt
+            @log.error "Client: Interrupted.."
+            FileUtils.remove_dir(path, true)
+            @log.info "Removed #{path}"
+            raise Interrupt
+        rescue RuntimeError => e
+            @log.error( e.message, Log::LV_USER)
+            FileUtils.remove_dir(path, true)
+            @log.info "Removed #{path}"
+            return false
+        end
+
+        compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+                @log.warn "Installed \"#{pkg_name}\" package version is bigger.."
+                return true
+            when 0 then
+                @log.warn "Checked \"#{pkg_name}\" package version : it is same with installed package version"
+                return true
+            when 1, 2 then
+            end
+        end
+
+        if check_installed_pkg(pkg_name) then
+            uninstall(pkg_name, false)
+        end
+
+        # TODO: Resolve conflicts
+        if not resolve_conflicts_internal(pkg_conflicts) then
+            @log.error "Failed to resolve conflicts [#{pkg_name}]"
+            return false
+        end            
+
+
+        if trace then
+            install_dep_pkgs = pkg.install_dep_list
+            new_pkg_os = pkg_os
+            install_dep_pkgs.each do |p|
+                # check local path first
+                if not repos_paths.nil? then
+                    # search
+                    binpkgs = []
+                    repos_paths.each do  |repos_path|
+                        binpkgs += Dir.glob("#{repos_path}/#{p.package_name}_*_#{new_pkg_os}.zip")
+                    end
+                    if not binpkgs.empty? then
+                        if not install_local_pkg_internal(binpkgs[0], true, false, repos_paths) then
+                            @log.warn "#{p} package is not installed"
+                        end
+                    else
+                        if not install_internal(p.package_name, new_pkg_os, true, false) then
+                            @log.warn "#{p} package is not installed"
+                        end
+                    end
+                else
+                    if not install_internal(p.package_name, new_pkg_os, true, false) then
+                        @log.warn "#{p} package is not installed"
+                    end
+                end
+            end
+        end
+
+        # install package
+        ret = FileInstaller.install(pkg_name, pkg_path, "binary", @location, @log)
+
+        if not ret then
+            @log.error "Install failed \"#{pkg_path} [#{new_pkg_ver}]\" file.. "
+            return false
+        end
+
+        add_local_pkg_info(pkg_name)
+        write_pkg_hash_to_file(nil)
+
+        @log.info "Installed \"#{pkg_path} [#{new_pkg_ver}]\" file.. OK"
+        return true
+    end
+
+
+    public
+    # upgrade package
+    def upgrade(os, trace)
+
+        if trace.nil? then trace = true end
+        list = check_upgrade(os)
+
+        if list.empty? or list.nil? then
+            @log.info "There is no packages for upgrading.."
+            return false
+        end
+
+        list.each do |p|
+            if check_installed_pkg(p) then
+                if not uninstall(p, trace) then
+                    @log.error "Failed to uninstall \"#{p}\" package.."
+                    return false
+                end
+            end
+
+            if not install_internal(p, os, trace, false) then
+                @log.error "Failed to install \"#{p}\" package.."
+                return false
+            end
+        end
+
+        @log.info "Upgraded packages from #{@server_addr}.. OK"
+        return true
+    end
+
+    public
+    # check package which will be upgraded
+    def check_upgrade(os)
+
+        update_pkgs = []
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        installed_pkg_hash = installed_pkg_hash_loc[installed_pkg_hash_key]
+        remote_pkg_hash = pkg_hash_os[os]
+
+        if remote_pkg_hash.nil? then
+            @log.error "There is no remote package list for #{os}."
+            return nil
+        end
+
+        if installed_pkg_hash.nil? then
+            @log.warn "There is no any installed package in \"#{@location}\""
+            return remote_pkg_hash.keys
+        end
+
+        arr_keys = installed_pkg_hash.keys
+        arr_keys.each do |k|
+            installed_ver = get_attr_from_installed_pkg(k, "version")
+            if not check_remote_pkg(k, os) then next end
+            remote_ver = get_attr_from_pkg(k, os, "version")
+            compare_result = compare_version_with_installed_pkg(k, remote_ver)
+            case compare_result
+            when -1 then next
+            when 0 then next
+            when 1 then
+                @log.output "\"#{k}\" package : #{installed_ver} -> #{remote_ver}"
+                update_pkgs.push(k)
+            end
+        end
+
+        @log.info "Checked packages for upgrading.. OK"
+        return update_pkgs
+    end
+
+    public
+    # get default path for installing
+    def get_default_inst_dir()
+        return Dir.pwd
+    end
+
+    public
+    # uninstall package
+    # trace : if true, uninstall all dependent packages
+    def uninstall(pkg_name, trace)
+
+        type = "binary"
+        pkg_list = []
+        pkg_hash = nil
+
+        if not check_installed_pkg(pkg_name) then
+            @log.error "\"#{pkg_name}\" package is not installed."
+            return false
+        end
+
+        pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
+
+        if trace then
+            pkg_list = get_all_reverse_install_dependent_packages(pkg_name, true)
+            if pkg_list.nil? then
+                @log.error "Failed to get \"#{pkg_name}\" package dependency information."
+                return false
+            end
+        else
+            pkg_list.push(pkg_name)
+        end
+
+        pkg_list.each do |p|
+            if not check_installed_pkg(p) then next end
+            if not FileInstaller.uninstall(p, type, @location, @log) then
+                @log.error "Failed uninstall \"#{pkg_name}\" package"
+                return false
+            end
+            pkg_hash = remove_pkg_info(p)
+        end
+
+        if trace then
+            @log.info "Uninstalled \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
+            @log.info "  [#{pkg_list.join(" -> ")}]"
+        else
+            @log.info "Uninstalled only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
+        end
+
+        write_pkg_hash_to_file(nil)
+        return true
+    end
+
+    public
+    # clean
+    def clean(force)
+        if not force then
+            puts "Do you really want to remove \"#{@location}\" path? [yes]"
+            input = $stdin.gets.strip
+            if input.upcase.eql? "YES" then
+                @log.info "Removed \"#{@location}\""
+            else
+                @log.info "Canceled"
+                return
+            end
+        end
+        if File.exist? @location then FileUtils.rm_rf(@location) end
+        FileUtils.mkdir_p(@location)
+        #@pkg_hash_os.clear
+        @installed_pkg_hash_loc.clear
+        #@archive_pkg_list.clear
+        @log.info "Cleaned \"#{@location}\" path.. OK"
+    end
+
+    public
+    # get reverse build dependent packages (just 1 depth)
+    def get_reverse_build_dependent_packages(pkg_name, os)
+
+        result = []
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then return [] end
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.build_dep_list.each do |dep|
+                if dep.package_name.eql? pkg_name and
+                    not dep.target_os_list.nil? and
+                    dep.target_os_list.include? os then
+                    result.push(pkg)
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+    # get reverse source dependent packages (just 1 depth)
+    def get_reverse_source_dependent_packages(pkg_name)
+
+        result = []
+        @support_os_list.each do |os|
+            pkg_hash = @pkg_hash_os[os]
+            pkg_list = pkg_hash.values
+            pkg_list.each do |pkg|
+                pkg.source_dep_list.each do |p|
+                    if p.package_name.eql? pkg_name then
+                        result.push(pkg)
+                    end
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+    # get reverse install dependent packages (jush 1 depth)
+    def get_reverse_install_dependent_packages(pkg_name, os)
+
+        result = []
+        pkg_hash = @pkg_hash_os[os]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |p|
+                if p.package_name.eql? pkg_name then
+                    result.push(pkg.package_name)
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+    # get all build dependent packages (considered build priority, and reverse)
+    def get_build_dependent_packages(pkg_name, os, reverse)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        @all_dep_list.clear
+        begin
+            get_build_dependency_arr(pkg_name, os, 0)
+            # in case of cross build dependency
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+
+        max = 0
+        @all_dep_list.each do |p|
+            if p[0].to_i > max then
+                max = p[0].to_i
+            else next end
+        end
+
+        result = []
+        i = 0
+        while i <= max
+            @all_dep_list.each do |p|
+                if p[0].to_i.eql? i then
+                    d = p[1]
+                    remote_os = get_attr_from_pkg(d.package_name, os, "os")
+                    remote_ver = get_attr_from_pkg(d.package_name, os, "version")
+                    if not d.target_os_list.include? remote_os then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.target_os_list.to_s}, but \"#{d.package_name}\" (#{remote_os}) package is in server"
+                        return nil
+                    end
+                    if not d.match? remote_ver then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
+                        return nil
+                    else result.push(d.package_name) end
+                end
+            end
+            i = i + 1
+        end
+
+        @log.info "Get build dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse.uniq.push(pkg_name)
+        else return result.uniq.insert(0, pkg_name) end
+    end
+
+    public
+    # get all install dependent packages (considered install priority, reverse, and force)
+    # reverse : return reverse result
+    # force : install package force
+    def get_install_dependent_packages(pkg_name, os, reverse, force)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        @all_dep_list.clear
+        begin
+            get_install_dependency_arr(pkg_name, os, force, 0)
+            # in case of cross build dependency
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+
+        max = 0
+        @all_dep_list.each do |p|
+            if p[0].to_i > max then
+                max = p[0].to_i
+            else next end
+        end
+
+        result = []
+        i = 0
+        while i <= max
+            @all_dep_list.each do |p|
+                if p[0].to_i.eql? i then
+                    d = p[1]
+                    remote_ver = get_attr_from_pkg(d.package_name, os, "version")
+                    if not d.match? remote_ver then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
+                        return nil
+                    else result.push(d.package_name) end
+                end
+            end
+            i = i + 1
+        end
+
+        @log.info "Get install dependent packages for \"#{pkg_name}\" package.. OK"
+        if reverse then return result.reverse.uniq.push(pkg_name)
+        else return result.uniq.insert(0, pkg_name) end
+    end
+
+    public
+    # get all install dependent packages for except (considered install priority, reverse, and force)
+    # reverse : return reverse result
+    # force : install package force
+    def get_install_dependent_packages_with_except(pkg_name, os, reverse, force, input_list)
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        @all_dep_list.clear
+        begin
+            get_install_dependency_arr_with_except(pkg_name, os, force, 0, input_list)
+            # in case of cross build dependency
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+
+        max = 0
+        @all_dep_list.each do |p|
+            if p[0].to_i > max then
+                max = p[0].to_i
+            else next end
+        end
+
+        result = []
+        i = 0
+        while i <= max
+            @all_dep_list.each do |p|
+                if p[0].to_i.eql? i then
+                    d = p[1]
+                    remote_ver = get_attr_from_pkg(d.package_name, os, "version")
+                    if not d.match? remote_ver then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
+                        return nil
+                    else result.push(d.package_name) end
+                end
+            end
+            i = i + 1
+        end
+
+        @log.info "Get install dependent packages for \"#{pkg_name}\" package.. OK"
+        if reverse then return result.reverse.uniq.push(pkg_name)
+        else return result.uniq.insert(0, pkg_name) end
+    end
+
+    public
+    # get all reverse install dependent packages (considered reverse install priority for tracing uninstall)
+    def get_all_reverse_install_dependent_packages(pkg_name, reverse)
+
+        if not check_installed_pkg(pkg_name) then return nil end
+        if reverse.nil? then reverse = true end
+
+        begin
+            res = get_all_reverse_install_dependency_arr(pkg_name, 0)
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+        res2 = res.split("::")
+        result = []
+        res2.each do |r|
+            result.push(r.split(':')[1])
+        end
+
+        @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse.uniq
+        else return result end
+    end
+
+    public
+    # get all reverse remote dependent packages (considered reverse install priority for tracing uninstall)
+    def get_all_reverse_install_dependent_packages_remote(pkg_name, os, reverse)
+        #if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        begin
+            res = get_all_reverse_install_dependency_arr_remote(pkg_name, os, 0)
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+        res2 = res.split("::")
+        result = []
+        res2.each do |r|
+            result.push(r.split(':')[1])
+        end
+
+        @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse
+        else return result end
+    end
+
+    public
+    # check package whether to exist in remote server
+    def check_remote_pkg(pkg_name, os)
+
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then return false end
+        pkg = pkg_hash[pkg_name]
+        if pkg.nil? then
+            #@log.warn "There is no \"#{pkg_name}\" remote package information in list"
+            return false
+        end
+
+        return true
+    end
+
+    public
+    # check package whether to exist in installed packages
+    def check_installed_pkg(pkg_name)
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+        if pkg_hash.nil? then return false end
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then return false end
+        return true
+    end
+
+    public
+    # get attribute from installed package
+    def get_attr_from_installed_pkg(pkg_name, attr)
+
+        if not check_installed_pkg(pkg_name) then return nil end
+        pkg = get_installed_pkg_from_list(pkg_name)
+
+        if pkg.nil? then return nil end
+
+        case attr
+        when "version" then return pkg.version
+        when "source" then return pkg.source
+        when "src_path" then return pkg.src_path
+        when "os" then return pkg.os
+        when "build_dep_list" then return pkg.build_dep_list
+        when "install_dep_list" then return pkg.install_dep_list
+        when "attribute" then return pkg.attribute
+        end
+    end
+
+    public
+    # get attribute from remote package
+    def get_attr_from_pkg(pkg_name, os, attr)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        pkg = get_pkg_from_list(pkg_name, os)
+
+        if pkg.nil? then return nil end
+
+        case attr
+        when "name" then return pkg.package_name
+        when "path" then return pkg.path
+        when "source" then return pkg.source
+        when "version" then return pkg.version
+        when "src_path" then return pkg.src_path
+        when "os" then return pkg.os
+        when "build_dep_list" then return pkg.build_dep_list
+        when "install_dep_list" then return pkg.install_dep_list
+        when "attribute" then return pkg.attribute
+        when "checksum" then return pkg.checksum
+        when "size" then return pkg.size
+        when "conflicts" then return pkg.conflicts                             
+
+        end
+    end
+
+    public
+    # show a package information
+    def show_pkg_info(pkg_name, os)
+        if not check_remote_pkg(pkg_name, os) then
+            @log.error "\"#{pkg_name}\" package does not exist"
+            return ""
+        end
+
+        pkg = get_pkg_from_list(pkg_name, os)
+        return pkg.to_s
+    end
+
+    public
+    # show all packages information
+    def show_pkg_list(os)
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then
+            @log.error "\"#{os}\" package list does not exist"
+            return ""
+        end
+
+        pkg_all_list = []
+        pkg_list = pkg_hash.values
+        pkg_list.each do |p|
+            pkg_all_list.push([p.package_name, p.version, p.description])
+        end
+        return pkg_all_list.sort
+    end
+
+    public
+    # show installed package information
+    def show_installed_pkg_info(pkg_name)
+
+        if not check_installed_pkg(pkg_name) then
+            @log.error "\"#{pkg_name}\" package does not exist"
+            return ""
+        end
+
+        pkg = get_installed_pkg_from_list(pkg_name)
+        return pkg.to_s
+    end
+
+    public
+    # show all installed packages information
+    def show_installed_pkg_list()
+
+        file_path = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[file_path]
+        if pkg_hash.nil? then
+            @log.error "Installed package list does not exist"
+            return nil
+        end
+        pkg_all_list = []
+        pkg_list = pkg_hash.values
+        pkg_list.each do |p|
+            pkg_all_list.push([p.package_name, p.version, p.description])
+        end
+        return pkg_all_list.sort
+    end
+
+    private
+    def get_build_dependency_arr(pkg_name, os, n)
+        pkg_hash = @pkg_hash_os[os]
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then
+            @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
+            return
+        end
+
+        # if package is already installed, skip tracing dependency
+        if check_installed_pkg(pkg_name) then
+            # compare version with installed package version
+            new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+            compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+            if compare_result == -1 or compare_result == 0 then return end
+        end
+
+        pkg.build_dep_list.each do |l|
+            @all_dep_list.push([n, l])
+            get_build_dependency_arr(l.package_name, os, n+1)
+        end
+
+        return
+    end
+
+    private
+    def get_install_dependency_arr(pkg_name, os, force, n)
+
+        pkg_hash = @pkg_hash_os[os]
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then
+            @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
+            return
+        end
+
+        # if package is already installed, skip tracing dependency
+        if check_installed_pkg(pkg_name) then
+            # compare version with installed package version
+            new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+            compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+            if not force then
+                if compare_result == -1 or compare_result == 0 then return end
+            end
+        end
+
+        pkg.install_dep_list.each do |l|
+            @all_dep_list.push([n, l])
+            get_install_dependency_arr(l.package_name, os, force, n+1)
+        end
+
+        return
+    end
+
+    private
+    def get_install_dependency_arr_with_except(pkg_name, os, force, n, input_list)
+
+        pkg_hash = @pkg_hash_os[os]
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then
+            @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
+            return
+        end
+
+        if !(pkg.install_dep_list.empty?) then
+            rem_list = []
+            pkg.install_dep_list.each do |i|
+                input_list.each do |j|
+                    if i.package_name.eql? j then
+                        rem_list.push(i)
+                    end
+                end
+            end
+            pkg.install_dep_list = pkg.install_dep_list - rem_list
+        end
+
+        pkg.install_dep_list.each do |l|
+            @all_dep_list.push([n, l])
+            get_install_dependency_arr_with_except(l.package_name, os, force, n+1, input_list)
+        end
+
+        return
+    end
+
+    private
+    def get_all_reverse_install_dependency_arr(pkg_name, n)
+
+        s = "#{n}:#{pkg_name}"
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |l|
+                if l.package_name.eql? pkg_name then
+                    s = s + "::" + get_all_reverse_install_dependency_arr(pkg.package_name, n+1)
+                end
+            end
+        end
+
+        return s
+    end
+
+    private
+    def get_all_reverse_install_dependency_arr_remote(pkg_name, os, n)
+
+        s = "#{n}:#{pkg_name}"
+        pkg_hash = @pkg_hash_os[os]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |l|
+                if l.package_name.eql? pkg_name then
+                    s = s + "::" + get_all_reverse_install_dependency_arr_remote(pkg.package_name, os, n+1)
+                end
+            end
+        end
+
+        return s
+    end
+
+    public
+    def get_pkg_from_list(pkg_name, os)
+
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then return nil end
+
+        pkg = pkg_hash[pkg_name]
+
+        return pkg
+    end
+
+    private
+    def get_installed_pkg_from_list(pkg_name)
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+        pkg = pkg_hash[pkg_name]
+        if pkg.nil? then return nil end
+
+        return pkg
+    end
+
+    private
+    def resolve_conflicts_internal(conflicts_pkgs)
+        if conflicts_pkgs.nil? then return true end                    
+        conflicts_pkgs.each do |pkg|
+            if check_installed_pkg(pkg.package_name) then                              
+                if not uninstall(pkg.package_name, true) then
+                    @log.error "Failed to uninstall [#{pkg.package_name}] package for resolving"                                       
+                    return false
+                else
+                    @log.info "Resolved conflict package [#{pkg.package_name}]"                                        
+                end
+            end                                
+        end    
+        return true
+    end                        
+
+    private
+    def resolve_conflicts(pkg_name, os)
+        conflicts = get_attr_from_pkg(pkg_name, os, "conflicts")
+        return resolve_conflicts_internal(conflicts)
+    end        
+
+    private
+    # install a package to @location after uninstalling and downloading
+    def install_pkg(pkg_name, os, force)
+
+        new_pkg_ver = ""
+
+        # install remote server package file
+        if not check_remote_pkg(pkg_name, os) then
+            @log.error "\"#{pkg_name}\" package does not exist in remote server"
+            return false
+        end
+        path = get_attr_from_pkg(pkg_name, os, "path")
+        # type should be binary. type = "binary"
+        # below code should be changed
+        type = path.split('/')[-2]
+        new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+
+        # compare version with installed package versiona
+        compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+                @log.warn "Checked \"#{pkg_name}\" package version : it is bigger then remote package version"
+                return true
+            when 0 then
+                @log.warn "Checked \"#{pkg_name}\" package version : it is same with remote package version"
+                return true
+            end
+        end
+
+        # if package is already installed, then uninstall it
+        if check_installed_pkg(pkg_name) then
+            if not uninstall(pkg_name, false) then
+                @log.error "Failed to uninstall \"#{pkg_name}\""
+                return false
+            end
+        end
+
+        # resolve conflict packages
+        if not resolve_conflicts(pkg_name, os) then
+            @log.error "Failed to resolve conflicts [#{pkg_name}]"
+            return false
+        end
+
+        # install package
+        #download
+        tmp_location = nil
+        begin
+            tmp_location = File.join(@tmp_path,Utils.create_uniq_name)
+            filepath = download(pkg_name, os, false, tmp_location)
+            if filepath.nil? or filepath[0].nil? then
+                return false
+            end
+
+            #install
+            ret = FileInstaller.install(pkg_name, filepath[0], type, @location, @log)
+        ensure
+            #remove garbage
+            FileUtils.rm_rf tmp_location if not tmp_location.nil? and File.exist? tmp_location
+        end
+
+        return ret
+    end
+
+    private
+    def compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+
+        if check_installed_pkg_list_file() then
+            read_installed_pkg_list()
+            if check_installed_pkg(pkg_name) then
+                installed_pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
+                compare_result = Utils.compare_version(installed_pkg_ver, new_pkg_ver)
+                return compare_result
+            end
+        end
+
+        return 2
+    end
+
+    private
+    def remove_pkg_info(pkg_name)
+
+        pkg_hash = {}
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+            if pkg_hash.include? pkg_name then
+                pkg_hash.delete(pkg_name)
+            end
+            @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+        else return nil end
+
+        @log.info "Removed information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    def add_pkg_info(pkg_name, os)
+
+        pkg_hash = {}
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+            pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os)
+        else pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os) end
+        @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+
+        #@log.info "Added information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    # add package manifest info
+    def add_local_pkg_info(pkg_name)
+
+        config_path = File.join(@location, PACKAGE_INFO_DIR, "#{pkg_name}")
+        pkg = read_pkginfo_file(pkg_name, config_path)
+
+        if pkg.nil? then
+            @log.error "Failed to read pkginfo.manifest file"
+            return nil
+        end
+
+        pkg_hash = {}
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+            pkg_hash[pkg_name] = pkg
+        else pkg_hash[pkg_name] = pkg end
+        @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+
+        #@log.info "Added information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    # read package manifet info
+    def read_pkginfo_file(pkg_name, path)
+
+        file_path = File.join(path, "pkginfo.manifest")
+        begin
+            pkg = Parser.read_single_pkginfo_from file_path
+        rescue => e
+            @log.error( e.message, Log::LV_USER)
+            return nil
+        end
+
+        if pkg.nil? then
+            @log.error "Failed to read manifest file : #{file_path}"
+            return nil
+        end
+
+        @log.info "Read information for \"#{pkg_name}\" package.. OK"
+        return pkg
+    end
+
+    # get the lastest snapshot
+    # from_server : if true, update from server
+    def get_lastest_snapshot(from_server)
+        ssinfo_file = "snapshot.info"
+        file_url = File.join(@server_addr, ssinfo_file)
+        if from_server then
+            if not FileDownLoader.download(file_url, @config_dist_path, @log) then
+                @log.error "Server does not have \"#{ssinfo_file}\" file."
+                return nil 
+            end
+        else
+            if File.exist? file_url then 
+                FileUtils.cp(file_url, @config_dist_path)
+            else 
+                @log.error "Server does not have \"#{ssinfo_file}\" file."
+                return nil 
+            end
+        end
+
+        file_path = File.join(@config_dist_path, ssinfo_file)
+        if not File.exist? file_path then return nil end
+
+        contents = File.open(file_path, "r").read
+
+        _list = contents.split("\n\n")
+        if _list.nil? or _list == "" or _list.empty? then return nil end
+        list = _list[-1].split("\n")
+        if list.nil? or list == "" or list.empty? then return nil end
+        _path = list[-1].split(":")
+        if _path.nil? or _path == ""  or _path.length != 2 then return nil end
+        path = _path[1].strip
+        if path == nil or path == "" then return nil end
+
+        return path
+    end
+
+    def get_pkglist_path()
+        return File.join(@config_dist_path, @snapshot_path)
+    end
+
+    # if url includes snapshot infomation, retuen true
+    def is_snapshot_url(addr = nil)
+        if addr.nil? then addr = @server_addr end
+        addr_arr = addr.split('/')
+        if addr_arr[-2].eql? "snapshots" then
+            return true
+        else
+            return false
+        end
+    end
+
+    def split_addr_and_snapshot(addr = nil)
+        if addr.nil? then addr = @server_addr end
+        addr_arr = addr.split('/')
+        if addr_arr[-2].eql? "snapshots" then
+            return addr_arr[0..-3].join("/"), "/"+addr_arr[-2..-1].join("/")
+        else
+            return nil
+        end
+    end
+
+    def is_snapshot_exist(ss_path = nil)
+        if ss_path.nil? then ss_path = @snapshot_path
+        elsif ss_path == "" then return false end
+
+        local_snapshot_path = File.join(@config_dist_path, ss_path)
+        if File.directory? local_snapshot_path then return true
+        else return false end
+    end
+
+    def read_remote_pkg_list(list_path)
+        @support_os_list.each do |os|
+            filename = PKG_LIST_FILE_PREFIX + os
+            local_file_path = File.join(list_path, filename)
+            if File.exist? local_file_path then
+                begin
+                    pkg_hash = Parser.read_repo_pkg_list_from local_file_path
+                    @pkg_hash_os[os] = pkg_hash
+                    @log.info "Get package information for #{os}.. OK"
+                rescue => e
+                    @log.error( e.message, Log::LV_USER)
+                    @pkg_hash_os[os] = {}
+                end
+            else
+                @log.warn "Failed to read pkg_list_#{os} file"
+                @pkg_hash_os[os] = {}
+            end
+        end
+    end
+
+    def read_supported_os_list(list_path)
+        local_file_path = File.join(list_path, OS_INFO_FILE)
+        if File.exist? local_file_path then
+            File.open(local_file_path, "r") do |f|
+                f.each_line do |l|
+                    os = l.strip
+                    if @support_os_list.index(os).nil? then @support_os_list.push(os) end
+                end
+            end
+            @log.info "Get supported os infomation.. OK"
+        else
+            @log.warn "Failed to get supported os infomation"
+        end
+    end
+
+    def download_os_list(from_server, dist = nil)
+        if dist.nil? then dist = get_pkglist_path end
+        file_url = File.join(@server_addr, OS_INFO_FILE)
+        if from_server then
+            if not FileDownLoader.download(file_url, dist, @log) then return false end
+        else
+            if File.exist? file_url then FileUtils.cp(file_url, dist)
+            else return false end
+        end
+
+        return true
+    end
+
+    def read_archive_pkg_list(list_path)
+        local_file_path = File.join(list_path, ARCHIVE_PKG_LIST_FILE)
+        if File.exist? local_file_path then
+            File.open(local_file_path, "r") do |f|
+                f.each_line do |l|
+                    pkg = l.strip
+                    if @archive_pkg_list.index(pkg).nil? then @archive_pkg_list.push(pkg) end
+                end
+            end
+            @log.info "Get archive package infomation.. OK"
+        else
+            @log.warn "Failed to get archive package infomation"
+        end
+    end
+
+    def download_archive_pkg_list(from_server, dist = nil)
+        if dist.nil? then dist = get_pkglist_path end
+        file_url = File.join(@server_addr, @snapshot_path, ARCHIVE_PKG_LIST_FILE)
+        if from_server then
+            if not FileDownLoader.download(file_url, dist, @log) then return false end
+        else
+            if File.exist? file_url then FileUtils.cp(file_url, dist)
+            else return false end
+        end
+
+        return true
+    end
+
+    def download_pkg_list(from_server, dist = nil)
+        if dist.nil? then dist = get_pkglist_path end
+        @support_os_list.each do |os|
+            filename = PKG_LIST_FILE_PREFIX + os
+            file_url = File.join(@server_addr, @snapshot_path, filename)
+            if from_server then
+                if not FileDownLoader.download(file_url, dist, @log) then return false end
+            else
+                if File.exist? file_url then FileUtils.cp(file_url, dist)
+                else return false end
+            end
+        end
+
+        return true
+    end
+
+    private
+    # create installed package hash
+    def read_installed_pkg_list()
+
+        config_path = File.join(@location, PACKAGE_INFO_DIR)
+        if not File.directory? config_path then return end
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then return
+        else
+            file_path = installed_pkg_hash_key
+            if not File.exist? file_path then
+                #raise RuntimeError, "#{file_path} file does not exist"
+                return
+            end
+            begin
+                pkg_hash = Parser.read_repo_pkg_list_from file_path
+            rescue => e
+                @log.error( e.message, Log::LV_USER)
+                return
+            end
+            @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+        end
+    end
+
+    private
+    # check to exist installed package list file
+    def check_installed_pkg_list_file()
+
+        if @location.nil? then raise RuntimeError, "#{@location} path does not exist" end
+        file_path = get_installed_pkg_list_file_path()
+        if File.exist? file_path then return true
+        else return false end
+    end
+
+    private
+    # get installed package list file path
+    def get_installed_pkg_list_file_path()
+
+        file_full_path = File.join(@location, PACKAGE_INFO_DIR, INSTALLED_PKG_LIST_FILE)
+        return file_full_path
+    end
+
+    private
+    # write package hash to file
+    def write_pkg_hash_to_file(pkg_hash)
+
+        file_path = get_installed_pkg_list_file_path()
+        if pkg_hash.nil? then
+            pkg_hash = @installed_pkg_hash_loc[file_path]
+        end
+        if not pkg_hash.nil? then
+            config_path = File.join(@location, PACKAGE_INFO_DIR)
+            if not File.exist? config_path then FileUtils.mkdir_p "#{config_path}" end
+            if File.exist? file_path then File.delete(file_path) end
+            File.open(file_path, "a+") do |file|
+                pkg_list = pkg_hash.values
+                pkg_list.each do |pkg|
+                    pkg.print_to_file(file)
+                    file.puts "\n"
+                end
+            end
+        end
+        @log.info "Write package informations to \"#{file_path}\".. OK"
+    end
+
+    private
+    def check_meta_pkg(pkg_name, os)
+        if not check_remote_pkg(pkg_name, os) then return false end
+
+        attr = get_attr_from_pkg(pkg_name, os, "attribute")
+        if attr.nil? or attr.empty? then return false end
+        if attr[0].strip.upcase.eql? "ROOT" then return true
+        else return false end
+    end
+
+    public
+    def register(address, distribution, pkg_file_path, password)
+        # check file exist
+        if not File.exist? pkg_file_path then
+            puts "The file does not exist!.. #{pkg_file_path}"
+            return false
+        end
+
+        result = Utils.parse_server_addr(address)
+        if result.nil? then
+            puts "Server address is incorrect. (#{address})"
+            puts "Tune as following format."
+            puts " <ip>:<port>"
+            exit 1
+        end
+        bs_ip = result[0]
+        bs_port = result[1]
+
+        pkg_file_path_list = []
+        pkg_file_path_list.push(pkg_file_path)
+        # set distribution
+        @server_addr = distribution
+        ret = upload(bs_ip, bs_port, pkg_file_path_list, nil, nil, nil, nil, password)
+
+        if ret then @log.info "Snapshot is generated : #{ret}" end
+    end
+
+    ##Print change log to console.
+    public
+    def printChangeLog(snapshot1 = nil, snapshot2 = nil)
+        snapshotPath = File.join(@config_dist_path, PackageServerConstants::SNAPSHOT_INFO_FILE_NAME)
+        @log.info("Read information of snapshot from " + snapshotPath);
+
+        ssController = SnapshotController.new(snapshotPath);
+        changeLogController = ChangeLogController.new(@server_addr, ssController)
+
+        if (snapshot1.nil?()) then
+            changeLog = changeLogController.getLatestChangeLog();
+        elsif snapshot2.nil?() then
+            changeLog = changeLogController.getChangeLog(snapshot1);
+        else
+            changeLog = changeLogController.getTotalChangeLog(snapshot1, snapshot2);
+        end
+
+        puts changeLog
+    end
+
+    ##Print snapshot list to console.
+    public
+    def printSnapshotList(showAll=false)
+        snapshotPath = File.join(@config_dist_path, PackageServerConstants::SNAPSHOT_INFO_FILE_NAME)
+        @log.info("Read information of snapshot from " + snapshotPath);
+
+        ssController = SnapshotController.new(snapshotPath);
+        if showAll then
+            result = ssController.getAllSnapshotList;
+        else
+            result = ssController.getManualSnapshotList ;
+        end
+
+        result.each() do |snapshot|
+            puts PackageServerConstants::SNAPSHOT_NAME_FIELD + ": " + snapshot.getName()
+            puts PackageServerConstants::SNAPSHOT_TIME_FIELD + ": " + snapshot.getTime()
+            puts
+        end
+
+    end
 end
index 3b2ccfe..1b46b0b 100644 (file)
@@ -31,248 +31,255 @@ $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
 require "utils"
 
 def set_default( options )
-       if options[:t].nil? then options[:t] = false end
-       if options[:type].nil? then options[:type] = 'all' end
-       if options[:f].nil? then options[:f] = false end
-       if options[:v].nil? then options[:v] = false end
- if options[:all].nil? then options[:all] = false end
+    if options[:t].nil? then options[:t] = false end
+    if options[:type].nil? then options[:type] = 'all' end
+    if options[:f].nil? then options[:f] = false end
+    if options[:v].nil? then options[:v] = false end
+    if options[:all].nil? then options[:all] = false end
+    options[:el] = []
 end
 
 def option_error_check( options )
 
-       case options[:cmd]
-
-       when "clean" then
-
-       when "upgrade" then
-               if options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli upgrade -u <package server url> [-l <location>] [-o <os>] [--trace]"                               
-               end                             
-
-       when "check-upgrade" then
-               if options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli check-upgrade -u <package server url> [-l <location>] [-o <os>]"                           
-               end
-               
-       when "download" then
-               if options[:pkg].nil? or options[:pkg].empty? or
-                               options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli download -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace]"
-               end
-       when "make-img" then
-               if options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli make-img -u <package server url> [-o <os>] [-m <image info>]"
-               end
-       when "dep-graph" then
-               if options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli dep-graph -u <package server url> [-o <os>] [--dep_type <dependency type>]"
-               end
-       when "install" then
-               if options[:pkg].nil? or options[:pkg].empty? or
-                               options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli install -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace] [--force]"
-               end
-
-       when "install-file" then
-               if options[:pkg].nil? or options[:pkg].empty? then
-                       raise ArgumentError, "Usage: pkg-cli install-file -P <package file> [-l <location>] [-u <package server url>] [--trace] [--force]"
-               end
-
-       when "uninstall" then
-               if options[:pkg].nil? or options[:pkg].empty? then
-                       raise ArgumentError, "Usage: pkg-cli uninstall -P <package name> [-l <location>] [--trace]"
-               end
-
-       when "show-rpkg" then
-               if options[:pkg].nil? or options[:pkg].empty? or
-                               options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli show-rpkg -P <package name> -u <package server url> [-o <os>]"
-               end
-
-       when "list-rpkg" then
-               if options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli list-rpkg -u <package server url> [-o <os>]"                       
-               end
-
-       when "show-lpkg" then
-               if options[:pkg].nil? or options[:pkg].empty? then
-                       raise ArgumentError, "Usage: pkg-cli show-lpkg -P <package name> [-l <location>]"
-               end
-
-       when "list-lpkg" then
-
-       when "build-dep" then
-               if options[:pkg].nil? or options[:pkg].empty? or
-                               options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli build-dep -P <package name> -u <package server url> [-o <os>]"
-               end
-
-       when "install-dep" then
-               if options[:pkg].nil? or options[:pkg].empty? or
-                               options[:url].nil? or options[:url].empty? then
-                       raise ArgumentError, "Usage: pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]"
-               end
-
-       when "register"
-               if      options[:pkg].nil? or options[:pkg].empty? or options[:address].nil? or options[:address].empty? or
-                               options[:dist].nil? or options[:dist].empty? then
-                       raise ArgumentError, "Usage: pkg-cli register -P <package file path> -a <server address> -d <distribution name> -w <password>"
-               end
-       when "snapshotlist"
-  if options[:url].nil? or options[:url].empty? then
-    raise ArgumentError, "Usage: pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]"
-  end
-       when "changelog"
-
-       else
-               raise ArgumentError, "Input is incorrect : #{options[:cmd]}"
-       end
+    case options[:cmd]
+
+    when "clean" then
+
+    when "upgrade" then
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli upgrade -u <package server url> [-l <location>] [-o <os>] [--trace]"
+        end
+
+    when "check-upgrade" then
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli check-upgrade -u <package server url> [-l <location>] [-o <os>]"
+        end
+
+    when "download" then
+        if options[:pkg].nil? or options[:pkg].empty? or
+            options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli download -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace]"
+        end
+    when "make-img" then
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli make-img -u <package server url> [-o <os>] [-i <image info>]"
+        end
+    when "dep-graph" then
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli dep-graph -u <package server url> [-o <os>] [--dep_type <dependency type>]"
+        end
+    when "install" then
+        if options[:pkg].nil? or options[:pkg].empty? or
+            options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli install -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace] [--force]"
+        end
+
+    when "install-file" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+            raise ArgumentError, "Usage: pkg-cli install-file -P <package file> [-l <location>] [-u <package server url>] [--trace] [--force]"
+        end
+
+    when "uninstall" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+            raise ArgumentError, "Usage: pkg-cli uninstall -P <package name> [-l <location>] [--trace]"
+        end
+
+    when "show-rpkg" then
+        if options[:pkg].nil? or options[:pkg].empty? or
+            options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli show-rpkg -P <package name> -u <package server url> [-o <os>]"
+        end
+
+    when "list-rpkg" then
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli list-rpkg -u <package server url> [-o <os>]"
+        end
+
+    when "show-lpkg" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+            raise ArgumentError, "Usage: pkg-cli show-lpkg -P <package name> [-l <location>]"
+        end
+
+    when "list-lpkg" then
+
+    when "build-dep" then
+        if options[:pkg].nil? or options[:pkg].empty? or
+            options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli build-dep -P <package name> -u <package server url> [-o <os>]"
+        end
+
+    when "install-dep" then
+        if options[:pkg].nil? or options[:pkg].empty? or
+            options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]"
+        end
+
+    when "register"
+        if     options[:pkg].nil? or options[:pkg].empty? or options[:address].nil? or options[:address].empty? or
+            options[:dist].nil? or options[:dist].empty? then
+            raise ArgumentError, "Usage: pkg-cli register -P <package file path> -a <server address> -d <distribution name> -w <password>"
+        end
+    when "snapshotlist"
+        if options[:url].nil? or options[:url].empty? then
+            raise ArgumentError, "Usage: pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]"
+        end
+    when "changelog"
+
+    else
+        raise ArgumentError, "Input is incorrect : #{options[:cmd]}"
+    end
 end
 
 def option_parse
-       options = {}
-       banner = "Requiest service to package-server and control packages service command-line tool." + "\n" \
-               + "\n" + "Usage: pkg-cli <SUBCOMMAND> [OPTS] or pkg-cli (-h|-v)" + "\n" \
-               + "\n" + "Subcommands:" + "\n" \
-               + "\t" + "clean         Delete the package in your SDK environment." + "\n" \
-               + "\t" + "download      Download the package in your SDK environment." + "\n" \
-               + "\t" + "make-img      Make SDK-Image." + "\n" \
-               + "\t" + "install       Download the package from package-server and install the package in your SDK environment." + "\n" \
-               + "\t" + "install-file  Install the package in your SDK environment." + "\n" \
-               + "\t" + "uninstall     Uninstall the package in your SDK environment." + "\n" \
-               + "\t" + "upgrade       Upgrade your SDK environment." + "\n" \
-               + "\t" + "check-upgrade Check packages to upgrade." + "\n" \
-               + "\t" + "show-rpkg     Show the package in the package-server." + "\n" \
-               + "\t" + "list-rpkg     Show the all packages in the package-server." + "\n" \
-               + "\t" + "show-lpkg     Show the package in your SDK environment." + "\n" \
-               + "\t" + "list-lpkg     Show the all packages in your SDK environment." + "\n" \
-               + "\t" + "snapshotlist  Show the snapshot list in your SDK environment." + "\n" \
-               + "\t" + "changelog     Show the change log in your SDK environment." + "\n" \
-               + "\t" + "build-dep     Show build-dependency packages" + "\n" \
-               + "\t" + "install-dep   Show install-dependency packages" + "\n" \
-               + "\n" + "Subcommand usage:" + "\n" \
-               + "\t" + "pkg-cli clean [-l <location>] [--force]" + "\n" \
-               + "\t" + "pkg-cli download -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace]" + "\n" \
-               + "\t" + "pkg-cli make-img -u <package server url> [-o <os>] [-i <image info>]" + "\n" \
-               + "\t" + "pkg-cli dep-graph -u <package server url> [-o <os>] [--dep_type <dependency type>]" + "\n" \
-               + "\t" + "pkg-cli install -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace] [--force]" + "\n" \
-               + "\t" + "pkg-cli install-file -P <package file> [-l <location>] [-u <package server url>] [--trace] [--force]" + "\n" \
-               + "\t" + "pkg-cli uninstall -P <package name> [-l <location>] [--trace]" + "\n" \
-               + "\t" + "pkg-cli upgrade -u <package server url> [-l <location>] [-o <os>] [--trace]" + "\n" \
-               + "\t" + "pkg-cli check-upgrade -u <package server url> [-l <location>] [-o <os>]" + "\n" \
-               + "\t" + "pkg-cli show-rpkg -P <package name> -u <package server url> [-o <os>]" + "\n"  \
-               + "\t" + "pkg-cli list-rpkg -u <package server url> [-o <os>]" + "\n" \
-               + "\t" + "pkg-cli show-lpkg -P <package name> [-l <location>]" + "\n"  \
-               + "\t" + "pkg-cli list-lpkg [-l <location>]" + "\n" \
-               + "\t" + "pkg-cli snapshotlist -u <package server url> [--all]" + "\n"  \
-               + "\t" + "pkg-cli changelog -u <package server url> [-snapshot <snapshot name,snapshot name>]" + "\n"  \
-               + "\t" + "pkg-cli build-dep -P <package name> -u <package server url> [-o <os>]" + "\n" \
-               + "\t" + "pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]" + "\n" \
-               + "\t" + "pkg-cli register -P <package file path> -a <server address> -d <distribution name> -w <password>" + "\n" \
-               + "\n" + "Options:" + "\n"
-
-       optparse = OptionParser.new(nil, 32, ' '*8) do|opts|
-               # Set a banner, displayed at the top
-               # of the help screen.
-         
-
-               opts.banner = banner
-
-               opts.on( '-P', '--pkg <package name/file>', 'package name or package file name' ) do |name|
-                       options[:pkg] = name
-               end
-
-               opts.on( '-o', '--os <operating system>', 'target operating system: ubuntu-32/ubuntu-64/windows-32/windows-64/macos-64' ) do |os|
-                       options[:os] = os
-               end
-
-               opts.on( '-d', '--dist <distribution name>', 'distribution name' ) do |dist|
-                       options[:dist] = dist 
-               end
-
-               opts.on( '-u', '--url <server url>', 'package server url: http://127.0.0.1/dibs/unstable' ) do |url|
-                       options[:url] = url
-               end
-
-               opts.on( '-l', '--loc <location>', 'install/download location' ) do |loc|
-                       options[:loc] = loc
-               end
-
-               opts.on( '-w', '--passwd <password>', 'password' ) do |passwd|
-                       options[:passwd] = passwd
-               end
-
-               opts.on( '-a', '--address <server address>', 'package server address : 127.0.0.1:2224' ) do |address|
-                       options[:address] = address
-               end
-
-               opts.on( '--trace', 'enable trace dependent packages' ) do
-                       options[:t] = true
-               end
-
-               opts.on( '--force', 'enable force' ) do
-                       options[:f] = true
-               end
-
-               opts.on( '--dep_type <dependency type>', 'all/build/install' ) do |type|
-                       options[:type] = type
-               end
+    options = {}
+    banner = "Requiest service to package-server and control packages service command-line tool." + "\n" \
+        + "\n" + "Usage: pkg-cli <SUBCOMMAND> [OPTS] or pkg-cli (-h|-v)" + "\n" \
+        + "\n" + "Subcommands:" + "\n" \
+        + "\t" + "clean         Delete the package in your SDK environment." + "\n" \
+        + "\t" + "download      Download the package in your SDK environment." + "\n" \
+        + "\t" + "make-img      Make SDK-Image." + "\n" \
+        + "\t" + "install       Download the package from package-server and install the package in your SDK environment." + "\n" \
+        + "\t" + "install-file  Install the package in your SDK environment." + "\n" \
+        + "\t" + "uninstall     Uninstall the package in your SDK environment." + "\n" \
+        + "\t" + "upgrade       Upgrade your SDK environment." + "\n" \
+        + "\t" + "check-upgrade Check packages to upgrade." + "\n" \
+        + "\t" + "show-rpkg     Show the package in the package-server." + "\n" \
+        + "\t" + "list-rpkg     Show the all packages in the package-server." + "\n" \
+        + "\t" + "show-lpkg     Show the package in your SDK environment." + "\n" \
+        + "\t" + "list-lpkg     Show the all packages in your SDK environment." + "\n" \
+        + "\t" + "snapshotlist  Show the snapshot list in your SDK environment." + "\n" \
+        + "\t" + "changelog     Show the change log in your SDK environment." + "\n" \
+        + "\t" + "build-dep    Show build-dependency packages" + "\n" \
+        + "\t" + "install-dep  Show install-dependency packages" + "\n" \
+        + "\n" + "Subcommand usage:" + "\n" \
+        + "\t" + "pkg-cli clean [-l <location>] [--force]" + "\n" \
+        + "\t" + "pkg-cli download -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace]" + "\n" \
+        + "\t" + "pkg-cli make-img -u <package server url> [-o <os>] [-i <image info>] [-x <meta-package list>]" + "\n" \
+        + "\t" + "pkg-cli dep-graph -u <package server url> [-o <os>] [--dep_type <dependency type>]" + "\n" \
+        + "\t" + "pkg-cli install -P <package name> -u <package server url> [-o <os>] [-l <location>] [--trace] [--force]" + "\n" \
+        + "\t" + "pkg-cli install-file -P <package file> [-l <location>] [-u <package server url>] [--trace] [--force]" + "\n" \
+        + "\t" + "pkg-cli uninstall -P <package name> [-l <location>] [--trace]" + "\n" \
+        + "\t" + "pkg-cli upgrade -u <package server url> [-l <location>] [-o <os>] [--trace]" + "\n" \
+        + "\t" + "pkg-cli check-upgrade -u <package server url> [-l <location>] [-o <os>]" + "\n" \
+        + "\t" + "pkg-cli show-rpkg -P <package name> -u <package server url> [-o <os>]" + "\n"  \
+        + "\t" + "pkg-cli list-rpkg -u <package server url> [-o <os>]" + "\n" \
+        + "\t" + "pkg-cli show-lpkg -P <package name> [-l <location>]" + "\n"  \
+        + "\t" + "pkg-cli list-lpkg [-l <location>]" + "\n" \
+        + "\t" + "pkg-cli snapshotlist -u <package server url> [--all]" + "\n"  \
+        + "\t" + "pkg-cli changelog -u <package server url> [-snapshot <snapshot name,snapshot name>]" + "\n"  \
+        + "\t" + "pkg-cli build-dep -P <package name> -u <package server url> [-o <os>]" + "\n" \
+        + "\t" + "pkg-cli install-dep -P <package name> -u <package server url> [-o <os>]" + "\n" \
+        + "\t" + "pkg-cli register -P <package file path> -a <server address> -d <distribution name> -w <password>" + "\n" \
+        + "\n" + "Options:" + "\n"
+
+    optparse = OptionParser.new(nil, 32, ' '*8) do|opts|
+        # Set a banner, displayed at the top
+        # of the help screen.
+
+        opts.banner = banner
+
+        opts.on( '-P', '--pkg <package name/file>', 'package name or package file name' ) do |name|
+            options[:pkg] = name
+        end
+
+        opts.on( '-o', '--os <operating system>', 'target operating system: ubuntu-32/ubuntu-64/windows-32/windows-64/macos-64' ) do |os|
+            options[:os] = os
+        end
+
+        opts.on( '-d', '--dist <distribution name>', 'distribution name' ) do |dist|
+            options[:dist] = dist
+        end
+
+        opts.on( '-u', '--url <server url>', 'package server url: http://127.0.0.1/dibs/unstable' ) do |url|
+            options[:url] = url
+        end
+
+        opts.on( '-l', '--loc <location>', 'install/download location' ) do |loc|
+            options[:loc] = loc
+        end
+
+        opts.on( '-w', '--passwd <password>', 'password' ) do |passwd|
+            options[:passwd] = passwd
+        end
+
+        opts.on( '-a', '--address <server address>', 'package server address : 127.0.0.1:2224' ) do |address|
+            options[:address] = address
+        end
+
+        opts.on( '--trace', 'enable trace dependent packages' ) do
+            options[:t] = true
+        end
+
+        opts.on( '--force', 'enable force' ) do
+            options[:f] = true
+        end
+
+        opts.on( '--dep_type <dependency type>', 'all/build/install' ) do |type|
+            options[:type] = type
+        end
 
         opts.on( '-i', '--info <image info>', 'sdk image information : http://download.tizen.org/sdk/packages/official' ) do |image_info|
-                       options[:info] = image_info
-               end
-
-               opts.on( '-h', '--help', 'display help' ) do
-                       puts opts
-                       exit
-               end
-
-               opts.on( '-v', '--version', 'display version' ) do
-                       puts "DIBS(Distributed Intelligent Build System) version " + Utils.get_version()
-                       exit
-               end
-               
-               opts.on('--all', 'show all information') do
-                 options[:all] = true
-               end
-               
-               opts.on('-s', '--snapshot snapshotName1,snapshotName2', Array, 'snapshot name') do |snapshotName|
-                 puts snapshotName[0], snapshotName[1]
-                 options[:snapshot] = snapshotName
-               end
-
-       end
-
-       cmd = ARGV[0]
-       if  cmd.eql? "download" or cmd.eql? "make-img" or
-               cmd.eql? "install" or cmd.eql? "show-rpkg" or
-               cmd.eql? "list-rpkg" or
-               cmd.eql? "uninstall" or cmd.eql? "show-lpkg" or
-               cmd.eql? "list-lpkg" or cmd.eql? "dep-graph" or
-               cmd.eql? "install-file" or cmd.eql? "clean" or
-               cmd.eql? "upgrade" or cmd.eql? "check-upgrade" or
-               cmd.eql? "build-dep" or cmd.eql? "install-dep" or
-               cmd.eql? "register" or
-               cmd.eql?("changelog") or
-               cmd.eql?("snapshotlist") or
-               cmd =~ /(-v)|(--version)/  or
-               cmd =~ /(help)|(-h)|(--help)/  then
-
-               if cmd.eql? "help" then
-                       V[0] = "-h"
-               end
-               options[:cmd] = ARGV[0]
-       else
-               raise ArgumentError, "Usage: pkg-cli <SUBCOMMAND> [OPTS] or pkg-cli -h"
-       end
-
-       optparse.parse!
-
-       set_default options
-
-       # option error check
-       option_error_check options
-
-       return options
+            options[:info] = image_info
+        end
+
+        opts.on( '-x', '--exception <meta-package list>', 'meta-package list : MOBILE-3.0,IVI-1.0' ) do |mpackage|
+            if not Utils.multi_argument_test( mpackage, "," ) then
+                raise ArgumentError, "meta-package variable parsing error : #{mpackage}"
+            end
+            options[:el] = mpackage.split(",")
+        end
+
+        opts.on( '-h', '--help', 'display help' ) do
+            puts opts
+            exit
+        end
+
+        opts.on( '-v', '--version', 'display version' ) do
+            puts "DIBS(Distributed Intelligent Build System) version " + Utils.get_version()
+            exit
+        end
+
+        opts.on('--all', 'show all information') do
+            options[:all] = true
+        end
+
+        opts.on('-s', '--snapshot snapshotName1,snapshotName2', Array, 'snapshot name') do |snapshotName|
+            puts snapshotName[0], snapshotName[1]
+            options[:snapshot] = snapshotName
+        end
+
+    end
+
+    cmd = ARGV[0]
+    if  cmd.eql? "download" or cmd.eql? "make-img" or
+        cmd.eql? "install" or cmd.eql? "show-rpkg" or
+        cmd.eql? "list-rpkg" or
+        cmd.eql? "uninstall" or cmd.eql? "show-lpkg" or
+        cmd.eql? "list-lpkg" or cmd.eql? "dep-graph" or
+        cmd.eql? "install-file" or cmd.eql? "clean" or
+        cmd.eql? "upgrade" or cmd.eql? "check-upgrade" or
+        cmd.eql? "build-dep" or cmd.eql? "install-dep" or
+        cmd.eql? "register" or
+        cmd.eql?("changelog") or
+        cmd.eql?("snapshotlist") or
+        cmd =~ /(-v)|(--version)/  or
+        cmd =~ /(help)|(-h)|(--help)/  then
+
+        if cmd.eql? "help" then
+            V[0] = "-h"
+        end
+        options[:cmd] = ARGV[0]
+    else
+        raise ArgumentError, "Usage: pkg-cli <SUBCOMMAND> [OPTS] or pkg-cli -h"
+    end
+
+    set_default options
+
+    optparse.parse!
+
+    # option error check
+    option_error_check options
+
+    return options
 end