Initialize
[sdk/tools/sdk-build.git] / src / pkg_server / installer.rb
1 =begin
2  
3  installer.rb 
4
5 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6
7 Contact:
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>
12
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
16
17 http://www.apache.org/licenses/LICENSE-2.0
18
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.
24
25 Contributors:
26 - S-Core Co., Ltd
27 =end
28
29 $LOAD_PATH.unshift File.dirname(__FILE__)
30 $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
31 require "serverConfig"
32 require "log"
33 require "utils"
34
35 class FileInstaller
36
37     CONFIG_PATH = "#{$build_tools}/client"
38     PACKAGE_INFO_DIR = ".info"
39
40     @@log = nil
41
42     def FileInstaller.set_logger(logger)
43         @@log = logger
44     end
45
46     def FileInstaller.install(package_name, package_file_path, type, target_path)
47
48         if not File.exist? package_file_path then
49             @@log.error "\"#{package_file_path}\" file does not exist."
50             return false
51         end
52
53         case type
54         # install script when binary package
55         when "binary" then
56             uniq_name = Utils.create_uniq_name
57             path = Utils::HOME + "/tmp/#{uniq_name}"
58             if Utils::HOST_OS.eql? "windows" then
59                 drive = Utils::HOME.split("/")[0]
60                 path = "#{drive}/#{uniq_name}"
61             end
62             FileUtils.mkdir_p "#{path}"
63
64             if File.directory? path then
65                log = "##### create temporary dir : #{path} #####\n"
66             else
67                log = "##### [Failed] create temporary dir : #{path} #####\n"
68                return false 
69             end
70
71             log = log + "##### extract file : #{package_file_path} #####\n"
72             log = log + extract_file(package_name, package_file_path, path, target_path)
73             move_dir(package_name, path, target_path)
74
75             log = log + "##### execute install script #####\n"
76             log = log + execute_install_script(package_name, path, target_path)
77
78             log = log + "##### move remove script #####\n"
79             move_remove_script(package_name, path, target_path)
80
81             log = log + "##### remove temporary dir : #{path} #####\n"
82             Utils.execute_shell("rm -rf #{path}")
83
84             target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
85             FileUtils.mkdir_p(target_config_path)
86             pkg_inst_log = "#{package_name}_inst.log"
87             pkg_inst_log_path = File.join(target_config_path, pkg_inst_log)
88
89             File.open(pkg_inst_log_path, "a+") do |f|
90                 f.puts log
91             end
92
93         when "source" then
94         end
95
96         # need verify
97         return true;
98     end
99
100     def FileInstaller.move_remove_script(package_name, path, target_path)
101         target_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
102         FileUtils.mkdir_p(target_path)
103         script_file_prefix = "#{path}/remove.*"
104         script_file = Dir.glob(script_file_prefix)[0]
105
106         if not script_file.nil? then
107             FileUtils.mv(script_file, target_path)
108         end
109     end 
110
111
112     def FileInstaller.execute_install_script(package_name, path, target_path)
113         script_file_prefix = "#{path}/install.*"
114         script_file = Dir.glob(script_file_prefix)[0]
115         log = ""
116         
117         if not script_file.nil? then
118             @@log.info "Execute \"#{script_file}\" file"
119             cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
120             log = `#{cmd}`
121         end
122         return log
123     end
124
125     def FileInstaller.execute_remove_script(package_name, target_path)
126         info_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
127         if not File.directory? info_path then
128             return false
129         end
130
131         script_file_prefix = "#{info_path}/remove.*"
132         script_file = Dir.glob(script_file_prefix)[0]
133         log = ""
134
135         if not script_file.nil? then
136             @@log.info "Execute \"#{script_file}\" file"
137             cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
138             log = `#{cmd}`
139         end
140     end
141
142     def FileInstaller.remove_pkg_files(package_name, target_path)
143         list_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
144
145         if not File.directory? list_path then
146             return false
147         end
148
149         list_file_name = "#{list_path}/#{package_name}.list"
150         list_file = Dir.glob(list_file_name)[0]
151         directories = []
152
153         if not list_file.nil? then
154             File.open(list_file, "r") do |file|
155                 file.each_line do |f|
156                     f = f.strip
157                     if f.nil? or f.empty? then next end
158                     file_path = File.join(target_path, f)
159                     if File.directory? file_path then
160                         if File.symlink? file_path then 
161                             File.unlink file_path
162                             next
163                         end
164                         entries = Dir.entries(file_path)
165                         if entries.include? "." then entries.delete(".") end
166                         if entries.include? ".." then entries.delete("..") end
167                         if entries.empty? or entries.nil? then
168                             begin
169                                 Dir.rmdir(file_path)
170                             rescue SystemCallError
171                                 @@log.warn "\"#{file_path}\" directory is not empty"
172                             end 
173                         else directories.push(file_path) end
174                     elsif File.file? file_path then FileUtils.rm_f(file_path)
175                     elsif File.symlink? file_path then File.unlink file_path 
176                     # if files are already removed by remove script,
177                     else @@log.warn "\"#{file_path}\" does not exist" end
178                 end
179             end
180
181             directories.reverse.each do |path|
182                 entries = Dir.entries(path)
183                 if entries.include? "." then entries.delete(".") end
184                 if entries.include? ".." then entries.delete("..") end
185                 if entries.empty? or entries.nil? then
186                 begin
187                     Dir.rmdir(path)
188                 rescue SystemCallError
189                     @@log.warn "\"#{file_path}\" directory is not empty"
190                 end 
191                 else next end
192            end
193         end
194         #FileUtils.rm_rf(list_path)
195         Utils.execute_shell("rm -rf #{list_path}")
196         return true
197     end
198
199     def FileInstaller.uninstall(package_name, type, target_path)
200         case type
201         when "binary" then
202             execute_remove_script(package_name, target_path)
203             remove_pkg_files(package_name, target_path)
204         when "source" then
205         end
206
207         return true
208     end
209
210     def FileInstaller.move_dir(package_name, source_path, target_path)
211         config_path = File.join(target_path, PACKAGE_INFO_DIR, package_name)
212         FileUtils.cp_r Dir.glob("#{source_path}/data/*"), target_path
213         FileUtils.cp "#{source_path}/pkginfo.manifest", config_path
214     end
215
216     def FileInstaller.extract_file(package_name, package_file_path, path, target_path)
217         dirname = File.dirname(package_file_path)
218         filename = File.basename(package_file_path)
219         ext = File.extname(filename)
220
221         target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
222         FileUtils.mkdir_p(target_config_path)
223         pkg_file_list = "#{package_name}.list"
224         pkg_file_list_path = File.join(target_config_path, pkg_file_list)
225         temp_pkg_file_list = "temp_file_list"
226         temp_pkg_file_list_path = File.join(target_config_path, "temp_file_list")
227
228         show_file_list_command = nil
229         extrach_file_list_command = nil
230
231         case ext
232         when ".zip" then
233             show_file_list_command = "zip -sf #{package_file_path}"
234             extract_file_list_command = "unzip \"#{package_file_path}\" -d \"#{path}\""
235         when ".tar" then
236             show_file_list_command = "tar -sf #{package_file_path}"
237             extract_file_list_command = "tar xf \"#{package_file_path}\" -C \"#{path}\""
238         else
239             @@log.error "\"#{filename}\" is not supported."
240             return nil 
241         end
242
243         system "#{show_file_list_command} > #{temp_pkg_file_list_path}"
244         File.open(pkg_file_list_path, "a+") do |targetfile|
245             File.open(temp_pkg_file_list_path, "r") do |sourcefile|
246                 sourcefile.each_line do |l|
247                     if l.strip.start_with? "data/" then
248                         ml = l.strip[5..-1]
249                         targetfile.puts ml
250                     else next end
251                 end
252             end
253         end
254
255         File.delete(temp_pkg_file_list_path)
256         log = `#{extract_file_list_command}`
257         @@log.info "Extracted \"#{filename}\" file.."
258         if log.nil? then log = "" end
259         return log
260     end
261
262     def FileInstaller.extract_specified_file(package_file_path, target_file, path)
263         dirname = File.dirname(package_file_path)
264         filename = File.basename(package_file_path)
265         ext = File.extname(filename)
266         
267         case ext
268         when ".zip" then
269             if not path.nil? then
270                 extract_file_command = "unzip -x #{package_file_path} #{target_file} -d #{path}"
271             else
272                 extract_file_command = "unzip -x #{package_file_path} #{target_file}"
273             end
274         when ".tar" then
275             if not path.nil? then
276                 path = File.join(path, package_file_path)
277                 extract_file_command = "tar xvf #{package_file_path} #{target_file}"
278             else
279                 extract_file_command = "tar xvf #{package_file_path} #{target_file}"
280             end
281         end
282
283         system "#{extract_file_command}"
284         
285         if not path.nil? then
286             target_file_path = File.join(path, target_file)
287         else
288             target_file_path = target_file
289         end
290
291         if File.exist? target_file_path then
292             @@log.info "Extracted \"#{target_file}\" file.."
293             return true
294         else
295             @@log.info "Failed to extracted \"#{target_file}\" file.."
296             return false
297         end
298     end
299 end
300