Subversion Repositories configs

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
175 - 1
"""
2
Copyright 2007-2019 VMware, Inc.  All rights reserved. -- VMware Confidential
3
 
4
VMware Installer
5
"""
6
from vmis import PRODUCT_NAME, PRODUCT_SUFFIX
7
 
8
DEST = LIBDIR/'vmware-installer/3.0.0'
9
CLEANUP = CONFDIR/'.cleanup'
10
 
11
# The 1.0 Installer looks in very specific locations for existing installs
12
# (/etc/vmware and /etc/vmware-vix)
13
OLDCONFDIR = Destination('/etc/vmware')
14
OLDBOOTSTRAPS = ['/etc/vmware', '/etc/vmware-vix']
15
 
16
installerLinks = ['vmware-installer', 'vmware-uninstall',
17
                  'vmware-uninstall-vix']
18
 
19
class VMwareInstaller(Installer):
20
 
21
   def InitializeQuestions(self, old, new, upgrade):
22
      # Only ask questions if they are not already set.  Otherwise we
23
      # can potentially end up changing paths from their old values to
24
      # their new values before {Pre,Post}Uninstall runs which assumes
25
      # its old value.
26
      #
27
      # Perhaps in the future we can ask these questions
28
      # per-transaction and use the new values for new installs but
29
      # not upgrades?  This is tricky though because a new dependent
30
      # could have been introduced which assumes being installed
31
      # alongside other components but would end up getting new paths.
32
      def _addQuestion(questionType, key, text, default):
33
         defaultAnswer = self.GetAnswer(key)
34
         if not defaultAnswer:
35
            defaultAnswer = default
36
         self.AddQuestion(questionType, key=key, text=text, default=defaultAnswer,
37
                          required=True, mustExist=False, level='CUSTOM')
38
 
39
      _addQuestion('Directory', key='prefix',
40
                   text='Product installation path prefix. '\
41
                   '(Desktop integration files, such as icons and .desktop entries, '\
42
                   'will still be installed under /usr.)', default=PREFIX)
43
 
44
      # XXX: Using non-default sysconfdir is not supported now. Comment out.
45
      #_addQuestion('Directory', key='sysconfdir', text='System configuration files.',
46
      #             default=SYSCONFDIR)
47
 
48
      # These have different defaults.
49
      if self.GetAnswer('initdir') is None:
50
         self.AddQuestion('InitDir', key='initdir', text='System service runlevel directory (contains rc?.d directories).  Use an empty directory if your system does not support rc?.d style directories.',
51
                          level='CUSTOM')
52
 
53
      if self.GetAnswer('initscriptdir') is None:
54
         self.AddQuestion('InitScriptDir', key='initscriptdir', text='System service scripts directory (commonly /etc/init.d).',
55
                          level='CUSTOM')
56
 
57
      self.AddQuestion('YesNo', key='installShortcuts', required=True,
58
                       text='Do you want to install shortcuts for your desktop?',
59
                       level='CUSTOM', default='yes')
60
 
61
   def PreTransactionUninstall(self, old, new, upgrade):
62
      keepConfig = ENV.get('VMWARE_KEEP_CONFIG')
63
      keepConfigStored = self.GetConfig('keepConfigOnUninstall')
64
      askQuestion = True
65
      if keepConfig:
66
         if keepConfig == 'no':
67
            self.SetConfig('keepConfigOnUninstall', 'no')
68
            askQuestion = False
69
         else:
70
            self.SetConfig('keepConfigOnUninstall', 'yes')
71
            askQuestion = False
72
 
73
      # Set a sane default if this has never been answered
74
      if not keepConfigStored:
75
         keepConfigStored = 'yes'
76
 
77
      # If the environment variable was set, there's no need to ask.  This also supports
78
      # silent uninstallation.
79
      if askQuestion:
80
         currentVersion = self.GetConfig('currentVersion')
81
         if currentVersion and \
82
            Version(currentVersion) == Version('3.0.0') and \
83
            not upgrade:
84
            # If this is the last installer, it's being uninstalled,
85
            # and we are not upgrading, then query the user if they
86
            # would like to keep their configuration files.
87
            self.AddQuestion('YesNo',
88
                             key='keepConfigOnUninstall',
89
                             text='All configuration information is about to be removed. ' \
90
                                  'Do you wish to keep your configuration files? You can ' \
91
                                  'also input \'quit\' or \'q\' to cancel uninstallation.',
92
                             required=False,
93
                             default=keepConfigStored,
94
                             level='REGULAR',
95
                             secondaryText='Uninstall')
96
 
97
   def InitializeInstall(self, old, new, upgrade):
98
      bin = DEST/''
99
      bin.perm = BINARY
100
 
101
      self.AddTarget('File', 'vmis*', DEST)
102
      self.AddTarget('File', 'vmware/*', DEST/'vmware')
103
      self.AddTarget('File', 'vmware-installer*.py', DEST)
104
      self.AddTarget('File', 'init.sh', DEST/'init.sh')
105
      # We need to create extra bootstrap files for the 1.0 Installer with BINDIR set
106
      # correctly since the 1.0 .bundle installer needs it in order to hook into our
107
      # downgrade script.   Otherwise it will just install and stomp all over portions
108
      # of our files.
109
      self.AddTarget('File', 'vmware-installer', bin/'vmware-installer')
110
      self.AddTarget('File', 'vmware-uninstall-downgrade', bin/'vmware-uninstall-downgrade')
111
 
112
      self.AddTarget('File', 'lib/*', DEST/'lib')
113
      self.AddTarget('File', 'sopython/*', DEST/'sopython')
114
      self.AddTarget('File', 'bin/*', DEST/'bin')
115
 
116
      # Python
117
      self.AddTarget('File', 'python/*', DEST/'python')
118
      self.SetPermission(DEST/'python/python', BINARY)
119
      self.SetPermission(DEST/'python/libpython.so', BINARY)
120
      self.SetPermission(DEST/'vmis-launcher', BINARY)
121
      self.SetPermission(DEST/'sopython/*', BINARY)
122
 
123
      # cdsHelper
124
      self.AddTarget('File', 'cdsHelper/*', DEST/'cdsHelper')
125
      self.AddTarget('File', 'vmware-cds-helper', DEST/'vmware-cds-helper')
126
      self.SetPermission(DEST/'vmware-cds-helper', BINARY)
127
 
128
      self.SetPermission(DEST/'bin/*', BINARY)
129
 
130
   def PostInstall(self, old, new, upgrade):
131
      bin = DEST/''
132
 
133
      # Store installer information in the database
134
      self.SetConfig('%s.vmisloc' % '3.0.0', DEST)
135
      self.SetConfig('%s.pyloc'   % '3.0.0', DEST/'python')
136
      self.SetConfig('%s.pyver'   % '3.0.0', PYTHON_VERSION)
137
 
138
      # Set up installer specific files.  These are shared between installers, so
139
      # must be laid down carefully. We only want to set up files if there is
140
      # either no existing installer or we are the latest and greatest.
141
      systemVersion = self.GetConfig('currentVersion')
142
      if systemVersion is None or Version(systemVersion) <= Version(new):
143
         # Set ourselves as the current version of the installer to use
144
         self.SetConfig('currentVersion', '3.0.0')
145
 
146
         # Remove existing symlink to pave the way for the new one.
147
         try:
148
            (BINDIR/'vmware-installer').remove()
149
         except OSError:
150
            # We don't care if it already doesn't exist.
151
            pass
152
         # Create installer hooks.  symlink expects a string and can't convert
153
         # a ComponentDestination object.  Convert them manually.
154
         try:
155
            BINDIR.makedirs()
156
         except OSError:
157
            # It's okay if it already exists.
158
            pass
159
         path(bin/'vmware-installer').symlink(str(BINDIR/'vmware-installer'))
160
 
161
         # Create necessary bootstrap files
162
         self._WriteInstallerBootstrapFile(installerPresent=True)
163
 
164
         # The 1.0 installer looks for bootstrap in these locations
165
         # with a BINDIR in them.  We need to create them if they
166
         # don't already exist
167
         for bstrap in OLDBOOTSTRAPS:
168
            bootstrap = path(bstrap)/'bootstrap'
169
            if not bootstrap.exists():
170
               try:
171
                  path(bstrap).makedirs()
172
               except OSError:
173
                  pass
174
               bootstrap.write_text('BINDIR="%s"\n\n' % BINDIR, append=False)
175
 
176
      for i in DEST.walkfiles('*.py'):
177
         compiled = self.CompilePythonFile(i)
178
         self.RegisterFile(compiled)
179
 
180
 
181
   def _WriteInstallerBootstrapFile(self, installerPresent=True):
182
      # To mitigate a bug in the older installers, which would attempt to run
183
      # the (now uninstalled, and thus missing), newer installer and crash, we need
184
      # to re-write the bootstrap file so that VERSION="0.1", which will always
185
      # force an older installer to use itself rather than trying to chain the the
186
      # "newer", non-existant installer
187
      if installerPresent:
188
         legacyVersionStamp = '3.0.0'
189
      else:
190
         legacyVersionStamp = '0.1'
191
 
192
      bootstrap = CONFDIR/'bootstrap'
193
      bootstrap.write_text('VMWARE_INSTALLER="%s"\n\n' % DEST, append=False)
194
      bootstrap.write_text('VERSION="%s" # For backwards compatibility\n' % legacyVersionStamp, append=True)
195
      bootstrap.write_text('VMISVERSION="%s"\n' % '3.0.0', append=True)
196
      bootstrap.write_text('VMISBUILDNUM="%s"\n' % '15018445', append=True)
197
      bootstrap.write_text('VMISPYVERSION="%s"\n' % PYTHON_VERSION, append=True)
198
 
199
 
200
   def PostTransactionInstall(self, old, new, upgrade):
201
      # The .cleanup file is originally created when loading the
202
      # database when the database doesn't already exist.  Now that
203
      # the transaction for vmware-installer has been committed we can
204
      # remove this file as the installer framework has been
205
      # installed and configured.
206
      # However, if the database already existed, this file will not be
207
      # created and the remove would fail.  No need to remove it, hence
208
      # the try/except.
209
      try:
210
         CLEANUP.remove()
211
      except OSError:
212
         log.Debug('%s did not exist.' % CLEANUP)
213
 
214
   def PreUninstall(self, old, new, upgrade):
215
      # Remove vmware-installer keys
216
      self.DelConfig('%s.vmisloc' % '3.0.0')
217
      self.DelConfig('%s.pyloc'   % '3.0.0')
218
      self.DelConfig('%s.pyver'   % '3.0.0')
219
 
220
   def PostUninstall(self, old, new, upgrade):
221
      currentVersion = self.GetConfig('currentVersion')
222
      keepConfig = self.GetConfig('keepConfigOnUninstall')
223
      # currentVersion should not be able to be None under normal install and
224
      # uninstall, but in a rollback scenario it can happen.
225
      if currentVersion and Version(currentVersion) == Version('3.0.0'):
226
         if keepConfig != 'yes':
227
            # If we are the newest installer, it means we're the last to go.
228
            # Clean up after ourselves.
229
 
230
            # Remove bootstrap files and set database .cleanup file
231
            bstraps = OLDBOOTSTRAPS + [CONFDIR]
232
            # Check if the old VIX or Player/WS is installed.  If so,
233
            # don't clean up the bootstrap files.
234
            for suffix in ['', '-vix']:
235
               oldfile = path('/etc/vmware%s/bootstrap' % suffix)
236
               if oldfile.exists():
237
                  text = oldfile.text()
238
                  if text.find('VERSION="1.0"') != -1:
239
                     bstraps.remove('/etc/vmware%s' % suffix)
240
 
241
            # Now cleanup our bootstraps
242
            if not upgrade:
243
               for bstrap in bstraps:
244
                  try:
245
                     bootstrapDir = path(bstrap)
246
                     bootstrap = bootstrapDir/'bootstrap'
247
                     bootstrap.unlink(ignore_errors=True)
248
                     bootstrapDir.rmdir()
249
                  except OSError as e:
250
                     log.Info('Problem removing bootstrap file %s: %s' % (bootstrap, e))
251
               # Signal cleanup of database.  This is done in PreUninstall
252
            # because if the uninstall only partially completes the
253
            # installer is in an inconsistent state and may not be able to
254
            # remove itself.
255
            CLEANUP.touch()
256
 
257
            # Remove installer symlink
258
            try:
259
               (BINDIR/'vmware-installer').remove()
260
            except OSError:
261
               # We don't care if it already doesn't exist.
262
               pass
263
 
264
            # Clear our config key
265
            self.DelConfig('currentVersion')
266
 
267
            # XXX: SYSCONFDIR/'config' - This file is used by VIX, Player, and
268
            # WS, so should only be uninstalled when one of those is the last to
269
            # go.  For now, it's going to go here, so it's removed from the system
270
            # when everything else goes.  A better solution should be found that
271
            # involves the VIX, Player, and WS component files.  It doesn't belong
272
            # in this one.
273
            # Only do this if we are not upgrading.
274
            if not upgrade:
275
               # If we are on an ESX system, we do *NOT* want to remove /etc/vmware/config
276
               # since ESX needs it!
277
               if not path('/proc/vmware/version').exists():
278
                  try:
279
                     (SYSCONFDIR/'vmware/config').remove()
280
                  except OSError as e:
281
                     log.Info('Error removing file: %s.' % (SYSCONFDIR/'vmware/config'))
282
                     log.Info(e)
283
                  # And finally, remove SYSCONFDIR/vmware
284
                  try:
285
                     (SYSCONFDIR/'vmware').rmdir()
286
                  except OSError as e:
287
                     log.Info('Error removing directory: %s.' % (SYSCONFDIR/'vmware'))
288
                     log.Info(e)
289
         else:
290
            # The user chose to keep their configuration, but we still need to remove the
291
            # currentVersion key since there is no current version of the installer installed
292
            # anymore
293
            self.DelConfig('currentVersion')
294
 
295
            # Re-write the bootstrap file
296
            self._WriteInstallerBootstrapFile(installerPresent=False)