|
1 #!perl |
|
2 # Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 # |
|
17 |
|
18 use strict; |
|
19 use FindBin; |
|
20 use lib "$FindBin::Bin"; |
|
21 use Getopt::Long; |
|
22 use IniData; |
|
23 use EnvDb; |
|
24 use CommandController; |
|
25 use CleanEnv; |
|
26 use GetEnv; |
|
27 |
|
28 |
|
29 # |
|
30 # Constants. |
|
31 # |
|
32 |
|
33 my $KMissingFileName = "__missing.txt"; |
|
34 my $KCompsFileName = "__comps.txt"; |
|
35 |
|
36 |
|
37 # |
|
38 # Globals. |
|
39 # |
|
40 |
|
41 my $verbose = 0; |
|
42 my $reallyClean = 0; |
|
43 my $force = 0; |
|
44 my $snapShotFileName; |
|
45 my $iniData = IniData->New(); |
|
46 my $commandController = CommandController->New($iniData, 'InstallSnapShot'); |
|
47 |
|
48 |
|
49 # |
|
50 # Main. |
|
51 # |
|
52 |
|
53 ProcessCommandLine(); |
|
54 InstallSnapShot(); |
|
55 |
|
56 |
|
57 # |
|
58 # Subs. |
|
59 # |
|
60 |
|
61 sub ProcessCommandLine { |
|
62 Getopt::Long::Configure ('bundling'); |
|
63 my $help; |
|
64 GetOptions('h' => \$help, 'r' => \$reallyClean, 'f' => \$force, 'v+' => \$verbose); |
|
65 |
|
66 if ($help) { |
|
67 Usage(0); |
|
68 } |
|
69 |
|
70 $snapShotFileName = shift @ARGV; |
|
71 defined $snapShotFileName or die Usage(1); |
|
72 unless ($snapShotFileName =~ /\.zip$/i) { |
|
73 $snapShotFileName .= '.zip'; |
|
74 } |
|
75 |
|
76 unless ($snapShotFileName and scalar(@ARGV) == 0) { |
|
77 print "Error: Invalid number of arguments\n"; |
|
78 Usage(1); |
|
79 } |
|
80 } |
|
81 |
|
82 sub Usage { |
|
83 my $exitCode = shift; |
|
84 |
|
85 Utils::PrintDeathMessage($exitCode, "\nUsage: installsnapshot [options] <snap_shot_file_name> |
|
86 |
|
87 options: |
|
88 |
|
89 -h help |
|
90 -r really clean |
|
91 -f force (don't prompt) |
|
92 -v verbose output (-vv very verbose)\n"); |
|
93 } |
|
94 |
|
95 sub InstallSnapShot { |
|
96 my $newEnv = ReadSnapShotEnv(); |
|
97 CheckEnvAvailable($newEnv); |
|
98 unless (CleanEnv::CleanEnv($iniData, $reallyClean, $force, $verbose)) { |
|
99 die "\nAborting because environment was not cleaned...\n"; |
|
100 } |
|
101 print "Installing snapshot environment...\n"; |
|
102 GetEnv::GetEnv($iniData, $newEnv, 0, undef, 0, 0, $verbose, undef, 0); |
|
103 print "Unpacking \"$snapShotFileName\"...\n"; |
|
104 Utils::Unzip($snapShotFileName, Utils::EpocRoot(), $verbose, 1); |
|
105 my $problems = 0; |
|
106 unlink (Utils::PrependEpocRoot($KMissingFileName)) or (++$problems and print "Warning: Couldn't delete \"$KMissingFileName\": $!\n"); |
|
107 unlink (Utils::PrependEpocRoot($KCompsFileName)) or (++$problems and print "Warning: Couldn't delete \"$KMissingFileName\": $!\n"); |
|
108 my $missingFiles = ReadSnapShotMissingFiles(); |
|
109 foreach my $thisMissingFile (@$missingFiles) { |
|
110 print "Removing \"$thisMissingFile\"...\n"; |
|
111 unlink $thisMissingFile or (++$problems and print "Warning: Couldn't delete \"$thisMissingFile\": $!\n"); |
|
112 } |
|
113 if ($problems) { |
|
114 print "There were problems installing this snapshot\n"; |
|
115 } |
|
116 else { |
|
117 print "Snapshot \"$snapShotFileName\" successfully installed\n"; |
|
118 } |
|
119 } |
|
120 |
|
121 sub CheckEnvAvailable { |
|
122 my $env = shift; |
|
123 print "Checking that all the component releases referred to by snap shot \"$snapShotFileName\" are available...\n" if ($verbose); |
|
124 my $pathData = $iniData->PathData(); |
|
125 my $errors = 0; |
|
126 foreach my $thisComp (sort keys %$env) { |
|
127 unless ($pathData->ReleaseExists($thisComp, $env->{$thisComp})) { |
|
128 print "Error: $thisComp $env->{$thisComp} is referred to by snap shot \"$snapShotFileName\" but does not exist\n"; |
|
129 $errors = 1; |
|
130 } |
|
131 } |
|
132 if ($errors) { |
|
133 die "Aborting (environment not altered)...\n"; |
|
134 } |
|
135 } |
|
136 |
|
137 sub ReadSnapShotEnv { |
|
138 print "Reading snap shot environment details from \"$KCompsFileName\" within \"$snapShotFileName\"...\n" if ($verbose); |
|
139 Utils::InitialiseTempDir($iniData); |
|
140 my %env; |
|
141 eval { |
|
142 Utils::UnzipSingleFile($snapShotFileName, $KCompsFileName, Utils::TempDir(), $verbose); |
|
143 my $file = Utils::ConcatenateDirNames(Utils::TempDir(), $KCompsFileName); |
|
144 open (COMPS, $file) or die "Couldn't open \"$file\": $!\n"; |
|
145 while (my $line = <COMPS>) { |
|
146 (my $comp, my $ver) = $line =~ /^(\S+)\s+(\S+)$/; |
|
147 unless ($comp and $ver) { |
|
148 die "Invalid line in \"$file\"\n"; |
|
149 } |
|
150 $env{$comp} = $ver; |
|
151 } |
|
152 close (COMPS); |
|
153 }; |
|
154 Utils::RemoveTempDir(); |
|
155 if ($@) { |
|
156 die "Error: Problem reading environment from snap shot \"$snapShotFileName\": $@"; |
|
157 } |
|
158 return \%env; |
|
159 } |
|
160 |
|
161 sub ReadSnapShotMissingFiles { |
|
162 print "Reading list of files missing from snap shot environment from \"$KMissingFileName\" within \"$snapShotFileName\"...\n" if ($verbose); |
|
163 Utils::InitialiseTempDir($iniData); |
|
164 my @missingFiles; |
|
165 eval { |
|
166 Utils::UnzipSingleFile($snapShotFileName, $KMissingFileName, Utils::TempDir(), $verbose); |
|
167 my $file = Utils::ConcatenateDirNames(Utils::TempDir(), $KMissingFileName); |
|
168 open (MISSING, $file) or die "Couldn't open \"$file\": $!\n"; |
|
169 while (my $line = <MISSING>) { |
|
170 chomp $line; |
|
171 $line = Utils::PrependEpocRoot($line); |
|
172 push (@missingFiles, $line); |
|
173 } |
|
174 close (MISSING); |
|
175 }; |
|
176 Utils::RemoveTempDir(); |
|
177 if ($@) { |
|
178 die "Error: Problem reading missing files from snap shot \"$snapShotFileName\": $@"; |
|
179 } |
|
180 return \@missingFiles; |
|
181 } |
|
182 |
|
183 __END__ |
|
184 |
|
185 =head1 NAME |
|
186 |
|
187 InstallSnapShot - Installs a snap shot created with MakeSnapShot. |
|
188 |
|
189 =head1 SYNOPSIS |
|
190 |
|
191 installsnapshot [options] <snap_shot_file_name> |
|
192 |
|
193 options: |
|
194 |
|
195 -h help |
|
196 -r really clean |
|
197 -f force (don't prompt) |
|
198 -v verbose output (-vv very verbose) |
|
199 |
|
200 =head1 DESCRIPTION |
|
201 |
|
202 The release tools exist to make it relatively straight forward to share binary files in a controlled way. In order to acheive a suitable level of control, a fair amount of rigor is imposed on users when they are making releases. There are times when this is inappropriate. For example, if a user wants to temporarily capture the current state of their environment. The commands C<MakeSnapShot> and C<InstallSnapShot> exist to make it easy to accurately capture the current state of an environment, and subsequently revert to it, without the overhead of doing a full environment release. Snap shots should only be used in preference to full environment releases when there is a B<temporary> need to capture an environment, because: |
|
203 |
|
204 =over 4 |
|
205 |
|
206 =item 1 |
|
207 |
|
208 No mechansims are provided for exporting or importing snap shots. |
|
209 |
|
210 =item 2 |
|
211 |
|
212 No release notes are provided with snap shots. |
|
213 |
|
214 =item 3 |
|
215 |
|
216 The contents of snap shots are inherently dirty - they consist of all the files that could not be accounted for with proper releases. Reliance on snap shots as a means of distributing software would therefore eventually become a self defeating activity since the snap shot files would get larger and larger over time. |
|
217 |
|
218 =back |
|
219 |
|
220 C<InstallSnapShot> uses a snap shot zip file generated by C<MakeSnapShot> to set the current environment state to that which the specified snap shot was made from. The following steps are performed: |
|
221 |
|
222 =over 4 |
|
223 |
|
224 =item 1 |
|
225 |
|
226 The environment is cleaned. If the C<-r> option is specified, files that are normally ignored (e.g. the contents of F<\epoc32\build>) are also removed. If the C<-f> option is specified, the cleaning process is carried out without warning the user before deleting files and reinstalling components. |
|
227 |
|
228 =item 2 |
|
229 |
|
230 Component releases are installed, removed or upgraded in such a way as to set the current environment to that which was present when the snap shot was made. |
|
231 |
|
232 =item 3 |
|
233 |
|
234 The contents of the snap shot zip file is installed, overwriting exisitng files, thereby restoring the snap shot, but at the same time making the environment dirty. |
|
235 |
|
236 =item 4 |
|
237 |
|
238 Any files that were missing from the snap shot environment are removed from the current environment. |
|
239 |
|
240 =back |
|
241 |
|
242 C<MakeSnapShot> generates a zip file that contains all the dirty files currently present in the environment. It makes no attempt to understand which component own which files. It also creates some metadata that list the component versions currently installed. This can subsequently be used by C<InstallSnapShot> to revert to the snap shot state. |
|
243 |
|
244 =head1 STATUS |
|
245 |
|
246 Supported. If you find a problem, please report it to us. |
|
247 |
|
248 =head1 KNOWN BUGS |
|
249 |
|
250 None. |
|
251 |
|
252 =head1 COPYRIGHT |
|
253 |
|
254 Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
255 All rights reserved. |
|
256 This component and the accompanying materials are made available |
|
257 under the terms of the License "Eclipse Public License v1.0" |
|
258 which accompanies this distribution, and is available |
|
259 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
260 |
|
261 Initial Contributors: |
|
262 Nokia Corporation - initial contribution. |
|
263 |
|
264 Contributors: |
|
265 |
|
266 Description: |
|
267 |
|
268 |
|
269 =cut |