Subversion Repositories configs

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
209 - 1
"""
2
Copyright 2008-2020 VMware, Inc.  All rights reserved. -- VMware Confidential
3
 
4
VMware Workstation component installer.
5
"""
6
DEST = LIBDIR/'vmware'
7
conf = DEST/'setup/vmware-config'
8
LICENSETOOL=BINDIR/'vmware-license-enter.sh'
9
 
10
PRODUCT = 'VMware Workstation'
11
LICENSEVERSION = '16.0'
12
 
13
LIMITSFILE = Destination('/etc/security/limits.conf')
14
NOFILE_MINIMUM = 4096
15
PAMLOGINFILE = Destination('/etc/pam.d/login')
16
 
17
vmwareSentinel = '# Automatically generated by the VMware Installer - DO NOT REMOVE\n'
18
pamLoginLine = 'session    required   pam_limits.so\n'
19
 
20
class Workstation(Installer):
21
   def PreTransactionInstall(self, old, new, upgrade):
22
      # Include update module
23
      globals()['update'] = self.LoadInclude('update')
24
 
25
   def PreTransactionUninstall(self, old, new, upgrade):
26
      # Include update module
27
      globals()['update'] = self.LoadInclude('update')
28
 
29
   def InitializeQuestions(self, old, new, upgrade):
30
 
31
      self.AddQuestion('TextEntry',
32
                       key='serialNumber',
33
                       text='',
34
                       header='Enter license key.',
35
                       footer='(optional) You can enter this information later.',
36
                       default='',
37
                       required=True,
38
                       level='REGULAR',
39
                       deferrable=True)
40
 
41
      # NOFILE hardlimit
42
      nofileHL = self.GetAnswer('nofileHardLimit')
43
      if nofileHL:
44
         qlevel = 'CUSTOM'
45
      else:
46
         qlevel = 'REGULAR'
47
      try:
48
         self.hardLimit = self.RunCommand('/bin/sh', '-c', 'ulimit -H -n').stdout
49
         self.hardLimit = self.hardLimit.strip()
50
         self.hardLimit = int(self.hardLimit)
51
         if self.hardLimit < NOFILE_MINIMUM:
52
            log.Debug('Hard limit is %d, adding question.', self.hardLimit)
53
            self.AddQuestion('NumericEntry',
54
                             key='nofileHardLimit',
55
                             text='Insufficient file descriptors can cause virtual machines to '
56
                                  'crash when using snapshots.  The installer has detected that '
57
                                  'your hard limit for open files is %d, which is lower than VMware '
58
                                  'Workstation may require.  Please enter a new limit.' % self.hardLimit,
59
                             min=1024,
60
                             max=65536,
61
                             required=False, default=NOFILE_MINIMUM, level=qlevel)
62
      except ValueError:
63
         # Log this, but move on.  Not a fatal error.
64
         log.Error('Hard limit returned non-integer value: %s', self.hardLimit)
65
 
66
   def InitializeInstall(self, old, new, upgrade):
67
      self.AddTarget('File', 'bin/*', BINDIR)
68
      self.AddTarget('File', 'man/*', MANDIR)
69
 
70
      self.AddTarget('File', 'share/icons/*', DATADIR/'icons')
71
 
72
      if self.GetConfig('installShortcuts', component='vmware-installer') != 'no':
73
         self.AddTarget('File', 'share/applications/*', DATADIR/'applications')
74
         self.AddTarget('File', 'share/appdata/*', DATADIR/'appdata')
75
 
76
      self.AddTarget('File', 'lib/*', DEST)
77
      self.AddTarget('File', 'doc/*', DOCDIR/'vmware-workstation')
78
      self.AddTarget('File', 'etc/*', SYSCONFDIR)
79
 
80
      # Symlink all binaries to appLoader.
81
      for i in ('vmware', 'vmware-tray'):
82
        self.AddTarget('Link', DEST/'bin/appLoader', DEST/'bin'/i)
83
 
84
      self.SetPermission(DEST/'bin/*', BINARY)
85
 
86
      # Ubuntu 10.04 requires additional .desktop files in /usr/local/share/applications
87
      # If GNOME or Ubuntu is going this way, rather than just add these links for
88
      # Ubuntu 10.04, always add them for future-proofing.
89
 
90
      # Some linux distributions use yet another standard for DE metadata, requiring
91
      # .appdata.xml files in order for WS to be usable via the DE app launcher.
92
      # Like the .desktop files, just install them along with the rest for futureproofing.
93
      if self.GetConfig('installShortcuts', component='vmware-installer') != 'no':
94
         self.AddTarget('Link', DATADIR/'applications/vmware-workstation.desktop',
95
                        PREFIX/'local/share/applications/vmware-workstation.desktop')
96
         self.AddTarget('Link', DATADIR/'appdata/vmware-workstation.appdata.xml',
97
                        PREFIX/'local/share/appdata/vmware-workstation.appdata.xml')
98
 
99
 
100
   def PreUninstall(self, old, new, upgrade):
101
      self.RunCommand(conf, '-d', 'product.version')
102
      self.RunCommand(conf, '-d', 'workstation.product.version')
103
      self.RunCommand(conf, '-d', 'vix.config.version')
104
 
105
      # Stop our init script for uninstallation
106
      script = INITSCRIPTDIR/'vmware'
107
      if INITSCRIPTDIR and script.exists():
108
         self.RunCommand(script, 'stop', ignoreErrors=True)
109
 
110
 
111
   def PostInstall(self, old, new, upgrade):
112
      # Used by VIX to locate correct provider.
113
      self.RunCommand(conf, '-s', 'product.version', self.GetManifestValue('version'))
114
      self.RunCommand(conf, '-s', 'workstation.product.version', self.GetManifestValue('version'))
115
      self.RunCommand(conf, '-s', 'product.name', PRODUCT)
116
      self.RunCommand(conf, '-s', 'vix.config.version', 1)
117
 
118
      if self.GetAnswer('eula.deferred', component='vmware-workstation') == 'yes':
119
         self.RunCommand(conf, '-s', 'acceptEULA', 'none')
120
         self.DelConfig('eula.deferred')
121
      else:
122
         self.RunCommand(conf, '-s', 'acceptEULA', 'yes')
123
 
124
      if self.GetConfig('installShortcuts', component='vmware-installer') != 'no':
125
         launcher = DATADIR/'applications/vmware-workstation.desktop'
126
         binary = BINDIR/'vmware'
127
         self.RunCommand('sed', '-e', 's,@@BINARY@@,%s,g' % binary, '-i', launcher)
128
 
129
      update.UpdateIconCache(self, DATADIR)
130
      update.UpdateMIME(self, DATADIR)
131
 
132
      # Update hard limit for the number of open files.
133
      self._ModifyVMwareLimitsConf(LIMITSFILE)
134
 
135
      # We killed all running vmware processes before installing,
136
      # so be sure to restart them.
137
      script = INITSCRIPTDIR/'vmware'
138
      if INITSCRIPTDIR and script.exists():
139
         self.RunCommand(script, 'stop', ignoreErrors=True)
140
         self.RunCommand(script, 'start')
141
 
142
      # serial entered by user:
143
      serialNumber = self.GetAnswer('serialNumber')
144
      if serialNumber:
145
          self.RunCommand(LICENSETOOL, serialNumber, PRODUCT, LICENSEVERSION)
146
 
147
   def PostUninstall(self, old, new, upgrade):
148
      # Reset hard limit for the number of open files on the system.
149
      self._ClearVMwareLimitsConf(LIMITSFILE, restoreEntry=True)
150
 
151
       # Empty out the Winger cache
152
      try:
153
         path('/var/lib/vmware/compcache').rmtree()
154
      except OSError:
155
         pass # Okay if the directory was already removed by the user
156
 
157
      # This seems a little counterintuitive, but we killed all running
158
      # vmware processes before uninstalling Workstation.  At this point
159
      # Player is still installed though, so we want to be
160
      # sure to restart the services for Player.
161
      script = INITSCRIPTDIR/'vmware'
162
      if INITSCRIPTDIR and script.exists():
163
         self.RunCommand(script, 'stop', ignoreErrors=True)
164
         self.RunCommand(script, 'start')
165
 
166
   def _ClearVMwareLimitsConf(self, limitsFile, restoreEntry=False):
167
      # Check if our section already exists at the beginning
168
      # of the file.  If it does clear it.
169
      log.Debug('nofile: Clearing limits file')
170
      text = limitsFile.text()
171
      newtext = re.sub(vmwareSentinel + '.*\n' + vmwareSentinel,
172
                       '', text, re.DOTALL)
173
      limitsFile.write_text(newtext)
174
 
175
      # If we're uninstalling and restoring the old file, add the
176
      # old limit back since we wiped it on install.
177
      if restoreEntry:
178
         oldLimit = self.GetConfig('oldNofileHardLimit')
179
         if oldLimit:
180
            log.Debug('nofile: Restoring old nofile hard limit.')
181
            self._WriteLimitsConfEntry(limitsFile, '*\t\thard\tnofile\t\t%s\n' % oldLimit)
182
            # And remove the entry from our config file.
183
            self.DelConfig('oldNofileHardLimit')
184
 
185
      self._ClearPamD(PAMLOGINFILE)
186
 
187
   def _RemoveMarkedLineFromFile(self, file_, entry):
188
      """ Remove a line wrapped in vmwareSentinel from a given file """
189
      text = file_.text()
190
      searchText = vmwareSentinel + entry + vmwareSentinel
191
      matches = re.findall(searchText, text, re.DOTALL)
192
      if not matches:
193
         return False
194
      newtext = re.sub(searchText, '', text, re.DOTALL)
195
      file_.write_text(newtext)
196
      return True
197
 
198
   def _WriteLimitsConfEntry(self, limitsFile, entry):
199
      # This function assumes that the file has already been cleared and prepped for
200
      # us to write an entry.
201
      text = limitsFile.text()
202
 
203
      # See if a limits line already exists for nofile
204
      # Remove comments.
205
      justText = re.sub('#.*\n', '', text)
206
 
207
      matches = re.findall('^\*.+hard.+nofile.+\d+', justText, re.MULTILINE)
208
      # If there is a match, we need to remove this line.
209
      if matches:
210
         # Store the old value.  We'll need to replace it later.
211
         self.SetConfig('oldNofileHardLimit', self.hardLimit)
212
         log.Debug('Removing existing hard nofile line.')
213
         text = re.sub('\*.+hard.+nofile.+\d+.*\n', '', text, re.MULTILINE)
214
      # Some systems have an '# End of file' marker.  Remove it and
215
      # set a flag to replace it if it's found.
216
      setFileEnd = False
217
      newText = re.sub('# End of file.*', '', text)
218
      if newText != text:
219
         setFileEnd = True
220
         text = newText
221
      # Now add in our line.
222
      text = text + entry
223
      if setFileEnd:
224
         text = text + '# End of file.'
225
      limitsFile.write_text(text)
226
 
227
   def _ClearPamD(self, pamFile):
228
      if pamFile.exists():
229
         self._RemoveMarkedLineFromFile(pamFile, pamLoginLine)
230
 
231
   def _WritePamD(self, pamFile):
232
      if pamFile.exists():
233
         text = pamFile.text()
234
 
235
         # Search for the entry we want:
236
         matches = re.findall('session\s+required\s+pam_limits.so', text)
237
 
238
         # If no matches were found, we need to add the entry.
239
         if not matches:
240
            newStr = text + vmwareSentinel + \
241
                     pamLoginLine + \
242
                     vmwareSentinel
243
            pamFile.write_text(newStr)
244
 
245
   def _ModifyVMwareLimitsConf(self, limitsFile):
246
      # Modify the limits.conf file to include the lines:
247
      # *            hard    nofile  ####
248
      # The validator ensures that the answer was an integer, so no need
249
      # to check.
250
      nofileHL = self.GetAnswer('nofileHardLimit')
251
      if nofileHL and (self.hardLimit != int(nofileHL)):
252
         limitsFile = Destination('/etc/security/limits.conf')
253
         if limitsFile.exists():
254
            self._ClearVMwareLimitsConf(limitsFile, restoreEntry=False)
255
            log.Debug('Modifying /etc/security/limits.conf hard limit from '
256
                      '%d to %d.', self.hardLimit, nofileHL)
257
            self._WriteLimitsConfEntry(limitsFile, vmwareSentinel + \
258
                                       '*\t\thard\tnofile\t\t%s\n' % nofileHL + \
259
                                       vmwareSentinel)
260
         self._WritePamD(PAMLOGINFILE)