Skip to content

Instantly share code, notes, and snippets.

@grahamgilbert
Created July 8, 2015 11:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamgilbert/8ccba318d3ecadee02b1 to your computer and use it in GitHub Desktop.
Save grahamgilbert/8ccba318d3ecadee02b1 to your computer and use it in GitHub Desktop.
Sal API Example
#!/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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment