-
-
Save nmcspadden/32585b218400b4f8c61c87a8fc4365c8 to your computer and use it in GitHub Desktop.
Postinstall for Tableau Desktop 9.3.0.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
"""License Tableau.""" | |
import os | |
import sys | |
import re | |
import subprocess | |
import pwd | |
import FoundationPlist | |
def run_subp(command, input=None): | |
""" | |
Run a subprocess. | |
Command must be an array of strings, allows optional input. | |
Returns results in a dictionary. | |
""" | |
# Validate that command is not a string | |
if isinstance(command, basestring): | |
# Not an array! | |
raise TypeError('Command must be an array') | |
proc = subprocess.Popen(command, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.STDOUT) | |
(out, err) = proc.communicate(input) | |
result_dict = { | |
"stdout": out, | |
"stderr": err, | |
"status": proc.returncode, | |
"success": True if proc.returncode == 0 else False | |
} | |
return result_dict | |
def getconsoleuser(): | |
'''Uses Apple's SystemConfiguration framework to get the current | |
console user''' | |
from SystemConfiguration import SCDynamicStoreCopyConsoleUser | |
cfuser = SCDynamicStoreCopyConsoleUser(None, None, None) | |
return cfuser[0] | |
tableau_dir = '/Applications/Tableau9.3/Tableau.app/Contents' | |
tableau_binary = "%s/MacOS/Tableau" % tableau_dir | |
cust_binary = "%s/Frameworks/FlexNet/custactutil" % tableau_dir | |
current_license = 'XXXX-XXXX-XXXX-XXXX-XXXX' | |
# Add in the registration data | |
registration = dict() | |
# Get the system serial number. For simplicity, this is abstracted out. | |
# This could be easily done by using subprocess to run: | |
# `system_profiler SPHardwareDataType` | |
# and searching for 'Serial Number' | |
serial = get_serial() | |
username = getconsoleuser() | |
# For simplicity, these values are hardcoded. | |
# You will need to have some way of looking up this information | |
# from your own directory source. | |
registration['Data.email'] = "email@domain.com" | |
registration['Data.first_name'] = "Nick" | |
registration['Data.last_name'] = "McSpadden" | |
registration['Data.company'] = 'Facebook:%s:%s' % (serial, username) | |
registration['Data.city'] = "Menlo Park" | |
registration['Data.country'] = "US" | |
registration['Data.department'] = "Engineering/Development" | |
registration['Data.industry'] = "Software & Technology" | |
registration['Data.phone'] = "650-555-1234" | |
registration['Data.state'] = "CA" | |
registration['Data.title'] = "Engineer" | |
registration['Data.zip'] = "94025" | |
# For simplicity, assume home directory in /Users | |
home_dir = os.path.join('/Users', username) | |
FoundationPlist.writePlist( | |
registration, | |
'%s/Library/Preferences/com.tableau.Registration.plist' % home_dir | |
) | |
os.chmod( | |
'%s/Library/Preferences/com.tableau.Registration.plist' % home_dir, | |
0644 | |
) | |
os.chown( | |
'%s/Library/Preferences/com.tableau.Registration.plist' % home_dir, | |
pwd.getpwnam(username).pw_uid, | |
-1 | |
) | |
info_plist = os.path.join(tableau_dir, 'Info.plist') | |
version = FoundationPlist.readPlist(info_plist)['CFBundleShortVersionString'] | |
# Install the licensing agent | |
# install_pkg() is a convenience function to call subprocess with | |
# /usr/sbin/installer | |
# Not provided in this post. | |
install_pkg( | |
"\"%s/Installers/Tableau\ FLEXNet.pkg\"" % tableau_dir, untrusted=True | |
) | |
# Execute the binary to get current licenses (if any) | |
cust_output = run_subp([cust_binary, '-view'])['stdout'] | |
if current_license in cust_output: | |
print "Already licensed, exiting." | |
print ( | |
'Tableau-Success', | |
( | |
'Machine is already licensed. Cusactutil Stdout:%s (Username: %s, ' | |
'Serial: %s, Version: %s)' % (cust_output, username, serial, version) | |
) | |
) | |
sys.exit(0) | |
# Activate Tableau and log failures | |
apply_license_cmd = [tableau_binary, '-activate', current_license] | |
shell_out = run_subp(apply_license_cmd) | |
if not shell_out['success']: | |
print >> sys.stderr, ( | |
'Tableau-Fail', | |
( | |
'Applying license failed with error code: %s (Username: %s, Serial: %s, ' | |
'Version: %s)' % (shell_out['status'], username, serial, version) | |
) | |
) | |
else: | |
# Check for fulfillment id and log results | |
cusactutil_stdout = run_subp([cust_binary, '-view'])['stdout'] | |
fulfillment_id = re.search( | |
'Fulfillment ID: (FID[a-z0-9_]*)', | |
cusactutil_stdout | |
) | |
if fulfillment_id: | |
print ( | |
'Tableau-Success', | |
( | |
'License activated and fulfillment id applied. %s (Username: %s, ' | |
'Serial: %s, Version: %s)' % ( | |
fulfillment_id.group(0), username, serial, version | |
) | |
) | |
) | |
else: | |
print >> sys.stderr, ( | |
'Tableau-Fail', | |
( | |
'License activated but no fulfillment id. Cusactutil Stdout: %s ' | |
'(Username: %s, Serial: %s, Version: %s)' % ( | |
cusactutil_stdout, username, serial, version | |
) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment