5 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
8 Taejun Ha <taejun.ha@samsung.com>
9 Jiil Hyoun <jiil.hyoun@samsung.com>
10 Donghyuk Yang <donghyuk.yang@samsung.com>
11 DongHee Yang <donghee.yang@samsung.com>
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
17 http://www.apache.org/licenses/LICENSE-2.0
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
29 $LOAD_PATH.unshift File.dirname(__FILE__)
30 $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
31 require "packageServerConfig"
34 if Utils.is_windows_like_os( Utils::HOST_OS ) then
41 CONFIG_PATH = "#{PackageServerConfig::CONFIG_ROOT}/client"
42 PACKAGE_INFO_DIR = ".info"
43 PACKAGE_MANIFEST = "pkginfo.manifest"
45 def FileInstaller.install(package_name, package_file_path, type, target_path, logger)
47 if not File.exist? package_file_path then
48 logger.error "\"#{package_file_path}\" file does not exist."
53 # install script when binary package
55 uniq_name = Utils.create_uniq_name
56 path = Utils::HOME + "/tmp/#{uniq_name}"
57 # windows has limitation for file path length
58 if Utils.is_windows_like_os( Utils::HOST_OS ) then
59 drive = Utils::HOME.split("/")[0]
60 path = "#{drive}/#{uniq_name}"
62 if not File.exist? path then FileUtils.mkdir_p "#{path}" end
64 if File.directory? path then
65 log = "## create temporary dir : #{path}\n"
67 logger.error "Failed to create temporary dir"
68 logger.info " [path: #{path}]"
73 logger.info "Installing \"#{package_name}\" package.."
74 logger.info " [file: #{package_file_path}]"
76 log = log + "## Extract file : #{package_file_path}\n"
77 result = extract_file(package_name, package_file_path, path, target_path, logger)
78 if result == "" or result.nil? then
79 write_log(target_path, package_name, log)
81 else log = log + result end
83 log = log + "## Move files : \"#{path}\" to \"#{target_path}\"\n"
84 result = move_dir(package_name, path, target_path, logger)
86 write_log(target_path, package_name, log)
88 else log = log + result end
90 log = log + "## Execute install script\n"
91 result = execute_install_script(package_name, path, target_path, logger)
93 write_log(target_path, package_name, log)
95 else log = log + result end
97 log = log + "## Move remove script\n"
98 result = move_remove_script(package_name, path, target_path, logger)
100 write_log(target_path, package_name, log)
102 else log = log + result end
104 log = log + "## Remove temporary dir : #{path} #####\n"
105 result = Utils.execute_shell_return("rm -rf #{path}")
107 logger.warn "Failed to remove temporary path"
108 logger.info " [path: #{path}]"
111 logger.error "FileInstaller: Interrupted.."
112 Utils.execute_shell("rm -rf #{path}")
113 logger.info "Removed #{path}"
116 write_log(target_path, package_name, log)
118 target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
119 if not File.exist? target_config_path then FileUtils.mkdir_p(target_config_path) end
120 pkg_inst_log = "#{package_name}_inst.log"
121 pkg_inst_log_path = File.join(target_config_path, pkg_inst_log)
123 File.open(pkg_inst_log_path, "a+") do |f|
131 logger.info "Installed \"#{package_name}\" package.. OK"
132 logger.info " [path: #{target_path}]"
136 def FileInstaller.write_log(target_path, package_name, log)
137 target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
138 if not File.exist? target_config_path then FileUtils.mkdir_p(target_config_path) end
139 pkg_inst_log = "#{package_name}_inst.log"
140 pkg_inst_log_path = File.join(target_config_path, pkg_inst_log)
142 File.open(pkg_inst_log_path, "a+") do |f|
147 def FileInstaller.move_remove_script(package_name, path, target_path, logger)
148 target_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
149 if not File.exist? target_path then FileUtils.mkdir_p(target_path) end
150 script_file_prefix = "#{path}/remove.*"
151 script_file = Dir.glob(script_file_prefix)[0]
154 if not script_file.nil? then
155 result = Utils.execute_shell_return("mv #{script_file} #{target_path}")
157 logger.error "Failed to move a remove script"
158 logger.info " [file: #{script_file}]"
159 logger.info " [from: #{path}]"
160 logger.info " [to: #{target_path}]"
162 else log = result.join("") end
163 logger.info "Moved remove script file.. OK"
164 log = log + "[file: #{script_file}]\n"
165 log = log + "[from: #{path}]\n"
166 log = log + "[to: #{target_path}]\n"
173 # Does not verify that the script execution is successful.
174 # Register shortcut should be failed.
175 def FileInstaller.execute_install_script(package_name, path, target_path, logger)
176 script_file_prefix = "#{path}/install.*"
177 script_file = Dir.glob(script_file_prefix)[0]
180 if not script_file.nil? then
181 logger.info "Execute \"#{script_file}\" file"
182 if Utils.is_windows_like_os( Utils::HOST_OS ) then
183 cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
185 cmd = "INSTALLED_PATH=\"#{target_path}\" #{script_file}"
187 logger.info " [cmd: #{cmd}]"
189 logger.info "Executed install script file.. OK"
190 log = log + "[file: #{script_file}]\n"
191 log = log + "[cmd: #{cmd}]\n"
197 # Does not verify that the script execution is successful.
198 # Removing shortcut should be failed.
199 def FileInstaller.execute_remove_script(package_name, target_path, logger)
200 info_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
201 if not File.directory? info_path then
202 logger.error "\"#{info_path}\" does not exist."
206 script_file_prefix = "#{info_path}/remove.*"
207 script_file = Dir.glob(script_file_prefix)[0]
210 if not script_file.nil? then
211 logger.info "Execute \"#{script_file}\" file"
212 if Utils.is_windows_like_os( Utils::HOST_OS ) then
213 cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
215 cmd = "INSTALLED_PATH=\"#{target_path}\" #{script_file}"
217 logger.info " [cmd: #{cmd}]"
219 logger.info "Executed remote script file.. OK"
220 log = log + "[file: #{script_file}]\n"
221 log = log + "[cmd: #{cmd}]\n"
227 def FileInstaller.remove_pkg_files(package_name, target_path, logger)
228 list_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
230 if not File.directory? list_path then
231 logger.error "\"#{list_path}\" does not exist."
235 list_file_name = "#{list_path}/#{package_name}.list"
236 list_file = Dir.glob(list_file_name)[0]
239 if not list_file.nil? then
240 File.open(list_file, "r") do |file|
241 file.each_line do |f|
243 if f.nil? or f.empty? then next end
244 file_path = File.join(target_path, f)
245 if File.directory? file_path then
246 if File.symlink? file_path then
247 File.unlink file_path
250 entries = Dir.entries(file_path)
251 if entries.include? "." then entries.delete(".") end
252 if entries.include? ".." then entries.delete("..") end
253 if entries.empty? or entries.nil? then
256 rescue SystemCallError
257 logger.warn "\"#{file_path}\" directory is not empty"
259 else directories.push(file_path) end
260 elsif File.file? file_path then FileUtils.rm_f(file_path)
261 elsif File.symlink? file_path then File.unlink file_path
262 # if files are already removed by remove script,
263 else logger.warn "\"#{file_path}\" does not exist" end
267 directories.reverse.each do |path|
268 if not File.directory? path then next end
269 entries = Dir.entries(path)
270 if entries.include? "." then entries.delete(".") end
271 if entries.include? ".." then entries.delete("..") end
272 if entries.empty? or entries.nil? then
275 rescue SystemCallError
276 logger.warn "\"#{file_path}\" directory is not empty"
281 Utils.execute_shell("rm -rf #{list_path}")
285 def FileInstaller.uninstall(package_name, type, target_path, logger)
288 result = execute_remove_script(package_name, target_path, logger)
289 if result.nil? then return false end
290 if not remove_pkg_files(package_name, target_path, logger) then return false end
297 def FileInstaller.move_dir(package_name, source_path, target_path, logger)
298 config_path = File.join(target_path, PACKAGE_INFO_DIR, package_name)
299 pkginfo_path = File.join(source_path, PACKAGE_MANIFEST)
300 data_path = File.join(source_path, "data")
303 if not File.exist? pkginfo_path then
304 logger.error "#{PACKAGE_MANIFEST} file does not exist. Check #{source_path}"
306 else FileUtils.cp pkginfo_path, config_path end
308 if File.exist? data_path then
309 # if os is linux, use cpio. it is faster than cp
310 if Utils.is_linux_like_os( Utils::HOST_OS ) then
311 absolute_path = `readlink -f #{target_path}`
312 result = Utils.execute_shell_return("cd #{data_path}; find . -depth | cpio -pldm #{absolute_path}")
314 result = Utils.execute_shell_return("cp -r #{data_path}/* #{target_path}")
317 logger.error "Failed to move files"
318 logger.info " [from: #{source_path}]"
319 logger.info " [to: #{target_path}]"
322 logger.info "Moved files.. OK"
323 log = log + "[from: #{source_path}]\n"
324 log = log + "[to: #{target_path}]\n"
325 else logger.warn "\"data\" directory does not exist." end
330 def FileInstaller.extract_file(package_name, package_file_path, path, target_path, logger)
331 dirname = File.dirname(package_file_path)
332 filename = File.basename(package_file_path)
333 ext = File.extname(filename)
335 target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
336 if not File.exist? target_config_path then FileUtils.mkdir_p(target_config_path) end
337 pkg_file_list = "#{package_name}.list"
338 pkg_file_list_path = File.join(target_config_path, pkg_file_list)
339 temp_pkg_file_list = "temp_file_list"
340 temp_pkg_file_list_path = File.join(target_config_path, "temp_file_list")
342 show_file_list_command = nil
343 extrach_file_list_command = nil
348 show_file_list_command = "zip -sf #{package_file_path}"
349 extract_file_list_command = "unzip -o \"#{package_file_path}\" -d \"#{path}\""
351 # path should be unix path if it is used in tar command
352 _package_file_path = Utils.get_unix_path(package_file_path)
353 _path = Utils.get_unix_path(path)
354 show_file_list_command = "tar -tf #{_package_file_path}"
355 extract_file_list_command = "tar xf \"#{_package_file_path}\" -C \"#{_path}\""
357 logger.error "\"#{filename}\" is not supported."
361 system "#{show_file_list_command} > #{temp_pkg_file_list_path}"
362 File.open(pkg_file_list_path, "a+") do |targetfile|
363 File.open(temp_pkg_file_list_path, "r") do |sourcefile|
364 sourcefile.each_line do |l|
365 if l.strip.start_with? "data/" then
372 File.delete(temp_pkg_file_list_path)
376 if Utils.is_windows_like_os( Utils::HOST_OS ) then
377 log = unzip_file(package_file_path, path)
379 #result = Utils.execute_shell_return(extract_file_list_command)
380 #if result.nil? then log = nil
381 #else log = result.join("") end
382 log = `#{extract_file_list_command}`
385 #result = Utils.execute_shell_return(extract_file_list_command)
386 #if result.nil? then log = nil
387 #else log = result.join("") end
388 log = `#{extract_file_list_command}`
391 if log == "" then log = nil end
393 logger.error "Failed to extract \"#{filename}\" file"
394 logger.info " [file: #{package_file_path}]"
395 logger.info " [from: #{path}]"
396 logger.info " [to: #{target_path}]"
397 logger.info " [cmd: #{extract_file_list_command}]"
401 logger.info "Extracted \"#{filename}\" file.. OK"
402 log = log + "[file: #{package_file_path}]\n"
403 log = log + "[from: #{path}]\n"
404 log = log + "[to: #{target_path}]\n"
405 log = log + "[cmd: #{extract_file_list_command}]\n"
409 def FileInstaller.extract_a_file(package_file_path, target_file, path, logger)
410 dirname = File.dirname(package_file_path)
411 filename = File.basename(package_file_path)
412 ext = File.extname(filename)
416 if not path.nil? then
417 extract_file_command = "unzip -x #{package_file_path} #{target_file} -d #{path}"
419 extract_file_command = "unzip -x #{package_file_path} #{target_file}"
422 # path should be unix path if it is used in tar command
423 _package_file_path = Utils.get_unix_path(package_file_path)
424 _path = Utils.get_unix_path(path)
425 if not path.nil? then
426 extract_file_command = "tar xf #{_package_file_path} -C #{_path} #{target_file}"
428 extract_file_command = "tar xf #{_package_file_path} #{target_file}"
432 system "#{extract_file_command}"
434 if not path.nil? then
435 target_file_path = File.join(path, target_file)
437 target_file_path = target_file
440 if File.exist? target_file_path then
441 logger.info "Extracted \"#{target_file}\" file.."
444 logger.warn "Failed to extracted \"#{target_file}\" file.."
445 logger.info " [file: #{package_file_path}]"
446 logger.info " [path: #{path}]"
447 logger.info " [cmd: #{extract_file_command}]"
452 def FileInstaller.unzip_file(zipfile, dest)
454 Zip::ZipFile.open(zipfile) do |zip_file|
456 f_path = File.join(dest, f.name)
457 FileUtils.mkdir_p(File.dirname(f_path))
458 if File.exist?(f_path) then
459 log = log + "[Warn] Exist file : #{f_path}\n" unless f_path.end_with? "/"
461 zip_file.extract(f, f_path)
462 if not f_path.end_with? "/" then
463 log = log + "[info] Extracted file : #{f_path}\n"
471 def FileInstaller.unzip_a_file(zipfile, file, dest)
472 Zip::ZipFile.open(zipfile) do |zip_file|
474 if f.name.strip == file then
475 f_path = File.join(dest, f.name)
476 FileUtils.mkdir_p(File.dirname(f_path))
477 zip_file.extract(f, f_path) unless File.exist?(f_path)