#!/usr/bin/python import os import subprocess import urllib import urllib2 import tempfile import json import shutil from time import localtime import stat # No trailing slash on this one SAL_URL = "https://sal.yourcompany.com" PUBLIC_KEY = "yourpublickeyhere" PRIVATE_KEY = "yourreallyreallyreallylongprivatekeyhere" PKG_IDENTIFIER = "com.yourcompany.sal_enrol" SAL_PKG = "https://github.com/salopensource/sal/releases/download/v0.4.0/sal_scripts.pkg" FACTER_PKG = "https://downloads.puppetlabs.com/mac/facter-latest.dmg" # STOP EDITING HERE def download_package(temp_dir, pkg_url): file_name = pkg_url.split('/')[-1] output_path = os.path.join(temp_dir, file_name) u = urllib2.urlopen(pkg_url) f = open(output_path, 'wb') meta = u.info() file_size = int(meta.getheaders("Content-Length")[0]) print "Downloading: %s Bytes: %s" % (file_name, file_size) file_size_dl = 0 block_sz = 8192 while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) f.write(buffer) status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) status = status + chr(8)*(len(status)+1) print status, f.close() return output_path def get_machine_groups(): api_url = "%s/api/machine_groups/" % SAL_URL req = urllib2.Request(api_url) req.add_header('privatekey', PRIVATE_KEY) req.add_header('publickey', PUBLIC_KEY) response = urllib2.urlopen(req) output = response.read() return json.loads(output) def mount_dmg(dmg): # Mount the dmg temp_mount = tempfile.mkdtemp() cmd = ['/usr/bin/hdiutil', 'attach', dmg, '-mountpoint', temp_mount] subprocess.call(cmd) return temp_mount def unmount_dmg(path): cmd = ['/usr/bin/hdiutil', 'eject', path] subprocess.call(cmd) def copy_packages(sourcePath, destPath): """ Finds all packages in a specified directory and copies them to a specified directory """ pkg_list = [] for package in os.listdir(sourcePath): if package.endswith('.pkg') or package.endswith('.mpkg'): pkg = os.path.join(sourcePath, package) dest_file = os.path.join(destPath, os.path.basename(pkg)) if os.path.isfile(pkg): shutil.copy(pkg, dest_file) else: shutil.copytree(pkg, dest_file) pkg_list.append(dest_file) return pkg_list def main(): # Make our tempdir temp_dir = tempfile.mkdtemp() pkg_root = os.path.join(temp_dir, 'package_root') if not os.path.exists(pkg_root): os.makedirs(pkg_root) # Download Sal package package = download_package(temp_dir, SAL_PKG) # Move it to the pkg root shutil.move(package, os.path.join(pkg_root,os.path.basename(package))) #Download FACTER_PKG facter = download_package(temp_dir, FACTER_PKG) # Mount Facter dmg facter_mount = mount_dmg(facter) # And copy out the .pkg facter_packages = copy_packages(facter_mount, pkg_root) # Unmount the dmg unmount_dmg(facter_mount) # Get all of the machine Groups machine_groups = get_machine_groups() script_dir = os.path.join(temp_dir, 'Scripts') now = localtime() version = "%04d.%02d.%02d" % (now.tm_year, now.tm_mon, now.tm_mday) # For Each machine group for group in machine_groups: pkg_name = '%s - %s.pkg' % (str(group['id']), group['name']) script = """#!/bin/bash /usr/bin/defaults write $3/Library/Preferences/com.github.salopensource.sal ServerURL %s /usr/bin/defaults write $3/Library/Preferences/com.github.salopensource.sal key %s /usr/sbin/installer -pkg "/private/tmp/%s" -target $3 """ % (SAL_URL, group['key'], os.path.basename(package)) # There is potentially going to be more than one package in here, loop over them all for facter_package in facter_packages: extra_script = """ /usr/sbin/installer -pkg "/private/tmp/%s" -target $3 """ % os.path.basename(facter_package) script = script + extra_script if not os.path.exists(script_dir): os.makedirs(script_dir) script_path = os.path.join(script_dir, 'postinstall') with open(script_path, "w") as fd: fd.write(script) os.chmod(script_path, 0755) pkg_output_path = os.path.join(os.getcwd(), pkg_name) cmd = ['/usr/bin/pkgbuild', "--root", pkg_root, "--identifier", PKG_IDENTIFIER, "--version", version, "--scripts", script_dir, "--install-location", "/private/tmp", pkg_output_path] subprocess.call(cmd) shutil.rmtree(script_dir) if __name__ == '__main__': main()