Subversion Repositories configs

Rev

Rev 203 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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