├── .gitignore
├── README.md
├── CODE_OF_CONDUCT.md
├── Chef_Processors
├── ChefProcessors.recipe
├── ChefAttributeList.py
├── ChefAttributeHash.py
├── ChefArray.py
├── ChefLaunchd.py
├── ChefRemotePackage.py
├── ChefMacOSXUserDefaults.py
└── ChefRemoteDirectory.py
├── Shared_Processors
├── SharedProcessors.recipe
├── FileAppender.py
├── PackageInfoVersioner.py
├── SHAChecksum.py
├── Rsync.py
├── InstallsArrayFineTuning.py
├── DirectoryList.py
├── SubDirectoryList.py
└── README.md
├── .pre-commit-config.yaml
├── Duo
├── duo.download.recipe
├── duo.pkg.recipe
├── duo.extract.recipe
├── ConfigHeaderVersioner.py
└── ConfigureMakeInstaller.py
├── Intellij
├── Intellij.download.recipe
├── Intellij.install.recipe
├── Intellij.munki.recipe
└── IntellijURLProvider.py
├── BlueJeans
├── BlueJeans.download.recipe
└── BlueJeans.munki.recipe
├── Mosh
├── mosh.download.recipe
├── mosh.munki.recipe
└── MoshVersioner.py
├── DbVisualizer
├── DbVisualizer.download.recipe
├── DbVisualizer.dmg.recipe
├── DbVisualizer.pkg.recipe
├── DbVisualizer.install.recipe
└── DbVisualizer.munki.recipe
├── Framer
├── Framer.download.recipe
└── Framer.munki.recipe
├── android_sdk
├── android_sdk.minimal.pkg.recipe
├── android_sdk.minimal.download.recipe
├── android_sdk.minimal.munki.recipe
├── AndroidSDKVersioner.py
├── PropertiesWriter.py
├── AndroidXMLParser.py
└── AndroidExtraXMLParser.py
├── android_ndk
├── android_ndk.download.recipe
├── android_ndk.dmg.recipe
├── AndroidNDKVersioner.py
└── android_ndk.munki.recipe
├── Xcode
├── Xcode.extract.recipe
├── Xcode.download.recipe
├── XcodeVersionedName.munki.recipe
├── XcodeXIPUnpacker.py
├── XcodeBuildNumberEmitter.py
├── Xcode.munki.recipe
├── XcodeVersionEmitter.py
├── AppleDataGatherer.py
├── XcodeFileNamer.py
└── XcodeVersioner.py
├── Acrolinx
├── Acrolinx.download.recipe
├── Acrolinx.munki.recipe
└── AcrolinxURLProvider.py
├── VMwareFusionDeploy
├── VMwareFusionDeploy.pkg.recipe
└── VMwareFusionDeploy.munki.recipe
├── AdoptOpenJDK
├── AdoptOpenJDK11.download.recipe
├── AdoptOpenJDK11.munki.recipe
└── AdoptOpenJDKURLProvider.py
├── LobbyVideo
├── DateVersioner.py
├── lobbyvideo.dmg.recipe
└── lobbyvideo.munki.recipe
├── SQLDeveloper
├── SQLDeveloper.dmg.recipe
├── SQLDeveloperVersioner.py
└── SQLDeveloper.munki.recipe
├── munkitools
├── munkitools4.download.recipe
├── munkitools3.download.recipe
├── munkitools3.pkg.recipe
└── munkitools4.pkg.recipe
└── CONTRIBUTING.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.pyc
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Where did all the recipes go?
2 |
3 | This repo is being decommissioned. All modern recipes are migrated to [nmcspadden-recipes](https://github.com/autopkg/nmcspadden-recipes).
4 |
5 | Thank you for being a user of this repo. Thanks to all the contributors!
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
4 | Please read the [full text](https://code.fb.com/codeofconduct/)
5 | so that you can understand what actions will and will not be tolerated.
6 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefProcessors.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Recipe stub for any Shared Processors in this directory.
9 | Identifier
10 | com.facebook.autopkg.shared.chef
11 | Input
12 |
13 | MinimumVersion
14 | 0.4.0
15 | Process
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Shared_Processors/SharedProcessors.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Recipe stub for any Shared Processors in this directory.
9 |
10 | Identifier
11 | com.facebook.autopkg.shared
12 | Input
13 |
14 | MinimumVersion
15 | 0.4.0
16 | Process
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/homebysix/pre-commit-macadmin
3 | rev: v1.4.0
4 | hooks:
5 | - id: check-autopkg-recipes
6 | args: ['--recipe-prefix=com.facebook.autopkg.']
7 | - id: forbid-autopkg-overrides
8 | - id: forbid-autopkg-trust-info
9 | - id: check-plists
10 | - repo: https://github.com/pre-commit/pre-commit-hooks
11 | rev: v2.2.3
12 | hooks:
13 | - id: check-added-large-files
14 | args: [--maxkb=100]
15 | - id: check-ast
16 | - id: check-byte-order-marker
17 | - id: check-case-conflict
18 | - id: check-docstring-first
19 | - id: check-merge-conflict
20 | - id: end-of-file-fixer
21 | - id: fix-encoding-pragma
22 | - id: mixed-line-ending
23 | - id: trailing-whitespace
24 | args: [--markdown-linebreak-ext=md]
25 |
--------------------------------------------------------------------------------
/Duo/duo.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest release of Duo.
9 | Identifier
10 | com.facebook.autopkg.download.duo
11 | Input
12 |
13 | NAME
14 | Duo
15 |
16 | MinimumVersion
17 | 0.2.0
18 | Process
19 |
20 |
21 | Processor
22 | DeprecationWarning
23 | Arguments
24 |
25 | warning_message
26 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Intellij/Intellij.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest Intellij disk image.
9 | Identifier
10 | com.facebook.autopkg.download.intellij
11 | Input
12 |
13 | NAME
14 | Intellij
15 |
16 | MinimumVersion
17 | 0.6.0
18 | Process
19 |
20 |
21 | Processor
22 | DeprecationWarning
23 | Arguments
24 |
25 | warning_message
26 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/BlueJeans/BlueJeans.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest release of BlueJeans.
9 | Identifier
10 | com.facebook.autopkg.download.bluejeans
11 | Input
12 |
13 | NAME
14 | BlueJeans
15 |
16 | MinimumVersion
17 | 0.2.0
18 | Process
19 |
20 |
21 | Processor
22 | DeprecationWarning
23 | Arguments
24 |
25 | warning_message
26 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Mosh/mosh.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest release of mosh.
9 | Identifier
10 | com.facebook.autopkg.download.mosh
11 | Input
12 |
13 | NAME
14 | Mosh
15 | PRERELEASES
16 | True
17 |
18 | MinimumVersion
19 | 0.5.0
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/DbVisualizer/DbVisualizer.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the latest version of DbVisualizer.
9 | Identifier
10 | com.facebook.autopkg.download.dbvisualizer
11 | Input
12 |
13 | NAME
14 | DbVisualizer
15 | VERSION
16 | 11
17 |
18 | MinimumVersion
19 | 0.5.0
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Duo/duo.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Packages Duo.
9 | Identifier
10 | com.facebook.autopkg.pkg.duo
11 | Input
12 |
13 | NAME
14 | Duo
15 | PREFIX_PATH
16 | opt/duo
17 |
18 | MinimumVersion
19 | 0.2.0
20 | ParentRecipe
21 | com.facebook.autopkg.extract.duo
22 | Process
23 |
24 |
25 | Processor
26 | DeprecationWarning
27 | Arguments
28 |
29 | warning_message
30 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Framer/Framer.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest Framer zip file.
9 | Identifier
10 | com.facebook.autopkg.download.framer
11 | Input
12 |
13 | DOWNLOAD_URL
14 | https://dl.devmate.com/com.motif.framer/FramerStudio.zip
15 | NAME
16 | Framer
17 |
18 | MinimumVersion
19 | 0.2.0
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Duo/duo.extract.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Extracts Duo.
9 | Identifier
10 | com.facebook.autopkg.extract.duo
11 | Input
12 |
13 | NAME
14 | Duo
15 | PREFIX_PATH
16 | opt/duo
17 |
18 | MinimumVersion
19 | 0.2.0
20 | ParentRecipe
21 | com.facebook.autopkg.download.duo
22 | Process
23 |
24 |
25 | Processor
26 | DeprecationWarning
27 | Arguments
28 |
29 | warning_message
30 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Intellij/Intellij.install.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads Intellij Disk Image and then moves it to Applications
9 | Identifier
10 | com.facebook.autopkg.install.intellij
11 | Input
12 |
13 | RELEASE
14 | latest
15 |
16 | MinimumVersion
17 | 0.1.0
18 | ParentRecipe
19 | com.facebook.autopkg.download.intellij
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/DbVisualizer/DbVisualizer.dmg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads and makes a DMG of the latest version of DbVisualizer.
9 | Identifier
10 | com.facebook.autopkg.dmg.dbvisualizer
11 | Input
12 |
13 | NAME
14 | DbVisualizer
15 |
16 | MinimumVersion
17 | 0.5.0
18 | ParentRecipe
19 | com.facebook.autopkg.download.dbvisualizer
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android_sdk/android_sdk.minimal.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a package containing the Android SDK.
9 | Identifier
10 | com.facebook.autopkg.pkg.android_sdk.minimal
11 | Input
12 |
13 | NAME
14 | android_sdk
15 |
16 | MinimumVersion
17 | 0.2.0
18 | ParentRecipe
19 | com.facebook.autopkg.download.android_sdk.minimal
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/DbVisualizer/DbVisualizer.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the current release version of DbVisualizer and builds a package.
9 | Identifier
10 | com.facebook.autopkg.pkg.dbvisualizer
11 | Input
12 |
13 | NAME
14 | DbVisualizer
15 |
16 | MinimumVersion
17 | 0.2.0
18 | ParentRecipe
19 | com.facebook.autopkg.download.dbvisualizer
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android_sdk/android_sdk.minimal.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads a minimal set of the latest release of Android SDK.
9 | Identifier
10 | com.facebook.autopkg.download.android_sdk.minimal
11 | Input
12 |
13 | NAME
14 | android_sdk
15 |
16 | MinimumVersion
17 | 0.5.0
18 | Process
19 |
20 |
21 | Processor
22 | DeprecationWarning
23 | Arguments
24 |
25 | warning_message
26 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/DbVisualizer/DbVisualizer.install.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the current release version of DbVisualizer, builds an installer package and installs it.
9 | Identifier
10 | com.facebook.autopkg.install.dbvisualizer
11 | Input
12 |
13 | NAME
14 | DbVisualizer
15 |
16 | MinimumVersion
17 | 0.4.0
18 | ParentRecipe
19 | com.facebook.autopkg.pkg.dbvisualizer
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android_ndk/android_ndk.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads latest release of Android NDK.
9 | Identifier
10 | com.facebook.autopkg.download.android_ndk
11 | Input
12 |
13 | NAME
14 | android_ndk
15 | RELEASE
16 | r.*
17 |
18 | MinimumVersion
19 | 0.5.0
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android_ndk/android_ndk.dmg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a disk image containing the Android NDK.
9 | Identifier
10 | com.facebook.autopkg.dmg.android_ndk
11 | Input
12 |
13 | NAME
14 | android_ndk
15 |
16 | MinimumVersion
17 | 0.2.0
18 | ParentRecipe
19 | com.facebook.autopkg.download.android_ndk
20 | Process
21 |
22 |
23 | Processor
24 | DeprecationWarning
25 | Arguments
26 |
27 | warning_message
28 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Xcode/Xcode.extract.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Description
7 | Extract Xcode from a XIP. Requires passing in a XIP containing Xcode.
8 | Identifier
9 | com.facebook.autopkg.xcode.extract
10 | Input
11 |
12 | NAME
13 | Xcode
14 | BUILD_NUMBER_EMIT_PATH
15 | %RECIPE_CACHE_DIR%/xcode_build_number
16 |
17 | MinimumVersion
18 | 1.0.4
19 | ParentRecipe
20 | com.facebook.autopkg.xcode.downloader
21 | Process
22 |
23 |
24 | Processor
25 | DeprecationWarning
26 | Arguments
27 |
28 | warning_message
29 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Acrolinx/Acrolinx.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the latest version of Acrolinx and imports it into Munki.
9 | Identifier
10 | com.facebook.autopkg.download.Acrolinx
11 | Input
12 |
13 | NAME
14 | Acrolinx
15 | AC_USERNAME
16 | username
17 | AC_PASSWORD
18 | password
19 |
20 | MinimumVersion
21 | 2.0
22 | Process
23 |
24 |
25 | Processor
26 | DeprecationWarning
27 | Arguments
28 |
29 | warning_message
30 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Shared_Processors/FileAppender.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """Processor that creates a file."""
9 |
10 | from __future__ import absolute_import
11 |
12 | from autopkglib import Processor, ProcessorError
13 |
14 | __all__ = ["FileAppender"]
15 |
16 |
17 | class FileAppender(Processor):
18 | """Append contents to the end of a file."""
19 |
20 | description = __doc__
21 | input_variables = {
22 | "file_path": {"required": True, "description": "Path to a file to append to."},
23 | "file_content": {"required": True, "description": "Contents to add to a file."},
24 | }
25 | output_variables = {}
26 |
27 | def main(self):
28 | try:
29 | with open(self.env["file_path"], "a") as fileref:
30 | fileref.write(self.env["file_content"])
31 | self.output("Appened to file at %s" % self.env["file_path"])
32 | except BaseException as err:
33 | raise ProcessorError(
34 | "Can't append to file at %s: %s" % (self.env["file_path"], err)
35 | )
36 | # clean the variable up afterwards to not poison future runs
37 | self.env["file_content"] = ""
38 | self.env["file_path"] = ""
39 |
40 |
41 | if __name__ == "__main__":
42 | PROCESSOR = FileAppender()
43 | PROCESSOR.execute_shell()
44 |
--------------------------------------------------------------------------------
/Xcode/Xcode.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Description
7 | Download Xcode from the Apple dev portal. You must override the APPLE_ID and PASSWORD_FILE. BETA must either be empty for stable releases or set to "Beta" in order to match Xcode betas.
8 | Identifier
9 | com.facebook.autopkg.xcode.downloader
10 | Input
11 |
12 | NAME
13 | Xcode
14 | APPLE_ID
15 | dev@domain.com
16 | PASSWORD_FILE
17 | secret.txt
18 | BETA
19 |
20 | PATTERN
21 | (.*\/Xcode_.*\/Xcode.*.xip)
22 | NOSKIP
23 |
24 | VERSION_EMIT_PATH
25 | %RECIPE_CACHE_DIR%/xcode_tag
26 |
27 | MinimumVersion
28 | 1.0.4
29 | Process
30 |
31 |
32 | Processor
33 | DeprecationWarning
34 | Arguments
35 |
36 | warning_message
37 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/VMwareFusionDeploy/VMwareFusionDeploy.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a VMwareFusion mass deployment package DMG. Requires justinrummel-recipes to download. You can substitute your own deploy.ini file in an override by placing the content in the DEPLOY_INI_FILE input variable. At a minimum, you'll need to put your license key in, or the postflight will fail.
9 | Identifier
10 | com.facebook.autopkg.pkg.deploy.VMwareFusion
11 | Input
12 |
13 | DEPLOY_INI_FILE
14 | [Volume License]
15 | key = XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
16 |
17 | [UI Defaults]
18 |
19 | [Locations]
20 |
21 | [Applications]
22 |
23 | [Virtual Machines]
24 |
25 | NAME
26 | VMwareFusionDeploy
27 |
28 | MinimumVersion
29 | 0.2.5
30 | ParentRecipe
31 | com.justinrummel.download.VMwareFusion
32 | Process
33 |
34 |
35 | Processor
36 | DeprecationWarning
37 | Arguments
38 |
39 | warning_message
40 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/AdoptOpenJDK/AdoptOpenJDK11.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the current release version of AdoptOpenJDK 11. JVM defaults to "hotspot", or you can use "openj9". JDK_VERSION is which JDK OpenJDK version you wish to use, defaults to 11.
9 | Identifier
10 | com.facebook.autopkg.download.AdoptOpenJDK11
11 | Input
12 |
13 | NAME
14 | AdoptOpenJDK11
15 | JVM_TYPE
16 | hotspot
17 | JDK_TYPE
18 | jdk
19 | JDK_VERSION
20 | 11
21 | BINARY_TYPE
22 | pkg
23 | RELEASE
24 | latest
25 |
26 | MinimumVersion
27 | 1.4.1
28 | Process
29 |
30 |
31 | Processor
32 | DeprecationWarning
33 | Arguments
34 |
35 | warning_message
36 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Intellij/Intellij.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the latest Intellij disk image and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.intellij
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/Intellij
15 | NAME
16 | Intellij
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | description
24 | Lightweight IDE for Java SE, Groovy and Scala development.
25 | display_name
26 | Intellij Community Edition
27 | name
28 | %NAME%
29 | unattended_install
30 |
31 |
32 |
33 | MinimumVersion
34 | 0.2.0
35 | ParentRecipe
36 | com.facebook.autopkg.download.intellij
37 | Process
38 |
39 |
40 | Processor
41 | DeprecationWarning
42 | Arguments
43 |
44 | warning_message
45 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Mosh/mosh.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Imports latest release of mosh into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.mosh
11 | Input
12 |
13 | NAME
14 | Mosh
15 | PRERELEASES
16 | True
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | category
24 | Developer Tools
25 | developer
26 | MIT
27 | display_name
28 | Mosh
29 | minimum_os_version
30 | 10.6
31 | name
32 | %NAME%
33 | unattended_install
34 |
35 |
36 |
37 | MinimumVersion
38 | 0.5.0
39 | ParentRecipe
40 | com.facebook.autopkg.download.mosh
41 | Process
42 |
43 |
44 | Processor
45 | DeprecationWarning
46 | Arguments
47 |
48 | warning_message
49 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/android_sdk/android_sdk.minimal.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads a minimal set of Android SDK tools, creates a PKG out of it, and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.android_sdk.minimal
11 | Input
12 |
13 | DESTINATION_PATH
14 | /opt/android_sdk
15 | MUNKI_REPO_SUBDIR
16 | apps/%NAME%
17 | NAME
18 | android_sdk
19 | pkginfo
20 |
21 | catalogs
22 |
23 | testing
24 |
25 | category
26 | Developer Tools
27 | description
28 | Android SDK.
29 | developer
30 | Google
31 | display_name
32 | Android SDK
33 | unattended_install
34 |
35 |
36 |
37 | MinimumVersion
38 | 0.2.0
39 | ParentRecipe
40 | com.facebook.autopkg.pkg.android_sdk.minimal
41 | Process
42 |
43 |
44 | Processor
45 | DeprecationWarning
46 | Arguments
47 |
48 | warning_message
49 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/LobbyVideo/DateVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | from __future__ import absolute_import
19 |
20 | import datetime
21 | import time
22 |
23 | from autopkglib import Processor
24 |
25 | __all__ = ["DateVersioner"]
26 |
27 |
28 | class DateVersioner(Processor):
29 | description = "Places current date and time into %version%."
30 | input_variables = {
31 | "notime": {
32 | "required": False,
33 | "description": (
34 | "True/false. If true, ",
35 | "only the current date is provided. Defaults to false.",
36 | ),
37 | }
38 | }
39 | output_variables = {"version": {"description": "Current date and time as version."}}
40 |
41 | __doc__ = description
42 |
43 | def main(self):
44 | try:
45 | notime = self.env["notime"]
46 | except KeyError:
47 | notime = False
48 | self.output("notime is %s" % notime)
49 | self.env["version"] = (
50 | str(datetime.date.today()) + "_" + str(time.strftime("%H-%M-%S"))
51 | )
52 | if notime:
53 | self.env["version"] = str(datetime.date.today())
54 | self.output("Version is set to %s" % self.env["version"])
55 |
56 |
57 | if __name__ == "__main__":
58 | processor = DateVersioner()
59 | processor.execute_shell()
60 |
--------------------------------------------------------------------------------
/Shared_Processors/PackageInfoVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for PackageInfoVersioner class."""
9 |
10 | # Disabling warnings for env members and imports that only affect recipe-
11 | # specific processors.
12 | # pylint: disable=e1101,f0401
13 |
14 | from __future__ import absolute_import
15 |
16 | from xml.dom import minidom
17 |
18 | from autopkglib import Processor, ProcessorError
19 |
20 | __all__ = ["PackageInfoVersioner"]
21 |
22 |
23 | class PackageInfoVersioner(Processor):
24 | """Get version from a PackageInfo file in a distribution/bundle package."""
25 |
26 | description = __doc__
27 | input_variables = {
28 | "package_info_path": {
29 | "required": True,
30 | "description": (
31 | "Path to PackageInfo file inside a distribution",
32 | "/bundle package.",
33 | ),
34 | }
35 | }
36 | output_variables = {
37 | "pkg_id": {
38 | "description": "Package identifier returned from pkg-info field in PackageInfo."
39 | },
40 | "version": {
41 | "description": "Version returned from pkg-info field in PackageInfo."
42 | }
43 | }
44 |
45 | __doc__ = description
46 |
47 | def main(self):
48 | try:
49 | dom = minidom.parse(self.env["package_info_path"])
50 | except IOError as err:
51 | raise ProcessorError(err)
52 | pkgrefs = dom.getElementsByTagName("pkg-info")
53 | self.env["pkg_id"] = pkgrefs[0].attributes["identifier"].value
54 | self.output("Found pkg_id %s" % self.env["pkg_id"])
55 | self.env["version"] = pkgrefs[0].attributes["version"].value
56 | self.output("Found version %s" % self.env["version"])
57 |
58 |
59 | if __name__ == "__main__":
60 | PROCESSOR = PackageInfoVersioner()
61 | PROCESSOR.execute_shell()
62 |
--------------------------------------------------------------------------------
/Framer/Framer.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the latest Framer zip file and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.framer
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/Framer
15 | NAME
16 | Framer
17 | pkginfo
18 |
19 | catalogs
20 |
21 | prod
22 | trusted_testers
23 | testing
24 |
25 | category
26 | Design
27 | description
28 | Framer is a design tool that uses code to make anything possible. Pioneer new patterns and groundbreaking designs. Find the best solution, not just the expected one.
29 | developer
30 | Motiv Tools, BV
31 | display_name
32 | Framer Studio
33 | name
34 | %NAME%
35 | unattended_install
36 |
37 |
38 |
39 | MinimumVersion
40 | 0.2.0
41 | ParentRecipe
42 | com.facebook.autopkg.download.framer
43 | Process
44 |
45 |
46 | Processor
47 | DeprecationWarning
48 | Arguments
49 |
50 | warning_message
51 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Shared_Processors/SHAChecksum.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) 2015, Facebook, Inc.
4 | # All rights reserved.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree. An additional grant
8 | # of patent rights can be found in the PATENTS file in the same directory.
9 | """See docstring for SHAChecksum class"""
10 |
11 | # Disabling warnings for env members and imports that only affect recipe-
12 | # specific processors.
13 | # pylint: disable=e1101,f0401
14 |
15 | import subprocess
16 |
17 | from autopkglib import Processor, ProcessorError
18 |
19 |
20 | __all__ = ["SHAChecksum"]
21 |
22 |
23 | class SHAChecksum(Processor):
24 | """Calculate checksum for a file"""
25 |
26 | description = __doc__
27 | input_variables = {
28 | "source_file": {
29 | "required": True,
30 | "description": ("Path to file to calculate checksum on."),
31 | },
32 | "checksum_type": {
33 | "required": False,
34 | "description": (
35 | "Checksum type, will be passed directly to ",
36 | "shasum -a. See manpage for available options. "
37 | "Defaults to SHA1.",
38 | ),
39 | },
40 | }
41 | output_variables = {
42 | "checksum": {
43 | "description": "Version returned from pkg-info field in PackageInfo."
44 | }
45 | }
46 |
47 | __doc__ = description
48 |
49 | def main(self):
50 | sha_args = self.env.get("checksum_type", None)
51 | cmd = ["/usr/bin/shasum"]
52 | if sha_args:
53 | cmd.append("-a")
54 | cmd.append(sha_args)
55 | cmd.append(self.env["source_file"])
56 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
57 | (shaout, shaerr) = proc.communicate()
58 | if shaerr:
59 | raise ProcessorError(shaerr)
60 | self.output(shaout)
61 | self.env["checksum"] = shaout.split()[0].decode("utf-8")
62 |
63 |
64 | if __name__ == "__main__":
65 | PROCESSOR = SHAChecksum()
66 | PROCESSOR.execute_shell()
67 |
--------------------------------------------------------------------------------
/Shared_Processors/Rsync.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) 2015, Facebook, Inc.
5 | # All rights reserved.
6 | #
7 | # This source code is licensed under the BSD-style license found in the
8 | # LICENSE file in the root directory of this source tree. An additional grant
9 | # of patent rights can be found in the PATENTS file in the same directory.
10 | """See docstring for Rsync class."""
11 |
12 | from __future__ import absolute_import
13 |
14 | import subprocess
15 |
16 | from autopkglib import Processor, ProcessorError
17 |
18 | __all__ = ["Rsync"]
19 |
20 |
21 | class Rsync(Processor):
22 | """Rsyncs a path to another path."""
23 |
24 | description = __doc__
25 | input_variables = {
26 | "source_path": {
27 | "required": True,
28 | "description": ("Path to file or directory to copy from."),
29 | },
30 | "destination_path": {
31 | "required": True,
32 | "description": ("Path to file or directory to copy to."),
33 | },
34 | "rsync_arguments": {
35 | "required": False,
36 | "description": ("List of arguments passed to rsync directly."),
37 | },
38 | "rsync_path": {
39 | "required": False,
40 | "description": ("Custom path to rsync. Defaults to /usr/bin/rsync."),
41 | },
42 | }
43 | output_variables = {}
44 |
45 | __doc__ = description
46 |
47 | def main(self):
48 | rsync_location = self.env.get("rsync_path", "/usr/bin/rsync")
49 | rsync_args = self.env.get("rsync_arguments", [])
50 | if isinstance(rsync_args, basestring):
51 | raise ProcessorError("rsync_args must be a list!")
52 | cmd = [rsync_location]
53 | if rsync_args:
54 | cmd.extend(rsync_args)
55 | cmd.extend([self.env["source_path"], self.env["destination_path"]])
56 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
57 | (rout, rerr) = proc.communicate()
58 | if rerr:
59 | raise ProcessorError(rerr)
60 | self.output(rout)
61 |
62 |
63 | if __name__ == "__main__":
64 | PROCESSOR = Rsync()
65 | PROCESSOR.execute_shell()
66 |
--------------------------------------------------------------------------------
/Xcode/XcodeVersionedName.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Download, extract, and import Xcode as a unique entry into Munki. You must override the APPLE_ID and PASSWORD.
9 | Identifier
10 | com.facebook.autopkg.xcode_versioned.munki
11 | Input
12 |
13 | APPLE_ID
14 | dev@domain.com
15 | DESTINATION_APP_NAME
16 | Xcode.app
17 | ICON_NAME
18 | Xcode.png
19 | MUNKI_REPO_SUBDIR
20 | apps/apple/xcode/
21 | NAME
22 | Xcode
23 | PASSWORD_FILE
24 | secret.txt
25 |
26 | ARBITRARY_SUFFIX
27 |
28 | pkginfo
29 |
30 | catalogs
31 |
32 | testing
33 |
34 | description
35 | Xcode
36 | display_name
37 | %NAME%
38 | name
39 | %NAME%
40 | unattended_install
41 |
42 |
43 |
44 | MinimumVersion
45 | 1.0.4
46 | ParentRecipe
47 | com.facebook.autopkg.xcode.extract
48 | Process
49 |
50 |
51 | Processor
52 | DeprecationWarning
53 | Arguments
54 |
55 | warning_message
56 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/DbVisualizer/DbVisualizer.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads and makes a DMG of the latest version of DbVisualizer, and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.dbvisualizer
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/DbVis
15 | NAME
16 | DbVisualizer
17 | VERSION
18 | 11
19 | pkginfo
20 |
21 | catalogs
22 |
23 | testing
24 |
25 | category
26 | Database Tools
27 | description
28 | DbVisualizer is the universal database tool for developers, DBAs and analysts. It is the perfect solution since the same tool can be used on all major operating systems accessing a wide range of databases.
29 | developer
30 | DbVis Software
31 | display_name
32 | DbVisualizer
33 | requires
34 |
35 | OracleJava7
36 |
37 | unattended_install
38 |
39 |
40 |
41 | MinimumVersion
42 | 0.5.0
43 | ParentRecipe
44 | com.facebook.autopkg.dmg.dbvisualizer
45 | Process
46 |
47 |
48 | Processor
49 | DeprecationWarning
50 | Arguments
51 |
52 | warning_message
53 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Shared_Processors/InstallsArrayFineTuning.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for PackageInfoVersioner class."""
9 |
10 |
11 | from __future__ import absolute_import
12 |
13 | from autopkglib import Processor, ProcessorError
14 |
15 | __all__ = ["InstallsArrayFineTuning"]
16 |
17 |
18 | class InstallsArrayFineTuning(Processor):
19 | """Change an installs array to allow fine-tuning of a type."""
20 |
21 | description = __doc__
22 | input_variables = {
23 | "additional_pkginfo": {
24 | "required": True,
25 | "description": ("Dictionary containing an installs array."),
26 | },
27 | "changes": {
28 | "required": True,
29 | "description": (
30 | "List of dictionaries containing replacement values "
31 | "for installs types. Each dictionary must contain a "
32 | "path and the new type."
33 | ),
34 | },
35 | }
36 |
37 | output_variables = {
38 | "changed_pkginfo": {"description": "Fine tuned additional_pkginfo dictionary."}
39 | }
40 |
41 | __doc__ = description
42 |
43 | def main(self):
44 | """Magic."""
45 | current = self.env["additional_pkginfo"]["installs"]
46 | changes = self.env["changes"]
47 | for change in changes:
48 | path = change.get("path", None)
49 | if not path:
50 | raise ProcessorError("No path found in change!")
51 | newtype = change.get("type", None)
52 | if not newtype:
53 | raise ProcessorError("No type found in change!")
54 | # Replace the installs
55 | for install in current:
56 | if install["path"] == path:
57 | install["type"] = newtype
58 | self.output("Replacing type for %s to %s" % (path, newtype))
59 | self.env["changed_pkginfo"] = current
60 |
61 |
62 | if __name__ == "__main__":
63 | PROCESSOR = InstallsArrayFineTuning()
64 | PROCESSOR.execute_shell()
65 |
--------------------------------------------------------------------------------
/android_ndk/AndroidNDKVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | """Return version for Android NDK."""
4 | #
5 | # Copyright (c) Facebook, Inc. and its affiliates.
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 |
19 | from __future__ import absolute_import
20 |
21 | import os
22 | import shlex
23 |
24 | from autopkglib import Processor, ProcessorError
25 |
26 | __all__ = ["AndroidNDKVersioner"]
27 |
28 |
29 | class AndroidNDKVersioner(Processor):
30 | """Return version for Android NDK."""
31 |
32 | description = (
33 | "Detect version of downloaded Android NDK based on source.properties."
34 | )
35 | input_variables = {
36 | "properties_path": {
37 | "required": True,
38 | "description": "File to parse for version info.",
39 | }
40 | }
41 | output_variables = {
42 | "release_num": {"description": "Release of download."},
43 | "version": {"description": "Version of download."},
44 | }
45 |
46 | def main(self):
47 | """Main."""
48 | path = self.env.get("properties_path")
49 | if not os.path.isfile(path):
50 | raise ProcessorError("%s doesn't exist!" % path)
51 | with open(path, "rb") as f:
52 | data = f.read()
53 | split_data = shlex.split(data)
54 | # Version is defined in the files
55 | version = split_data[split_data.index("Pkg.Revision") + 2]
56 | self.env["version"] = version.split()[-1]
57 | # Release is just based on filename
58 | self.env["release_num"] = os.path.basename(os.path.dirname(path)).split("-")[-1]
59 |
60 |
61 | if __name__ == "__main__":
62 | PROCESSOR = AndroidNDKVersioner()
63 | PROCESSOR.execute_shell()
64 |
--------------------------------------------------------------------------------
/BlueJeans/BlueJeans.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Imports the latest release of BlueJeans into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.bluejeans
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/%NAME%
15 | NAME
16 | BlueJeans
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | category
24 | Productivity
25 | description
26 | As an alternate to the browser plugin, Mac and Windows users can participate in live meetings using the Blue Jeans desktop app. This app will download automatically when you choose the Desktop App connection option to join a Blue Jeans meeting.
27 |
28 | With the Blue Jeans desktop app, you can:
29 |
30 | Host and join live meetings
31 | Start an instant meeting
32 | See and share video, audio, and content
33 | developer
34 | BlueJeans
35 | display_name
36 | Blue Jeans
37 | name
38 | %NAME%
39 | unattended_install
40 |
41 |
42 |
43 | MinimumVersion
44 | 0.2.0
45 | ParentRecipe
46 | com.facebook.autopkg.download.bluejeans
47 | Process
48 |
49 |
50 | Processor
51 | DeprecationWarning
52 | Arguments
53 |
54 | warning_message
55 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Acrolinx/Acrolinx.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the latest version of Acrolinx and imports it into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.Acrolinx
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/acrolinx
15 | NAME
16 | Acrolinx
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | category
24 | Productivity
25 | description
26 | Acrolinx helps you create more readable, findable, and engaging content.
27 | developer
28 | Acrolinx
29 | display_name
30 | Acrolinx
31 | name
32 | %NAME%
33 | unattended_install
34 |
35 |
36 |
37 | MinimumVersion
38 | 2.0
39 | ParentRecipe
40 | com.facebook.autopkg.download.Acrolinx
41 | Process
42 |
43 |
44 | Processor
45 | DeprecationWarning
46 | Arguments
47 |
48 | warning_message
49 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/AdoptOpenJDK/AdoptOpenJDK11.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Downloads the current release version of AdoptOpenJDK 11 and imports into Munki.
9 | Identifier
10 | com.github.facebook.munki.AdoptOpenJDK11
11 | Input
12 |
13 | NAME
14 | AdoptOpenJDK11
15 | MUNKI_REPO_SUBDIR
16 | apps/openjdk
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | category
24 | Developer Tools
25 | description
26 | Adopt Open JDK 11
27 | developer
28 | AdoptOpenJDK
29 | display_name
30 | Adopt OpenJDK 11
31 | name
32 | %NAME%
33 | unattended_install
34 |
35 |
36 |
37 | MinimumVersion
38 | 1.4.1
39 | ParentRecipe
40 | com.facebook.autopkg.download.AdoptOpenJDK11
41 | Process
42 |
43 |
44 | Processor
45 | DeprecationWarning
46 | Arguments
47 |
48 | warning_message
49 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/android_ndk/android_ndk.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Takes the EXTRACTED DMG and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.android_ndk
11 | Input
12 |
13 | DESTINATION_PATH
14 | /opt/android_ndk
15 | MUNKI_REPO_SUBDIR
16 | apps/%NAME%
17 | NAME
18 | android_ndk
19 | pkginfo
20 |
21 | catalogs
22 |
23 | testing
24 |
25 | category
26 | Developer Tools
27 | description
28 | Android NDK. Be sure to set your ENV variable for ANDROID_NDK_REPOSITORY to /opt/android_ndk/.
29 | developer
30 | Google
31 | display_name
32 | Android NDK
33 | unattended_install
34 |
35 |
36 |
37 | MinimumVersion
38 | 0.2.0
39 | ParentRecipe
40 | com.facebook.autopkg.dmg.android_ndk
41 | Process
42 |
43 |
44 | Processor
45 | DeprecationWarning
46 | Arguments
47 |
48 | warning_message
49 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Xcode/XcodeXIPUnpacker.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """Unpack an Xcode XIP."""
18 |
19 | import os
20 | import subprocess
21 |
22 | from autopkglib import Processor, ProcessorError
23 |
24 |
25 | __all__ = ["XcodeXIPUnpacker"]
26 |
27 |
28 | class XcodeXIPUnpacker(Processor):
29 | """Unpack a XIP file from Apple."""
30 |
31 | description = "Unpack an Apple XIP file."
32 | input_variables = {
33 | "PKG": {"required": True, "description": "Path to an Xcode .xip file."},
34 | "output_path": {
35 | "required": False,
36 | "description": (
37 | "Path to unpack the contents. Defaults to "
38 | "%RECIPE_CACHE_DIR%/%NAME%_unpack."
39 | ),
40 | },
41 | }
42 | output_variables = {}
43 |
44 | __doc__ = description
45 |
46 | def main(self):
47 | """Main."""
48 | xip_path = self.env["PKG"]
49 | if self.env.get("output_path"):
50 | output = self.env["output_path"]
51 | else:
52 | output = os.path.join(
53 | self.env["RECIPE_CACHE_DIR"], self.env["NAME"] + "_unpack"
54 | )
55 | if not os.path.isdir(output):
56 | os.makedirs(output)
57 |
58 | self.output(
59 | "Extracting xip archive, please be patient, this could take a long time..."
60 | )
61 | os.chdir(output)
62 | cmd = ["/usr/bin/xip", "--expand", xip_path]
63 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
64 | (out, err) = proc.communicate()
65 | if err:
66 | raise ProcessorError(err)
67 | self.output("Finished xip unpack.")
68 |
69 |
70 | if __name__ == "__main__":
71 | processor = XcodeXIPUnpacker()
72 | processor.execute_shell()
73 |
--------------------------------------------------------------------------------
/Xcode/XcodeBuildNumberEmitter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """ Emit Xcode Build Number to disk """
18 |
19 | import os.path
20 |
21 | from autopkglib import Processor
22 |
23 |
24 | __all__ = ["XcodeBuildNumberEmitter"]
25 |
26 |
27 | class XcodeBuildNumberEmitter(Processor):
28 | """Emit file containing Xcode Build Number"""
29 |
30 | description = __doc__
31 | input_variables = {
32 | "dont_skip": {
33 | "required": False,
34 | "default": False,
35 | "description": ("If this evaluates as truthy, do not skip this step."),
36 | },
37 | "build_version": {
38 | "required": True,
39 | "description": ("The build version number for this Xcode Release"),
40 | },
41 | "output_filepath": {
42 | "required": True,
43 | "description": ("Path to which xcode build number is emitted."),
44 | },
45 | }
46 | output_variables = {
47 | "derived_filename": {"description": "The derived filename to emit."}
48 | }
49 |
50 | __doc__ = description
51 |
52 | def main(self):
53 | """Main."""
54 | if not self.env["dont_skip"]:
55 | self.output("dont_skip is false, so skipping this Processor.")
56 | return
57 |
58 | build_number = self.env["build_version"]
59 |
60 | destination = os.path.expandvars(self.env["output_filepath"])
61 | with open(destination, "w") as f:
62 | f.write(build_number)
63 | self.output(
64 | "Xcode build number ({}) written to disk at {}".format(
65 | build_number,
66 | destination,
67 | )
68 | )
69 |
70 |
71 | if __name__ == "__main__":
72 | PROCESSOR = XcodeBuildNumberEmitter()
73 | PROCESSOR.execute_shell()
74 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefAttributeList.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for ChefAttributeList class."""
9 |
10 | from __future__ import absolute_import
11 |
12 | import os.path
13 |
14 | from autopkglib import Processor
15 |
16 | __all__ = ["ChefAttributeList"]
17 |
18 |
19 | class ChefAttributeList(Processor):
20 | """Class for Attribute List."""
21 |
22 | description = (
23 | "Produces a Chef attribute variable for a list of items. "
24 | "The attribute prefixes correspond to node settings - i.e. "
25 | "default[category][prefix][attribute]."
26 | )
27 | input_variables = {
28 | "attribute_version": {
29 | "required": True,
30 | "description": "Version of Munki this applies to.",
31 | },
32 | "attribute": {"required": True, "description": "Name of attribute."},
33 | "value": {
34 | "required": True,
35 | "description": (
36 | "Single string containing list of items, separated by commas."
37 | ),
38 | },
39 | "path_prefix": {
40 | "required": False,
41 | "description": "Path to prepend to each found item.",
42 | "default": "",
43 | },
44 | }
45 | output_variables = {
46 | "chef_block": {"description": "Chef attribute block."},
47 | "attribute_variable": {"description": "Full name of variable."},
48 | }
49 |
50 | __doc__ = description
51 |
52 | def main(self):
53 | """Main."""
54 | att_prefix = "munki['%s']['%s']" % (
55 | self.env["attribute_version"],
56 | self.env["attribute"],
57 | )
58 | self.env["chef_block"] = att_prefix + " = [\n"
59 | for value in self.env["value"].split(","):
60 | # attribute = '%s = [\n'
61 | # print "Value: %s" % value
62 | self.env["chef_block"] += " '%s',\n" % str(
63 | os.path.join(self.env["path_prefix"], value)
64 | )
65 | self.env["chef_block"] += "]\n"
66 | self.output("Chef block: %s" % self.env["chef_block"])
67 | self.env["attribute_variable"] = att_prefix.replace("default", "node")
68 |
69 |
70 | if __name__ == "__main__":
71 | PROCESSOR = ChefAttributeList()
72 | PROCESSOR.execute_shell()
73 |
--------------------------------------------------------------------------------
/Mosh/MoshVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | """See docstring for MoshVersioner class"""
18 |
19 | # The majority of this code is taken from MunkiCommon:
20 | # https://github.com/munki/munki/blob/master/code/client/munkilib/munkicommon.py
21 |
22 | import os
23 | import subprocess
24 | import tempfile
25 | from xml.dom import minidom
26 |
27 | from autopkglib import Processor, ProcessorError
28 |
29 |
30 | __all__ = ["MoshVersioner"]
31 |
32 |
33 | class MoshVersioner(Processor):
34 | description = "Get version from Mosh download."
35 | input_variables = {
36 | "pathname": {"required": True, "description": ("Path to downloaded package.")}
37 | }
38 | output_variables = {
39 | "version": {
40 | "description": (
41 | "Version info parsed, naively derived from the " "package's name."
42 | )
43 | }
44 | }
45 |
46 | __doc__ = description
47 |
48 | def main(self):
49 | filepath = self.env["pathname"]
50 | pkgtmp = tempfile.mkdtemp()
51 | os.chdir(pkgtmp)
52 | cmd_extract = ["/usr/bin/xar", "-xf", filepath, "Distribution"]
53 | result = subprocess.call(cmd_extract)
54 | if result == 0:
55 | dom = minidom.parse(os.path.join(pkgtmp, "Distribution"))
56 | pkgrefs = dom.getElementsByTagName("pkg-ref")
57 | unfixed = pkgrefs[1].attributes["version"].value.encode("UTF-8")
58 | # At this point, unfixed_version is typically "mosh-1.x.x"
59 | self.env["version"] = unfixed.lstrip(b"mosh-").decode()
60 | self.output("Found version: %s" % self.env["version"])
61 | else:
62 | raise ProcessorError(
63 | "An error occurred while extracting Distribution file"
64 | )
65 |
66 |
67 | if __name__ == "__main__":
68 | PROCESSOR = MoshVersioner()
69 | PROCESSOR.execute_shell()
70 |
--------------------------------------------------------------------------------
/Xcode/Xcode.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Description
7 | Download, extract, and import Xcode into Munki. You must override the APPLE_ID and PASSWORD.
8 | Identifier
9 | com.facebook.autopkg.xcode.munki
10 | Input
11 |
12 | NAME
13 | Xcode
14 | USE_VERSIONED_FILENAME
15 |
16 | FILENAME_SUFFIX
17 |
18 | MUNKI_REPO_SUBDIR
19 | apps/apple/xcode/
20 | ICON_NAME
21 | Xcode.png
22 | pkginfo
23 |
24 | catalogs
25 |
26 | testing
27 |
28 | description
29 | Xcode
30 | display_name
31 | %NAME%
32 | name
33 | %NAME%
34 | postinstall_script
35 | #!/bin/sh
36 | # Ensure everyone is a member of "developer" group
37 | /usr/sbin/dseditgroup -o edit -a everyone -t group _developer
38 | # Enable Developer Mode
39 | /usr/sbin/DevToolsSecurity -enable
40 | # Accept the license
41 | /Applications/%fixed_filename%/Contents/Developer/usr/bin/xcodebuild -license accept
42 | # Install embedded packages
43 | for PKG in `/bin/ls /Applications/%fixed_filename%/Contents/Resources/Packages/*.pkg` ; do
44 | /usr/sbin/installer -pkg "$PKG" -target /
45 | done
46 |
47 | unattended_install
48 |
49 |
50 |
51 | MinimumVersion
52 | 1.0.4
53 | ParentRecipe
54 | com.facebook.autopkg.xcode.extract
55 | Process
56 |
57 |
58 | Processor
59 | DeprecationWarning
60 | Arguments
61 |
62 | warning_message
63 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/LobbyVideo/lobbyvideo.dmg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Pacakges the lobbyvideo file
9 | Identifier
10 | com.facebook.autopkg.dmg.lobbyvideo
11 | Input
12 |
13 | DESTINATION_PATH
14 | /Users/Shared
15 | NAME
16 | lobbyvideo
17 | RULESET_NAME
18 | lobbyvideo.mp4
19 | SOURCE_DIR
20 | /Users/Shared/lobby_video
21 |
22 | MinimumVersion
23 | 0.2.0
24 | Process
25 |
26 |
27 | Processor
28 | DeprecationWarning
29 | Arguments
30 |
31 | warning_message
32 | This recipe will soon be removed. Please remove it from your list of recipes.
33 |
34 |
35 |
36 | Arguments
37 |
38 | pkgdirs
39 |
40 | dmg_root
41 | 0775
42 |
43 | pkgroot
44 | %RECIPE_CACHE_DIR%/
45 |
46 | Processor
47 | PkgRootCreator
48 |
49 |
50 | Arguments
51 |
52 | destination_path
53 | %RECIPE_CACHE_DIR%/dmg_root/
54 | source_path
55 | %SOURCE_DIR%/%RULESET_NAME%
56 |
57 | Processor
58 | Copier
59 |
60 |
61 | Arguments
62 |
63 | notime
64 |
65 |
66 | Processor
67 | DateVersioner
68 |
69 |
70 | Arguments
71 |
72 | dmg_path
73 | %RECIPE_CACHE_DIR%/%NAME%-%version%.dmg
74 | dmg_root
75 | %RECIPE_CACHE_DIR%/dmg_root/
76 |
77 | Processor
78 | DmgCreator
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/VMwareFusionDeploy/VMwareFusionDeploy.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Imports the VMwareFusion mass deployment package into Munki. Requires justinrummel-recipes to download. You can substitute your own deploy.ini file in an override by placing the content in the DEPLOY_INI_FILE input variable. At a minimum, you'll need to put your license key in (replace the XXXXXs), or the postflight will fail.
9 | Identifier
10 | com.facebook.autopkg.munki.deploy.VMwareFusion
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/VMware
15 | NAME
16 | VMwareFusion
17 | pkginfo
18 |
19 | blocking_applications
20 |
21 | VMware Fusion.app
22 |
23 | catalogs
24 |
25 | testing
26 |
27 | category
28 | Productivity
29 | description
30 |
31 | developer
32 | VMware
33 | display_name
34 | VMWare Fusion Pro
35 | minimum_os_version
36 | 10.13
37 | name
38 | %NAME%
39 | uninstall_method
40 | uninstall_script
41 | uninstall_script
42 | #!/bin/sh
43 | /bin/rm -rf /Applications/VMware\ Fusion.app
44 | /bin/rm -f /Library/Preferences/VMware Fusion/config
45 |
46 |
47 |
48 | MinimumVersion
49 | 0.2.5
50 | ParentRecipe
51 | com.facebook.autopkg.pkg.deploy.VMwareFusion
52 | Process
53 |
54 |
55 | Processor
56 | DeprecationWarning
57 | Arguments
58 |
59 | warning_message
60 | These recipes have moved into nmcspadden-recipes, and the identifiers have changed. Please update your overrides!
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/LobbyVideo/lobbyvideo.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a dmg of the lobbyvideo and imports into Munki.
9 | Identifier
10 | com.facebook.autopkg.munki.lobbyvideo
11 | Input
12 |
13 | MUNKI_REPO_SUBDIR
14 | apps/lobby/
15 | NAME
16 | lobbyvideo
17 | pkginfo
18 |
19 | catalogs
20 |
21 | testing
22 |
23 | description
24 | Lobby Video
25 | display_name
26 | %NAME%
27 | name
28 | %NAME%
29 | unattended_install
30 |
31 |
32 |
33 | MinimumVersion
34 | 0.2.0
35 | ParentRecipe
36 | com.facebook.autopkg.dmg.lobbyvideo
37 | Process
38 |
39 |
40 | Processor
41 | DeprecationWarning
42 | Arguments
43 |
44 | warning_message
45 | This recipe will soon be removed. Please remove it from your list of recipes.
46 |
47 |
48 |
49 | Arguments
50 |
51 | additional_pkginfo
52 |
53 | version
54 | %version%
55 |
56 |
57 | Processor
58 | MunkiPkginfoMerger
59 |
60 |
61 | Arguments
62 |
63 | additional_makepkginfo_options
64 |
65 | --itemname=%RULESET_NAME%
66 | --destinationpath=%DESTINATION_PATH%
67 | --owner=root
68 | --group=wheel
69 | --mode=u+rwx,go+rx
70 |
71 | pkg_path
72 | %dmg_path%
73 | repo_subdirectory
74 | %MUNKI_REPO_SUBDIR%
75 |
76 | Processor
77 | MunkiImporter
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/Acrolinx/AcrolinxURLProvider.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | """See docstring for AcrolinxURLProvider class"""
17 |
18 | from __future__ import absolute_import, division, print_function, unicode_literals
19 |
20 | from autopkglib import ProcessorError
21 | from autopkglib.URLGetter import URLGetter
22 |
23 |
24 | __all__ = ["AcrolinxURLProvider"]
25 |
26 | URL = "https://{}:{}@download.acrolinx.com:1443/api/deliverablePackages/575b1d0d401ae30b00e90f40/download/latest?preserve_credentials=true&proxy=true"
27 |
28 |
29 | class AcrolinxURLProvider(URLGetter):
30 | """Provides a download URL for Acrolinx."""
31 |
32 | description = __doc__
33 | input_variables = {
34 | "username": {"required": True, "description": "Username for authentication."},
35 | "password": {"required": True, "description": "Password for authentication"},
36 | }
37 | output_variables = {"url": {"description": "Download URL for Acrolinx."}}
38 |
39 | def main(self):
40 | """Find the download URL"""
41 | username = self.env["username"]
42 | password = self.env["password"]
43 | url = URL.format(username, password)
44 | # Fetch the API data
45 | curl_cmd = self.prepare_curl_cmd()
46 | curl_cmd.extend(["--head", url])
47 | raw_headers = self.download_with_curl(curl_cmd)
48 | header = self.parse_headers(raw_headers)
49 | # Use semantic versioning for the version string, although historically this
50 | # hasn't been anything particularly problematic
51 | acrolinx_url = header.get("http_redirected")
52 | if not acrolinx_url:
53 | self.output(f"Header: {header}")
54 | raise ProcessorError(
55 | "Header did not contain an 'http_redirected' "
56 | "value containing the expected Acrolinx URL. Check your "
57 | "username and password."
58 | )
59 | self.output(f"Found URL: {acrolinx_url}")
60 | self.env["url"] = acrolinx_url
61 |
62 |
63 | if __name__ == "__main__":
64 | PROCESSOR = AcrolinxURLProvider()
65 | PROCESSOR.execute_shell()
66 |
--------------------------------------------------------------------------------
/SQLDeveloper/SQLDeveloper.dmg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a DMG for SQLDeveloper. You must provide your own .zip download using the -p argument.
9 | Identifier
10 | com.facebook.autopkg.dmg.sqldeveloper
11 | Input
12 |
13 | NAME
14 | SQLDeveloper
15 |
16 | MinimumVersion
17 | 0.5.1
18 | Process
19 |
20 |
21 | Comment
22 | Requires manually providing SQLDeveloper .zip download.
23 | Processor
24 | PackageRequired
25 |
26 |
27 | Arguments
28 |
29 | pkgdirs
30 |
31 | pkgroot
32 | %RECIPE_CACHE_DIR%/%NAME%
33 |
34 | Processor
35 | PkgRootCreator
36 |
37 |
38 | Arguments
39 |
40 | archive_path
41 | %PKG%
42 | destination_path
43 | %pkgroot%
44 | purge_destination
45 |
46 |
47 | Processor
48 | Unarchiver
49 |
50 |
51 | Arguments
52 |
53 | input_path
54 | %pkgroot%/SQLDeveloper.app
55 | requirement
56 | identifier "com.oracle.SQLDeveloper" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = VB5E2TV963
57 |
58 | Processor
59 | CodeSignatureVerifier
60 |
61 |
62 | Arguments
63 |
64 | app_path
65 | %pkgroot%/SQLDeveloper.app
66 |
67 | Processor
68 | SQLDeveloperVersioner
69 |
70 |
71 | Arguments
72 |
73 | dmg_path
74 | %RECIPE_CACHE_DIR%/%NAME%-%version%.dmg
75 | dmg_root
76 | %pkgroot%
77 |
78 | Processor
79 | DmgCreator
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/munkitools/munkitools4.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Note: munkitools does not include a code signature. If your
9 | organization requires code signature, it is recommend to internally sign
10 | the application.
11 |
12 | Downloads and imports version 4 of the Munki tools via
13 | the official releases listing on GitHub. You can set INCLUDE_PRERELEASES
14 | to any value to have this recipe pull prerelease versions.
15 |
16 | Note that Munki 4 includes two additional component pkgs, munkitools_python
17 | and munkitools_no_python.
18 | This recipe imports this to the Munki with the appropriate 'requires' key,
19 | however as it is considered an optional component, this recipe does not
20 | add it as an update_for any Munki component. Admins should add
21 | munkitools_app_usage to a manifest manually if its installation on clients
22 | is desired.
23 |
24 | This recipe cannot be overridden to pull a download from an
25 | alternate location such as munkibuilds.org - it will only download the
26 | official releases. For this, use the munkitools2-autobuild.munki
27 | recipe with a manually-provided DOWNLOAD_URL variable.
28 |
29 | The GitHubReleasesInfoProvider processor used by this recipe also
30 | respects an input variable: 'sort_by_highest_tag_names', which
31 | if set, will ignore the post dates of the releases and instead sort
32 | descending by tag names according to LooseVersion semantics.
33 |
34 | MUNKI_ICON should be overridden with your icon name.
35 |
36 | Identifier
37 | com.facebook.autopkg.download.munkitools4
38 | Input
39 |
40 | INCLUDE_PRERELEASES
41 |
42 | NAME
43 | munkitools4
44 |
45 | MinimumVersion
46 | 0.5.0
47 | Process
48 |
49 |
50 | Arguments
51 |
52 | asset_regex
53 | ^munkitools-4.*?pkg$
54 | github_repo
55 | munki/munki
56 | include_prereleases
57 | %INCLUDE_PRERELEASES%
58 |
59 | Processor
60 | GitHubReleasesInfoProvider
61 |
62 |
63 | Processor
64 | URLDownloader
65 |
66 |
67 | Processor
68 | EndOfCheckPhase
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Duo/ConfigHeaderVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for ConfigHeaderVersioner class."""
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | from __future__ import absolute_import, print_function
25 |
26 | from autopkglib import Processor, ProcessorError
27 |
28 | __all__ = ["ConfigHeaderVersioner"]
29 |
30 |
31 | class ConfigHeaderVersioner(Processor):
32 | # pylint: disable=missing-docstring
33 | description = "Looks for a version key in a config.h header file."
34 | input_variables = {
35 | "header_file": {
36 | "required": True,
37 | "description": "Path to the config.h file in a Makefile directory.",
38 | },
39 | "version_key": {
40 | "required": False,
41 | "description": (
42 | "Key to look for for versioning. Defaults to PACKAGE_VERSION."
43 | ),
44 | "default": "PACKAGE_VERSION",
45 | },
46 | }
47 | output_variables = {"version": {"description": "Value of version key."}}
48 |
49 | __doc__ = description
50 |
51 | def main(self):
52 | print("Version key: %s" % self.env["version_key"])
53 | try:
54 | with open(self.env["header_file"], "rb") as f:
55 | for line in f:
56 | if self.env["version_key"] in line:
57 | version_line = line
58 | break
59 | # If we get here, we didn't find the version key
60 | else:
61 | raise ProcessorError("Version key not found in file!")
62 | except IOError as err:
63 | raise ProcessorError(err)
64 | self.output("Version line found: %s" % version_line)
65 | # The line is typically: #define PACKAGE_VERSION
66 | self.env["version"] = version_line.split(" ")[2].rstrip().strip('"')
67 | self.output("Version found: %s" % self.env["version"])
68 |
69 |
70 | if __name__ == "__main__":
71 | PROCESSOR = ConfigHeaderVersioner()
72 | PROCESSOR.execute_shell()
73 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefAttributeHash.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.
8 | #
9 | """See docstring for ChefAttributeHash class."""
10 |
11 | from __future__ import absolute_import
12 |
13 | from autopkglib import Processor
14 |
15 | __all__ = ["ChefAttributeHash"]
16 |
17 |
18 | class ChefAttributeHash(Processor):
19 | description = (
20 | "Produces a Chef attribute variable for a hash of items. "
21 | "The attribute prefixes correspond to node settings - i.e. "
22 | "default[category][prefix][attribute]."
23 | )
24 | input_variables = {
25 | "attribute_category": {
26 | "required": True,
27 | "description": "Leading category for each attribute.",
28 | },
29 | "attribute_prefix": {
30 | "required": True,
31 | "description": "Prefix to each attribute.",
32 | },
33 | "attribute": {"required": True, "description": "Name of attribute."},
34 | "value": {"required": True, "description": ("Dictionary of keys and values.")},
35 | "in_array": {
36 | "required": False,
37 | "description": (
38 | "Is this hash inside an array? If yes, a comma is added to the end"
39 | ),
40 | },
41 | }
42 | output_variables = {
43 | "chef_block": {"description": "Chef attribute block."},
44 | "attribute_variable": {"description": "Full name of variable."},
45 | }
46 |
47 | __doc__ = description
48 |
49 | def main(self):
50 | att_prefix = "default['%s']['%s']['%s']" % (
51 | self.env["attribute_category"],
52 | self.env["attribute_prefix"],
53 | self.env["attribute"],
54 | )
55 | self.env["chef_block"] = att_prefix + " = {\n"
56 | for value in sorted(self.env["value"].keys()):
57 | self.env["chef_block"] += "\t%s => %s,\n" % (
58 | value,
59 | self.env["value"][value],
60 | )
61 | self.env["chef_block"] += "}"
62 | # Remove the trailing comma on the last item
63 | self.env["chef_block"] = self.env["chef_block"].replace(",\n}", "\n}")
64 | if self.env.get("in_array"):
65 | # if this hash is in a list of hashes, add a comma at the end
66 | self.env["chef_block"] += ","
67 | self.env["chef_block"] += "\n"
68 | self.output("Chef block: %s" % self.env["chef_block"])
69 | self.env["attribute_variable"] = att_prefix.replace("default", "node")
70 |
71 |
72 | if __name__ == "__main__":
73 | PROCESSOR = ChefAttributeHash()
74 | PROCESSOR.execute_shell()
75 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Facebook's AutoPkg Recipes
2 | We want to make contributing to this project as easy and transparent as
3 | possible.
4 |
5 | ## Our Development Process
6 | Changes to AutoPkg recipes must be tested extensively and follow [AutoPkg recipe best practices](https://github.com/autopkg/autopkg/wiki/Recipe-Writing-Guidelines) as best as possible.
7 |
8 | These recipes are authored to support Facebook's needs first and foremost, and are then made available to the community in the hopes that others may benefit.
9 |
10 | Changes may occur in these recipes as Facebook encounters new solutions or revised methods for obtaining and installing the software.
11 |
12 | ## Pull Requests
13 | We actively welcome your pull requests.
14 |
15 | 1. Fork the repo and create your branch from `master`.
16 | 2. If you've added code that should be tested, please extensively test it and demonstrate with run logs that it works.
17 | 3. If any input or output variables change, please update the documentation.
18 | 4. Obviously, your recipe changes should work.
19 | 5. Make sure your code passes lint tests.
20 | 6. If you haven't already, complete the Contributor License Agreement ("CLA").
21 |
22 | ## Contributor License Agreement ("CLA")
23 | In order to accept your pull request, we need you to submit a CLA. You only need
24 | to do this once to work on any of Facebook's open source projects.
25 |
26 | Complete your CLA here:
27 |
28 | ## Issues
29 | We use GitHub issues to track public bugs. Please ensure your description is
30 | clear and has sufficient instructions to be able to reproduce the issue.
31 |
32 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
33 | disclosure of security bugs. In those cases, please go through the process
34 | outlined on that page and do not file a public issue.
35 |
36 | ## Coding Style
37 | * 4 spaces for indentation rather than tabs
38 | * 80 character line length
39 | * All custom processors (Python code) must pass flake8 and isort style linting.
40 |
41 | Sometimes custom processors are necessities to solve specific problems that can't be addressed by the built in provided processors. This repo contains several custom processors for that purpose.
42 |
43 | When possible, utilize existing built-in processors and shared processors. Custom Python processors should be purpose-built and limited in scope to the functionality necessary to solve the problem.
44 |
45 | ## License
46 | By contributing to Facebook's Recipes for AutoPkg, you agree that your contributions will be licensed
47 | under its BSD license.
48 |
49 | Please note that most of AutoPkg itself is licensed under the Apache license. For a good source on the differences between these licenses, please consult the free open book "[Understanding Open Source and Free Software Licensing](http://www.oreilly.com/openbook/osfreesoft/)" (O'Reilly, 2004).
50 |
--------------------------------------------------------------------------------
/android_sdk/AndroidSDKVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for AndroidSDKVersioner class."""
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | from __future__ import absolute_import
25 |
26 | import urllib2
27 | import xml.etree.cElementTree as ET
28 |
29 | from autopkglib import Processor, ProcessorError
30 |
31 | __all__ = ["AndroidSDKVersioner"]
32 |
33 |
34 | class AndroidSDKVersioner(Processor):
35 | # pylint: disable=missing-docstring
36 | description = "Parse the XML file for the latest version of the SDK tools."
37 | input_variables = {
38 | "xml_file": {"required": True, "description": "Path or URL to XML file."}
39 | }
40 | output_variables = {
41 | "version": {"description": "Combined version of the SDK tools."}
42 | }
43 |
44 | __doc__ = description
45 |
46 | def main(self):
47 | if "http" in self.env["xml_file"]:
48 | try:
49 | tree = ET.ElementTree(file=urllib2.urlopen(self.env["xml_file"]))
50 | except urllib2.URLError as err:
51 | raise ProcessorError(err)
52 | else:
53 | try:
54 | tree = ET.ElementTree(file=self.env["xml_file"])
55 | except IOError as err:
56 | raise ProcessorError(err)
57 | root = tree.getroot()
58 | schema = root.tag.split("}")[0] + "}"
59 | match = root.findall("%s%s" % (schema, "tool"))
60 | revision = "%srevision" % schema
61 | result = ""
62 | try:
63 | major = match[-1].find(revision).find("%smajor" % schema).text
64 | minor = match[-1].find(revision).find("%sminor" % schema).text
65 | micro = match[-1].find(revision).find("%smicro" % schema).text
66 | except IndexError:
67 | raise ProcessorError("Version not found!")
68 | result = "%s.%s.%s" % (major, minor, micro)
69 | self.env["version"] = result
70 | self.output("Version: %s" % self.env["version"])
71 |
72 |
73 | if __name__ == "__main__":
74 | PROCESSOR = AndroidSDKVersioner()
75 | PROCESSOR.execute_shell()
76 |
--------------------------------------------------------------------------------
/Intellij/IntellijURLProvider.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Intellij URL Provider."""
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | import xml.etree.cElementTree as ET
18 |
19 | from autopkglib.URLGetter import URLGetter
20 |
21 |
22 | __all__ = ["IntellijURLProvider"]
23 |
24 | intellij_version_url = "https://www.jetbrains.com/updates/updates.xml"
25 |
26 |
27 | class IntellijURLProvider(URLGetter):
28 | """Provide URL for latest Intellij IDEA build."""
29 |
30 | description = "Provides URL and version for the latest release of Intellij."
31 | input_variables = {
32 | "base_url": {
33 | "required": False,
34 | "description": (
35 | "Default is " "https://www.jetbrains.com/updates/updates.xml"
36 | ),
37 | },
38 | "edition": {
39 | "required": False,
40 | "description": (
41 | 'Either "C" for "Community" or "U" for "Ultimate" '
42 | 'edition. Defaults to "C".'
43 | ),
44 | },
45 | }
46 | output_variables = {"url": {"description": "URL to the latest release of Intellij"}}
47 |
48 | __doc__ = description
49 |
50 | def get_intellij_version(self, intellij_version_url):
51 | """Retrieve version number from XML."""
52 | # Read XML
53 | raw_xml = self.download(intellij_version_url, text=True)
54 | # Select the latest released build
55 | root = ET.fromstring(raw_xml)
56 | product = root.find('product[@name="IntelliJ IDEA"]')
57 | channel = product.find('channel[@status="release"]')
58 | builds = channel.findall("build")
59 | version = builds[0].attrib["version"]
60 | # Return pkg url.
61 | return str(version)
62 |
63 | def main(self):
64 | """Main function."""
65 | # Determine values.
66 | version_url = self.env.get("version_url", intellij_version_url)
67 | version = self.get_intellij_version(version_url)
68 | download_url = "https://download.jetbrains.com/idea/" "ideaI%s-%s.dmg" % (
69 | self.env.get("edition", "C"),
70 | version,
71 | )
72 |
73 | self.env["url"] = download_url
74 | self.output("URL: %s" % self.env["url"])
75 |
76 |
77 | if __name__ == "__main__":
78 | processor = IntellijURLProvider()
79 | processor.execute_shell()
80 |
--------------------------------------------------------------------------------
/Xcode/XcodeVersionEmitter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """Get all Version information from Xcode."""
18 |
19 | import os.path
20 |
21 | from autopkglib import Processor
22 |
23 |
24 | try:
25 | # python 2
26 | from urlparse import urlsplit
27 | except ImportError:
28 | from urllib.parse import urlsplit
29 |
30 |
31 | __all__ = ["XcodeVersionEmitter"]
32 |
33 |
34 | class XcodeVersionEmitter(Processor):
35 | """Output a version number based on the URL. Skipped by default."""
36 |
37 | description = __doc__
38 | input_variables = {
39 | "dont_skip": {
40 | "required": False,
41 | "default": False,
42 | "description": ("If this evaluates as truthy, do not skip this step."),
43 | },
44 | "url": {"required": True, "description": ("URL to parse the version from.")},
45 | "output_filepath": {
46 | "required": True,
47 | "description": ("Path to which xcode version tag is emitted."),
48 | },
49 | }
50 | output_variables = {
51 | "derived_filename": {"description": "The derived filename to emit."}
52 | }
53 |
54 | __doc__ = description
55 |
56 | def main(self):
57 | """Main."""
58 | if not self.env["dont_skip"]:
59 | self.output("dont_skip is false, so skipping this Processor.")
60 | return
61 | url = self.env["url"]
62 | url_split_object = urlsplit(url)
63 | # "https://download.developer.apple.com/Developer_Tools/Xcode_10.2.1/Xcode_10.2.1.xip" # noqa
64 | # "https://developer.apple.com//services-account/download?path=/Developer_Tools/Xcode_11_Beta_2/Xcode_11_Beta_2.xip" # noqa
65 | filename = os.path.splitext(os.path.basename(url_split_object.path))[0].lower()
66 | self.output("Derived filename: {}".format(filename))
67 | self.env["derived_filename"] = filename
68 |
69 | destination = os.path.expandvars(self.env["output_filepath"])
70 | with open(destination, "w") as f:
71 | f.write(filename)
72 | self.output(
73 | "Derived filename ({}) written to disk at {}".format(
74 | filename, destination
75 | )
76 | )
77 |
78 |
79 | if __name__ == "__main__":
80 | PROCESSOR = XcodeVersionEmitter()
81 | PROCESSOR.execute_shell()
82 |
--------------------------------------------------------------------------------
/munkitools/munkitools3.download.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Note: munkitools does not include a code signature. If your
9 | organization requires code signature, it is recommend to internally sign
10 | the application.
11 |
12 | Downloads and imports version 3 of the Munki tools via
13 | the official releases listing on GitHub. You can set INCLUDE_PRERELEASES
14 | to any value to have this recipe pull prerelease versions.
15 |
16 | Note that Munki 3 includes an additional component pkg, munkitools_app_usage.
17 | This recipe imports this to the Munki with the appropriate 'requires' key,
18 | however as it is considered an optional component, this recipe does not
19 | add it as an update_for any Munki component. Admins should add
20 | munkitools_app_usage to a manifest manually if its installation on clients
21 | is desired.
22 |
23 | This recipe cannot be overridden to pull a download from an
24 | alternate location such as munkibuilds.org - it will only download the
25 | official releases. For this, use the munkitools2-autobuild.munki
26 | recipe with a manually-provided DOWNLOAD_URL variable.
27 |
28 | The GitHubReleasesInfoProvider processor used by this recipe also
29 | respects an input variable: 'sort_by_highest_tag_names', which
30 | if set, will ignore the post dates of the releases and instead sort
31 | descending by tag names according to LooseVersion semantics.
32 |
33 | MUNKI_ICON should be overridden with your icon name.
34 |
35 | Identifier
36 | com.facebook.autopkg.download.munkitools3
37 | Input
38 |
39 | INCLUDE_PRERELEASES
40 |
41 | NAME
42 | munkitools3
43 |
44 | MinimumVersion
45 | 0.5.0
46 | Process
47 |
48 |
49 | Processor
50 | DeprecationWarning
51 | Arguments
52 |
53 | warning_message
54 | This recipe will soon be removed. Please remove it from your list of recipes.
55 |
56 |
57 |
58 | Arguments
59 |
60 | asset_regex
61 | ^munkitools-3.*?pkg$
62 | github_repo
63 | munki/munki
64 | include_prereleases
65 | %INCLUDE_PRERELEASES%
66 |
67 | Processor
68 | GitHubReleasesInfoProvider
69 |
70 |
71 | Processor
72 | URLDownloader
73 |
74 |
75 | Processor
76 | EndOfCheckPhase
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/android_sdk/PropertiesWriter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | """See docstring for PropertiesWriter class."""
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | from __future__ import absolute_import
25 |
26 | import ConfigParser
27 | from collections import OrderedDict
28 |
29 | from autopkglib import Processor, ProcessorError
30 |
31 | __all__ = ["PropertiesWriter"]
32 |
33 |
34 | # this code stolen from http://stackoverflow.com/a/25084055
35 | class EqualsSpaceRemover:
36 | output_file = None
37 |
38 | def __init__(self, new_output_file):
39 | self.output_file = new_output_file
40 |
41 | def write(self, what):
42 | self.output_file.write(what.replace(" = ", "="))
43 |
44 |
45 | class PropertiesWriter(Processor):
46 | # pylint: disable=missing-docstring
47 | description = "Read the version.properties file inside the SQLDeveloper.app."
48 | input_variables = {
49 | "file_path": {
50 | "required": True,
51 | "description": "Path to source.properties file to create.",
52 | },
53 | "properties": {
54 | "required": True,
55 | "description": "Dictionary of keys/values to write to file.",
56 | },
57 | }
58 | output_variables = {}
59 |
60 | __doc__ = description
61 |
62 | def main(self):
63 | cp = ConfigParser.SafeConfigParser()
64 | cp.optionxform = str
65 |
66 | sort = sorted(self.env["properties"].items(), key=lambda t: t[0])
67 | properties = OrderedDict(sort)
68 |
69 | for key, value in properties.iteritems():
70 | cp.set("", str(key), value)
71 | # Write the file out
72 | with open(self.env["file_path"], "wb") as f:
73 | try:
74 | cp.write(EqualsSpaceRemover(f))
75 | except IOError as err:
76 | raise ProcessorError(err)
77 | # Now delete the first line, the section header
78 | with open(self.env["file_path"], "rb") as old:
79 | lines = old.readlines()
80 | lines[0] = "# Generated by AutoPkg\n"
81 | with open(self.env["file_path"], "wb") as new:
82 | for line in lines:
83 | new.write(line)
84 |
85 |
86 | if __name__ == "__main__":
87 | PROCESSOR = PropertiesWriter()
88 | PROCESSOR.execute_shell()
89 |
--------------------------------------------------------------------------------
/SQLDeveloper/SQLDeveloperVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for SQLDeveloperVersioner class."""
19 |
20 | from __future__ import absolute_import
21 |
22 | import ConfigParser
23 | import os.path
24 |
25 | from autopkglib import Processor, ProcessorError
26 |
27 | __all__ = ["SQLDeveloperVersioner"]
28 |
29 |
30 | # this code stolen directly from
31 | # http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788
32 | class FakeSecHead(object):
33 | def __init__(self, fp):
34 | self.fp = fp
35 | self.sechead = "[properties]\n"
36 |
37 | def readline(self):
38 | if self.sechead:
39 | try:
40 | return self.sechead
41 | finally:
42 | self.sechead = None
43 | else:
44 | return self.fp.readline()
45 |
46 |
47 | class SQLDeveloperVersioner(Processor):
48 | # pylint: disable=missing-docstring
49 | description = "Read the version.properties file inside the SQLDeveloper.app."
50 | input_variables = {
51 | "app_path": {
52 | "required": True,
53 | "description": "Path to app to find the version.properties file in.",
54 | }
55 | }
56 | output_variables = {"version": {"description": "Actual version of app."}}
57 |
58 | __doc__ = description
59 |
60 | def main(self):
61 | # Unsurprisingly, SQLDeveloper fails to include a useful version in
62 | # the app's Info.plist. Instead, the actual version is buried deep
63 | # inside in a file called "version.properties". Thanks, Oracle.
64 | # You know, I was a having a pretty good day up until now...
65 | relative_path = (
66 | "Contents/Resources/sqldeveloper/sqldeveloper/bin/version.properties"
67 | )
68 | file_path = os.path.join(self.env["app_path"], relative_path)
69 | # this code stolen directly from
70 | # http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788
71 | cp = ConfigParser.SafeConfigParser()
72 | try:
73 | cp.readfp(FakeSecHead(open(file_path)))
74 | except IOError as err:
75 | raise ProcessorError(err)
76 | self.env["version"] = cp.get("properties", "ver_full")
77 | self.output("Version: %s" % self.env["version"])
78 |
79 |
80 | if __name__ == "__main__":
81 | PROCESSOR = SQLDeveloperVersioner()
82 | PROCESSOR.execute_shell()
83 |
--------------------------------------------------------------------------------
/Shared_Processors/DirectoryList.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for DirectoryList class."""
9 |
10 |
11 | from __future__ import absolute_import
12 |
13 | import os
14 | from glob import glob
15 |
16 | from autopkglib import Processor, ProcessorError
17 |
18 | __all__ = ["DirectoryList"]
19 |
20 |
21 | class DirectoryList(Processor):
22 | """Returns a list of items in a subdirectory as a string, separated by
23 | commas.
24 |
25 | Does not recurse into subdirectories.
26 | """
27 |
28 | input_variables = {
29 | "pattern": {
30 | "description": "Shell glob pattern to match files by",
31 | "required": True,
32 | },
33 | "find_method": {
34 | "description": (
35 | "Type of pattern to match. Currently only "
36 | 'supported type is "glob" (also the default)'
37 | ),
38 | "default": "glob",
39 | "required": False,
40 | },
41 | "remove_extension": {
42 | "description": ("Remove the extension at the end. Default to False."),
43 | "default": False,
44 | "required": False,
45 | },
46 | "suffix_string": {
47 | "description": (
48 | "String to append to each found item name in dir. Defaults to ','"
49 | ),
50 | "default": ",",
51 | "required": False,
52 | },
53 | }
54 | output_variables = {"found_filenames": {"description": "Found filename"}}
55 |
56 | description = __doc__
57 |
58 | def globfind(self, pattern):
59 | """Returns multiple files matching a glob."""
60 | # pylint: disable=no-self-use
61 |
62 | glob_matches = glob(pattern)
63 |
64 | if len(glob_matches) < 1:
65 | raise ProcessorError("No matching filename found")
66 |
67 | glob_matches.sort()
68 |
69 | # return glob_matches
70 | new_glob = []
71 | for glob_item in glob_matches:
72 | new_string = os.path.basename(glob_item)
73 | if self.env["remove_extension"]:
74 | new_string = os.path.splitext(new_string)[0]
75 | new_glob.append(new_string)
76 | return new_glob
77 |
78 | def main(self):
79 | pattern = self.env.get("pattern")
80 | method = self.env.get("find_method")
81 |
82 | format_string = "%s" % self.env["suffix_string"]
83 | search_string = "{0}"
84 | if method == "glob":
85 | self.env["found_filenames"] = search_string.format(
86 | format_string.join(self.globfind(pattern))
87 | ).strip()
88 | else:
89 | raise ProcessorError("Unsupported find_method: %s" % method)
90 | self.output("Found matches: %s" % self.env["found_filenames"])
91 |
92 |
93 | if __name__ == "__main__":
94 | PROCESSOR = DirectoryList()
95 | PROCESSOR.execute_shell()
96 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefArray.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.
8 | #
9 | """See docstring for ChefArray class."""
10 |
11 | from __future__ import absolute_import
12 |
13 | from autopkglib import Processor
14 |
15 | __all__ = ["ChefArray"]
16 |
17 |
18 | class ChefArray(Processor):
19 | description = (
20 | "Produces an array that can be used with other "
21 | " Chef blocks. See "
22 | "https://docs.chef.io/ruby.html#arrays."
23 | )
24 | input_variables = {
25 | "item_list": {
26 | "description": (
27 | "Array of items to be put into the array block. This "
28 | "can also be a single string."
29 | ),
30 | "required": True,
31 | },
32 | "no_wrap_quotes": {
33 | "description": "Do not add wrapping quotation marks.",
34 | "required": False,
35 | },
36 | "remove_version": {
37 | "description": ("Removes the version string from the variable."),
38 | "required": False,
39 | },
40 | }
41 | output_variables = {"array_block": {"description": "Chef array block."}}
42 |
43 | __doc__ = description
44 |
45 | def main(self):
46 | beginning_bracket = "[\n"
47 | iterator = "item"
48 | end_bracket = "]"
49 | each_text = ".each do |%s|\n" % iterator
50 | quotes = "'"
51 | itemlist = list()
52 |
53 | # Are we going to use wrapping quotes?
54 | if self.env.get("no_wrap_quotes"):
55 | quotes = ""
56 |
57 | # Check to see if one item was passed as a single string
58 | if isinstance(self.env["item_list"], basestring):
59 | if self.env["remove_version"]:
60 | # Remove the ['version'] text from the string
61 | version_string = "['%s']" % self.env["remove_version"]
62 | if version_string in self.env["item_list"]:
63 | self.env["item_list"] = self.env["item_list"].replace(
64 | version_string, ""
65 | )
66 | self.env["array_block"] = self.env["item_list"] + each_text
67 | else:
68 | itemlist = self.env["item_list"]
69 | # Begin the block
70 | self.env["array_block"] = beginning_bracket
71 | # Loop through the array of items
72 | for item in itemlist:
73 | self.output("Item: %s" % item)
74 | self.env["array_block"] += " %s%s%s,\n" % (quotes, str(item), quotes)
75 | # End the block
76 | self.env["array_block"] += end_bracket
77 | # Remove the trailing comma on the last item
78 | self.env["array_block"] = self.env["array_block"].replace(",\n]", "\n]")
79 | self.env["array_block"] += each_text
80 | self.output("Chef block: \n%s" % self.env["array_block"])
81 |
82 |
83 | if __name__ == "__main__":
84 | PROCESSOR = ChefArray()
85 | PROCESSOR.execute_shell()
86 |
--------------------------------------------------------------------------------
/Duo/ConfigureMakeInstaller.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for ConfigureMakeInstaller class."""
19 |
20 | from __future__ import absolute_import
21 |
22 | import os
23 | import subprocess
24 |
25 | from autopkglib import Processor, ProcessorError
26 |
27 | __all__ = ["ConfigureMakeInstaller"]
28 |
29 |
30 | class ConfigureMakeInstaller(Processor):
31 | # pylint: disable=missing-docstring
32 | description = "Runs Configure, Make, Make Install on target directory."
33 | input_variables = {
34 | "installer_dir_path": {
35 | "required": True,
36 | "description": "Path to directory containing Configure file.",
37 | },
38 | "prefix_path": {
39 | "required": False,
40 | "description": "Path to apply to --prefix argument.",
41 | },
42 | "output_path": {
43 | "required": False,
44 | "description": (
45 | "Path to output location. If not specified, "
46 | "'make install' may install things outside "
47 | "the cache directory. Be warned!"
48 | ),
49 | },
50 | }
51 | output_variables = {}
52 |
53 | __doc__ = description
54 |
55 | def main(self):
56 | conf_path = self.env["installer_dir_path"]
57 | makefile = os.path.join(conf_path, "Makefile")
58 | os.chdir(conf_path)
59 | cmd = ["./configure"]
60 | if self.env["prefix_path"]:
61 | cmd.append("--prefix=" + self.env["prefix_path"])
62 |
63 | # ./configure
64 | self.output("Command: %s" % cmd)
65 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
66 | (conf_out, conf_err) = proc.communicate()
67 | if conf_err:
68 | raise ProcessorError("./configure error: %s" % conf_err)
69 | self.output(conf_out)
70 |
71 | # make
72 | self.output("Running make")
73 | cmd = ["/usr/bin/make", "-f", makefile]
74 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
75 | (m_out, m_err) = proc.communicate()
76 | # if m_err:
77 | # raise ProcessorError("make error: %s" % m_err)
78 | self.output(m_out)
79 |
80 | # make install
81 | self.output("Running make install")
82 | destpath = self.env.get("output_path")
83 | cmd = ["/usr/bin/make", "install", "-f", makefile]
84 | if destpath:
85 | cmd.append("DESTDIR=" + destpath)
86 | self.output("install cmd: %s" % cmd)
87 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
88 | (mi_out, mi_err) = proc.communicate()
89 | # if mi_err:
90 | # raise ProcessorError("make install error: %s" % mi_err)
91 | self.output(mi_out)
92 |
93 |
94 | if __name__ == "__main__":
95 | PROCESSOR = ConfigureMakeInstaller()
96 | PROCESSOR.execute_shell()
97 |
--------------------------------------------------------------------------------
/SQLDeveloper/SQLDeveloper.munki.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Creates a DMG for SQLDeveloper and imports into Munki. You must provide your own .zip download using the -p argument.
9 | Identifier
10 | com.facebook.autopkg.munki.sqldeveloper
11 | Input
12 |
13 | JDK_NAME
14 | OracleJava8JDK
15 | MUNKI_REPO_SUBDIR
16 | apps/Oracle
17 | NAME
18 | SQLDeveloper
19 | pkginfo
20 |
21 | catalogs
22 |
23 | testing
24 |
25 | category
26 | Developer Tools
27 | description
28 | SQL Developer is a free integrated development environment that simplifies the development and management of Oracle Database.
29 | developer
30 | Oracle
31 | display_name
32 | SQL Developer
33 | name
34 | %NAME%
35 |
36 |
37 | MinimumVersion
38 | 0.5.1
39 | ParentRecipe
40 | com.facebook.autopkg.dmg.sqldeveloper
41 | Process
42 |
43 |
44 | Arguments
45 |
46 | faux_root
47 | %pkgroot
48 | installs_item_paths
49 |
50 | SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin/version.properties
51 |
52 |
53 | Processor
54 | MunkiInstallsItemsCreator
55 |
56 |
57 | Arguments
58 |
59 | additional_pkginfo
60 |
61 | installs
62 |
63 |
64 | md5checksum
65 | 2e7650fee02f3ac91838397daf5f8817
66 | path
67 | /Applications/SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin/version.properties
68 | type
69 | file
70 |
71 |
72 | requires
73 |
74 | %JDK_NAME%
75 |
76 | version
77 | %version%
78 |
79 |
80 | Processor
81 | MunkiPkginfoMerger
82 |
83 |
84 | Arguments
85 |
86 | pkg_path
87 | %RECIPE_CACHE_DIR%/%NAME%-%version%.dmg
88 | repo_subdirectory
89 | %MUNKI_REPO_SUBDIR%
90 |
91 | Processor
92 | MunkiImporter
93 |
94 |
95 | Arguments
96 |
97 | path_list
98 |
99 | %RECIPE_CACHE_DIR%/%NAME%-%version%.dmg
100 |
101 |
102 | Processor
103 | PathDeleter
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Shared_Processors/SubDirectoryList.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for SubDirectoryList class."""
9 |
10 |
11 | from __future__ import absolute_import
12 |
13 | import os
14 |
15 | from autopkglib import Processor, ProcessorError
16 |
17 | __all__ = ["SubDirectoryList"]
18 |
19 |
20 | class SubDirectoryList(Processor):
21 | """Finds a filename for use in other Processors.
22 |
23 | Currently only supports glob filename patterns.
24 | """
25 |
26 | input_variables = {
27 | "root_path": {
28 | "description": "Path to start looking for files.",
29 | "required": True,
30 | },
31 | "suffix_string": {
32 | "description": (
33 | "String to append to each found item name in dir. Defaults to ','"
34 | ),
35 | "default": ",",
36 | "required": False,
37 | },
38 | }
39 | output_variables = {
40 | "found_filenames": {
41 | "description": (
42 | "String containing a list of all files found "
43 | "relative to root_path, separated by "
44 | "suffix_string."
45 | )
46 | },
47 | "found_directories": {
48 | "description": (
49 | "String containg a list of all directories "
50 | "found relative to root_path, separated by "
51 | "suffix_string."
52 | )
53 | },
54 | "relative_root": {"description": ("Relative root path")},
55 | }
56 |
57 | description = __doc__
58 |
59 | def main(self):
60 | sip_dirs = ["usr", "usr/local", "private", "private/etc", "Library"]
61 | format_string = "%s" % self.env["suffix_string"]
62 | # search_string = ' \'{0}\''
63 | search_string = "{0}"
64 | dir_list = list()
65 | file_list = list()
66 | if not os.path.isdir(self.env["root_path"]):
67 | raise ProcessorError("Can't find root path!")
68 | for dirName, subdirList, fileList in os.walk(self.env["root_path"]):
69 | relative_path = os.path.relpath(dirName, self.env["root_path"])
70 | # We need to remove the SIP folders so Chef doesn't try to create them
71 | if not relative_path == "." and not (relative_path in sip_dirs):
72 | dir_list.append(relative_path)
73 | # search_string.format(format_string.join(dirName)).strip()
74 | for fname in fileList:
75 | if ".DS_Store" in fname:
76 | continue
77 | # print('\t%s' % fname)
78 | relpath = os.path.relpath(
79 | os.path.join(fname, dirName), self.env["root_path"]
80 | )
81 | self.output("Relative path: %s" % relpath)
82 | if relpath == ".":
83 | # we want to avoid prepending './' to files at root dir
84 | relpath = ""
85 | # print "Real relative path: %s" % relpath
86 | file_list.append(os.path.join(relpath, fname))
87 | self.env["found_directories"] = search_string.format(
88 | format_string.join(dir_list)
89 | ).strip()
90 | self.env["found_filenames"] = search_string.format(
91 | format_string.join(file_list)
92 | ).strip()
93 |
94 |
95 | if __name__ == "__main__":
96 | PROCESSOR = SubDirectoryList()
97 | PROCESSOR.execute_shell()
98 |
--------------------------------------------------------------------------------
/Xcode/AppleDataGatherer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """See docstring for AppleDataGatherer class"""
18 |
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | import os
25 |
26 | from autopkglib import Processor, ProcessorError
27 |
28 |
29 | try:
30 | # python 2
31 | from urllib import quote
32 | except ImportError:
33 | from urllib.parse import quote
34 |
35 |
36 | __all__ = ["AppleDataGatherer"]
37 |
38 |
39 | class AppleDataGatherer(Processor):
40 | """Gather Xcode-specific curl data payloads into a file on disk."""
41 |
42 | description = __doc__
43 | input_variables = {
44 | "apple_id": {
45 | "required": True,
46 | "description": ("AppleID that can log into the Apple dev portal."),
47 | },
48 | "password": {
49 | "required": False,
50 | "description": ("Password for AppleID that can log into Apple dev portal."),
51 | },
52 | "password_file": {
53 | "required": False,
54 | "description": (
55 | "A path to a file to read the password from. Using this will "
56 | "ignore the 'password' argument."
57 | ),
58 | },
59 | "appID_key": {"required": True, "description": ("App ID key to log into.")},
60 | }
61 | output_variables = {"data_pathname": {"description": "Path to the data file."}}
62 |
63 | __doc__ = description
64 |
65 | def main(self):
66 | """Store the login data file."""
67 | appleIDstring = "appleId={}&".format(quote(self.env["apple_id"]))
68 | appIDKeystring = "appIdKey={}&".format(self.env["appID_key"])
69 | if not self.env.get("password") and not self.env.get("password_file"):
70 | raise ProcessorError(
71 | "You must provide either a password, or a password_file argument."
72 | )
73 | password = self.env.get("password")
74 | if self.env.get("password_file"):
75 | with open(self.env["password_file"]) as f:
76 | password = f.read()
77 | passwordstring = "accountPassword={}".format(password)
78 |
79 | login_data = appleIDstring + appIDKeystring + passwordstring
80 | download_dir = os.path.join(self.env["RECIPE_CACHE_DIR"], "downloads")
81 | filename = "login_data"
82 | # create download_dir if needed
83 | if not os.path.exists(download_dir):
84 | try:
85 | os.makedirs(download_dir)
86 | except OSError as err:
87 | raise ProcessorError(
88 | "Can't create %s: %s" % (download_dir, err.strerror)
89 | )
90 | self.output("Writing data to file")
91 | self.env["data_pathname"] = os.path.join(download_dir, filename)
92 | with open(self.env["data_pathname"], "w") as f:
93 | f.write(login_data)
94 |
95 |
96 | if __name__ == "__main__":
97 | PROCESSOR = AppleDataGatherer()
98 | PROCESSOR.execute_shell()
99 |
--------------------------------------------------------------------------------
/Xcode/XcodeFileNamer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """Create a filename for Xcode based on version information."""
18 |
19 | from autopkglib import Processor
20 |
21 |
22 | __all__ = ["XcodeFileNamer"]
23 |
24 |
25 | class XcodeFileNamer(Processor):
26 | """Create a filename for Xcode based on version information."""
27 |
28 | description = __doc__
29 | input_variables = {
30 | "should_produce_versioned_name": {
31 | "description": (
32 | "Whether or not we should produce a versioned name. "
33 | "If this is non-empty, it's evaluated as true."
34 | ),
35 | "required": True,
36 | },
37 | "major_version": {
38 | "description": "Major version of Xcode - i.e. Xcode 7, 8.",
39 | "required": True,
40 | },
41 | "minor_version": {
42 | "description": "Minor version of Xcode - i.e. Xcode X.1, X.2.",
43 | "required": True,
44 | },
45 | "patch_version": {
46 | "description": (
47 | "Patch version of Xcode - i.e. Xcode X.Y.0, X.Y.1. "
48 | "Patch version will be normalized to 0 if missing (i.e. 8.3 "
49 | "becomes 8.3.0)."
50 | ),
51 | "required": True,
52 | },
53 | "is_beta": {
54 | "description": ("Boolean that is true if this Xcode is a beta version."),
55 | "required": True,
56 | },
57 | "beta_version": {
58 | "description": (
59 | "The beta number - 1, 2, 3, etc. Only used if is_beta is True. "
60 | "Assumed to be 0 if not provided."
61 | ),
62 | "required": False,
63 | },
64 | "should_lowercase": {
65 | "description": (
66 | "If this value is non-empty, use a lower-case filename - xcode_X.Y.0_suffix.app."
67 | ),
68 | "required": False,
69 | },
70 | "suffix": {
71 | "description": (
72 | "Any additional suffix string to append to the name prior to the .app extension."
73 | ),
74 | "required": False,
75 | },
76 | }
77 | output_variables = {
78 | "xcode_filename": {"description": "Allow producing a versioned Xcode name."}
79 | }
80 |
81 | __doc__ = description
82 |
83 | def main(self):
84 | """Main."""
85 | if not self.env["should_produce_versioned_name"] and self.env["is_beta"]:
86 | # Default name for Xcode Beta
87 | self.env["xcode_filename"] = "Xcode-beta"
88 | return
89 | elif not self.env["should_produce_versioned_name"]:
90 | # Default name for Xcode
91 | self.env["xcode_filename"] = "Xcode"
92 | return
93 | # end up with xcode_10.2.0_beta_4 or xcode_10.2.1
94 | prefix = "Xcode"
95 | if self.env.get("should_lowercase"):
96 | prefix = "xcode"
97 | name = "{}_{}.{}.{}".format(
98 | prefix,
99 | self.env["major_version"],
100 | self.env["minor_version"],
101 | self.env["patch_version"],
102 | )
103 | if self.env["is_beta"]:
104 | name = name + "_beta_{}".format(self.env.get("beta_version", "0"))
105 | name += self.env.get("suffix", "")
106 | self.output("Xcode name: {}".format(name))
107 | self.env["xcode_filename"] = name
108 |
109 |
110 | if __name__ == "__main__":
111 | PROCESSOR = XcodeFileNamer()
112 | PROCESSOR.execute_shell()
113 |
--------------------------------------------------------------------------------
/AdoptOpenJDK/AdoptOpenJDKURLProvider.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | """See docstring for AdoptOpenJDKURLProvider class"""
17 |
18 | from __future__ import absolute_import, division, print_function, unicode_literals
19 |
20 | import json
21 |
22 | from autopkglib import ProcessorError
23 | from autopkglib.URLGetter import URLGetter
24 |
25 |
26 | try:
27 | from urllib.parse import urljoin
28 | except ImportError:
29 | from urlparse import urljoin
30 |
31 |
32 | __all__ = ["AdoptOpenJDKURLProvider"]
33 |
34 | URL = "https://api.adoptopenjdk.net/v2/info/releases/"
35 |
36 |
37 | class AdoptOpenJDKURLProvider(URLGetter):
38 | """Provides a version and dmg download for the AdoptOpenJDK."""
39 |
40 | description = __doc__
41 | input_variables = {
42 | "jdk_version": {"required": True, "description": "Version of JDK to fetch."},
43 | "jdk_type": {
44 | "required": False,
45 | "description": "Fetch 'jdk', or 'jre'. Defaults to 'jdk'.",
46 | },
47 | "jvm_type": {
48 | "required": False,
49 | "description": (
50 | "Fetch a 'hotspot' or 'openj9' JVM target. Defaults to 'hotspot'."
51 | ),
52 | },
53 | "binary_type": {
54 | "required": False,
55 | "description": "Fetch a 'pkg' or 'tgz' download. Defaults to 'pkg'.",
56 | },
57 | "release": {
58 | "required": False,
59 | "description": "Fetch a specific release. Defaults to 'latest'.",
60 | },
61 | }
62 | output_variables = {
63 | "version": {"description": "Version of the product."},
64 | "url": {"description": "Download URL."},
65 | "checksum": {"description": "Checksum of the targeted product."},
66 | }
67 |
68 | def get_checksum(self, checksum_url, binary_type):
69 | """Get the expected checksum for the release."""
70 | checksum_data = self.download(checksum_url, text=True)
71 | return checksum_data.split()[0]
72 |
73 | def main(self):
74 | """Find the download URL"""
75 | jvm_type = self.env.get("jvm_type", "hotspot")
76 | if jvm_type not in ["hotspot", "openj9"]:
77 | raise ProcessorError("jvm_type can only be 'hotspot' or 'openj9'")
78 | jdk_type = self.env.get("jdk_type", "jdk")
79 | if jdk_type not in ["jdk", "jre"]:
80 | raise ProcessorError("jdk_type can only be 'jdk' or 'jre'")
81 | binary_type = self.env.get("binary_type", "pkg")
82 | if binary_type not in ["pkg", "tgz"]:
83 | raise ProcessorError("jdk_type can only be 'pkg' or 'tgz'")
84 | release = self.env.get("release", "latest")
85 | queries = "?os=mac&openjdk_impl={}&type={}&release={}".format(
86 | jvm_type, jdk_type, release
87 | )
88 | # Fetch the API data
89 | query_suffix = urljoin("openjdk{}".format(self.env["jdk_version"]), queries)
90 | api_url = urljoin(URL, query_suffix)
91 | self.output("Query URL: {}".format(api_url))
92 | api_data = self.download(api_url, text=True)
93 | api_results = json.loads(api_data)
94 | # Determine what we're looking for - pkg or tgz
95 | if binary_type == "pkg":
96 | checksum_url = api_results["binaries"][0]["installer_checksum_link"]
97 | url = api_results["binaries"][0]["installer_link"]
98 | else:
99 | checksum_url = api_results["binaries"][0]["checksum_link"]
100 | url = api_results["binaries"][0]["binary_link"]
101 | # Use semantic versioning for the version string, although historically this
102 | # hasn't been anything particularly problematic
103 | version = api_results["binaries"][0]["version_data"]["semver"]
104 | self.env["version"] = version
105 | self.output("Version: {}".format(version))
106 | # Get the checksum from the internet
107 | checksum = self.get_checksum(checksum_url, binary_type)
108 | self.env["checksum"] = checksum
109 | self.output("checksum: {}".format(checksum))
110 | # Pick the URL
111 | self.env["url"] = url
112 | self.output("Found URL {}".format(self.env["url"]))
113 |
114 |
115 | if __name__ == "__main__":
116 | PROCESSOR = AdoptOpenJDKURLProvider()
117 | PROCESSOR.execute_shell()
118 |
--------------------------------------------------------------------------------
/Shared_Processors/README.md:
--------------------------------------------------------------------------------
1 | # Shared Processors
2 |
3 | ## FileAppender
4 |
5 | This processor will simply append a string on to the end of a file. This is useful if an AutoPkg recipe needs to add more variables or other data into a file that already exists (as part of a download, or something created from a previous FileCreator processor).
6 |
7 | ### Example Usage:
8 | ```
9 |
10 | Processor
11 | com.facebook.autopkg.shared/FileAppender
12 | Arguments
13 |
14 | file_path
15 | %pkgroot%/attributes/default.rb
16 | file_content
17 | this_will_be_added_to_the_end
18 |
19 |
20 | ```
21 |
22 | ## PackageInfoVersioner
23 |
24 | This processor provides a way to get a version number from the PackageInfo file inside a distribution/bundle style package. This processor specifically looks for the "pkg-info" XML tag inside the PackageInfo file and uses that as the version. This is helpful for bundle packages that provide multiple components with unique / differing version numbers, and there's no single item you can reliably use for versioning.
25 |
26 | The simplest usage is to use something like FileFinder to locate the PackageInfo file inside the bundle package you've downloaded or unarchived and then call this processor.
27 |
28 | ### Example Usage:
29 | ```
30 |
31 | Processor
32 | com.facebook.autopkg.shared/PackageInfoVersioner
33 | Arguments
34 |
35 | package_info_path
36 | %found_filename%/PackageInfo
37 |
38 |
39 | ```
40 |
41 | ## Rsync
42 |
43 | This processor calls out to a locally installed rsync (defaults to `/usr/bin/rsync`) to rsync between a source and destination. You can specify a path to a specific rsync binary if needed.
44 |
45 | Arguments can be passed in, and the string provided to the "rsync_arguments" processor input variable will be passed directly into the subprocess call to rsync. See the rsync man page for acceptable arguments. *NOTE: The leading hyphens before your arguments are required!*
46 |
47 | Please note that we have so far only used this for local source -> destination copying, and have not tested a very wide a variety of rsync arguments - so there may be some things that get passed in that don't behave properly in this context. If you do find some arguments that cause problems, please let us know!
48 |
49 | ### Example Usage:
50 | ```
51 |
52 | Processor
53 | com.facebook.autopkg.shared/Rsync
54 | Arguments
55 |
56 | source_path
57 | %RECIPE_CACHE_DIR%/unpack/folder
58 | destination_path
59 | %pkgroot%/merged_folder
60 | rsync_arguments
61 | -Phav
62 |
63 |
64 | ```
65 |
66 | ## SHAChecksum
67 |
68 | This processors calls out to `/usr/bin/shasum` to calculate a checksum on a file. You can specify the SHA type (to be passed to the `-a` argument) as an input variable.
69 |
70 | ### Example Usage:
71 | This example will calculate the SHA-256 sum:
72 |
73 | ```
74 |
75 | Processor
76 | com.facebook.autopkg.shared/SHAChecksum
77 | Comment
78 | Calculate SHA256 checksum
79 | Arguments
80 |
81 | source_file
82 | %RECIPE_CACHE_DIR%/%NAME%-%version%.pkg
83 | checksum_type
84 | 256
85 |
86 |
87 | ```
88 |
89 | ## SubDirectoryList
90 | This is a more complex processor with more specific usage. For a given root path, this processor will walk through and create two lists: one for all files found relative to the root path, and one for all directories found relative to the root path.
91 |
92 | Both of these lists are stored as strings, with each item separated by the contents of the "suffix_string" input variable (which defaults to "," comma).
93 |
94 | This doesn't have too much use in most AutoPkg recipes, but is the foundational key for translating packages into other management suites that require the pre-creation of subdirectories before placing files on the disk.
95 |
96 | ### Example Usage:
97 | Here's a simple example for how to get the list of contents inside an unpacked package - such as the Munki app package.
98 |
99 | ```
100 |
101 | Processor
102 | com.facebook.autopkg.shared/SubDirectoryList
103 | Comment
104 | MUNKI ADMIN - get list of folder contents
105 | Arguments
106 |
107 | root_path
108 | %pkgroot%/files/default/munki/admin/%version%/
109 |
110 |
111 | ```
112 | The resulting `%found_directories%` will contain a list of all folders that are inside this root path, and the `%found_files%` will contain a list of all files that were found.
113 |
114 | This could be useful for recipes that convert packages into Puppet or Chef recipes, which may require directories to be created on disk prior to files being placed there.
115 |
--------------------------------------------------------------------------------
/android_sdk/AndroidXMLParser.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for AndroidXMLParser class."""
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | from __future__ import absolute_import
25 |
26 | import urllib2
27 | import xml.etree.cElementTree as ET
28 |
29 | from autopkglib import Processor, ProcessorError
30 |
31 | __all__ = ["AndroidXMLParser"]
32 |
33 |
34 | class AndroidXMLParser(Processor):
35 | # pylint: disable=missing-docstring
36 | description = "Parse the provided XML file for a variable match."
37 | input_variables = {
38 | "xml_file": {"required": True, "description": "Path or URL to XML file."},
39 | "namespace": {
40 | "required": True,
41 | "description": "Namespace to search for to find a tag inside.",
42 | },
43 | "tags": {
44 | "required": True,
45 | "description": (
46 | "Dictionary of tags to search for, and variables to "
47 | "name them - {'vendor-display': 'VendorDisplay'"
48 | ),
49 | },
50 | }
51 | output_variables = {
52 | "xml_output_variables": {
53 | "description": (
54 | "Output variables per 'tags' supplied as input. Note "
55 | "that this output variable is used as both a "
56 | "placeholder for documentation and for auditing "
57 | "purposes. One should use the actual named output "
58 | "variables as given as values to 'plist_keys' to refer"
59 | "to the output of this processor."
60 | )
61 | }
62 | }
63 |
64 | __doc__ = description
65 |
66 | def main(self):
67 | if "http" in self.env["xml_file"]:
68 | try:
69 | tree = ET.ElementTree(file=urllib2.urlopen(self.env["xml_file"]))
70 | except urllib2.URLError as err:
71 | raise ProcessorError(err)
72 | else:
73 | try:
74 | tree = ET.ElementTree(file=self.env["xml_file"])
75 | except IOError as err:
76 | raise ProcessorError(err)
77 | root = tree.getroot()
78 | schema = root.tag.split("}")[0] + "}"
79 | match = root.findall("%s%s" % (schema, self.env["namespace"]))
80 | for key, outputVar in self.env["tags"].iteritems():
81 | for item in match[-1]:
82 | if item.tag.replace(schema, "") == key:
83 | self.env[outputVar] = item.text
84 | self.output("Found %s as %s" % (key, self.env[outputVar]))
85 | break
86 | if key == "uses-license" and ("license" in self.env["tags"].keys()):
87 | # Special case since the license isn't a traditional key
88 | license_ref = item.attrib["ref"]
89 | self.output("Found license ref: %s" % license_ref)
90 | self.env[outputVar] = license_ref
91 | self.env[self.env["tags"]["license"]] = (
92 | root[0].text.encode("ascii", "ignore").encode("string-escape")
93 | )
94 | if key == "url":
95 | # It's easy to find the URL here, the structure is always the same
96 | archives = "%sarchives" % schema
97 | archive = "%sarchive" % schema
98 | url = "%surl" % schema
99 | # Look for a host os
100 | host_os = "%shost-os" % schema
101 | archive_list = match[-1].find(archives).findall(archive)
102 | for arch in archive_list:
103 | if arch.find(host_os) is not None:
104 | # If there's a "host-os" in the archive
105 | if "macosx" in arch.find(host_os).text:
106 | # Look for a Mac version
107 | self.env[outputVar] = arch.find(url).text.encode(
108 | "ascii", "ignore"
109 | )
110 | # self.output("Found %s as %s" % (key, self.env[outputVar]))
111 | break
112 | else:
113 | # No host os was provided, so assume they're not platform specific
114 | # So we return the first item
115 | self.env[outputVar] = (
116 | match[-1].find(archives).find(archive).find(url).text
117 | )
118 | self.output("Found: %s" % self.env[outputVar])
119 |
120 |
121 | if __name__ == "__main__":
122 | PROCESSOR = AndroidXMLParser()
123 | PROCESSOR.execute_shell()
124 |
--------------------------------------------------------------------------------
/Xcode/XcodeVersioner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright (c) Facebook, Inc. and its affiliates.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | """Get all Version information from Xcode."""
18 |
19 |
20 | from collections import namedtuple
21 |
22 | from autopkglib import Processor, ProcessorError
23 |
24 |
25 | try:
26 | import objc
27 | except ImportError:
28 | pass
29 |
30 | __all__ = ["XcodeVersioner"]
31 |
32 |
33 | class XcodeVersioner(Processor):
34 | """Break down a version number into its separate components."""
35 |
36 | description = __doc__
37 | input_variables = {
38 | "version": {
39 | "required": True,
40 | "description": (
41 | "CFBundleShortVersionString from an Xcode Info.plist. Produced by "
42 | "PlistReader."
43 | ),
44 | },
45 | "app_path": {
46 | "required": True,
47 | "description": (
48 | "Path to Xcode app to look up version information from the bundle."
49 | ),
50 | },
51 | }
52 | output_variables = {
53 | "major_version": {"description": "Major version of Xcode - i.e. Xcode 7, 8."},
54 | "minor_version": {
55 | "description": "Minor version of Xcode - i.e. Xcode X.1, X.2."
56 | },
57 | "patch_version": {
58 | "description": (
59 | "Patch version of Xcode - i.e. Xcode X.Y.0, X.Y.1. "
60 | "Patch version will be normalized to 0 if missing (i.e. 8.3 "
61 | "becomes 8.3.0)."
62 | )
63 | },
64 | "is_beta": {
65 | "description": ("Boolean that is true if this Xcode is a beta version.")
66 | },
67 | "beta_version": {"description": ("The beta number - 1, 2, 3, etc.")},
68 | "build_version": {"description": ("Build version of Xcode - e.g. 11B500")},
69 | }
70 |
71 | __doc__ = description
72 |
73 | def _load_objc_framework(self, f_name, f_path, class_whitelist):
74 | loaded = {}
75 | framework_bundle = objc.loadBundle( # NOQA
76 | f_name, bundle_path=f_path, module_globals=loaded
77 | )
78 | desired = {}
79 | for x in class_whitelist:
80 | if x in loaded:
81 | desired[x] = loaded[x]
82 | return namedtuple("AttributedFramework", desired.keys())(**desired)
83 |
84 | def xcode_info(self, app_path):
85 | DVTFoundation_path = (
86 | "%s/Contents/SharedFrameworks/" + "DVTFoundation.framework"
87 | ) % app_path
88 | desired_classes = ["DVTToolsInfo"]
89 | DVTFoundation = self._load_objc_framework(
90 | "DVTFoundation", DVTFoundation_path, desired_classes
91 | )
92 | x_info = DVTFoundation.DVTToolsInfo.toolsInfo()
93 | x_v = x_info.toolsVersion()
94 | x_b = x_info.toolsBuildVersion()
95 | app_info = []
96 | app_info.append(["major_version", str(x_v.versionMajorComponent())])
97 | app_info.append(["minor_version", str(x_v.versionMinorComponent())])
98 | app_info.append(["patch_version", str(x_v.versionUpdateComponent())])
99 | app_info.append(["build_version", x_b.name()])
100 | is_beta = bool(x_info.isBeta())
101 | app_info.append(["is_beta", is_beta])
102 | if is_beta:
103 | app_info.append(["beta_version", str(x_info.toolsBetaVersion())])
104 | else:
105 | app_info.append(["beta_version", "0"])
106 | return app_info
107 |
108 | def main(self):
109 | """Main."""
110 | main_version_string = self.env["version"]
111 | split_string = main_version_string.split(".")
112 | if len(split_string) < 2:
113 | raise ProcessorError(
114 | "Version string should be in format X.Y, unless Apple broke "
115 | "literally everything again."
116 | )
117 | self.env["major_version"] = str(split_string[0])
118 | self.output("Major version: %s" % self.env["major_version"])
119 | self.env["minor_version"] = str(split_string[1])
120 | self.output("Minor version: %s" % self.env["minor_version"])
121 | try:
122 | self.env["patch_version"] = split_string[2]
123 | except IndexError:
124 | self.output("Normalizing patch to 0")
125 | self.env["patch_version"] = str("0")
126 | self.env["is_beta"] = False
127 | xcode_info_results = self.xcode_info(self.env["app_path"])
128 | xcode_data = {}
129 | for info_pair in xcode_info_results:
130 | xcode_data[info_pair[0]] = info_pair[1]
131 | if xcode_data["is_beta"]:
132 | self.output("Beta version: %s" % xcode_data["beta_version"])
133 | self.env["is_beta"] = xcode_data["is_beta"]
134 | self.env["beta_version"] = xcode_data["beta_version"]
135 | self.output("Patch version: %s" % self.env["patch_version"])
136 |
137 | self.env["build_version"] = xcode_data["build_version"]
138 | self.output("Build version: %s" % self.env["build_version"])
139 |
140 |
141 | if __name__ == "__main__":
142 | PROCESSOR = XcodeVersioner()
143 | PROCESSOR.execute_shell()
144 |
--------------------------------------------------------------------------------
/munkitools/munkitools3.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Note: munkitools does not include a code signature. If your
9 | organization requires code signature, it is recommend to internally sign
10 | the application.
11 |
12 | Downloads and imports version 3 of the Munki tools via
13 | the official releases listing on GitHub. You can set INCLUDE_PRERELEASES
14 | to any value to have this recipe pull prerelease versions.
15 |
16 | Note that Munki 3 includes an additional component pkg, munkitools_app_usage.
17 | This recipe imports this to the Munki with the appropriate 'requires' key,
18 | however as it is considered an optional component, this recipe does not
19 | add it as an update_for any Munki component. Admins should add
20 | munkitools_app_usage to a manifest manually if its installation on clients
21 | is desired.
22 |
23 | This recipe cannot be overridden to pull a download from an
24 | alternate location such as munkibuilds.org - it will only download the
25 | official releases. For this, use the munkitools2-autobuild.munki
26 | recipe with a manually-provided DOWNLOAD_URL variable.
27 |
28 | The GitHubReleasesInfoProvider processor used by this recipe also
29 | respects an input variable: 'sort_by_highest_tag_names', which
30 | if set, will ignore the post dates of the releases and instead sort
31 | descending by tag names according to LooseVersion semantics.
32 |
33 | MUNKI_ICON should be overridden with your icon name.
34 |
35 | Identifier
36 | com.facebook.autopkg.pkg.munkitools3
37 | Input
38 |
39 | INCLUDE_PRERELEASES
40 |
41 | NAME
42 | munkitools3
43 |
44 | MinimumVersion
45 | 0.5.0
46 | ParentRecipe
47 | com.facebook.autopkg.download.munkitools3
48 | Process
49 |
50 |
51 | Processor
52 | DeprecationWarning
53 | Arguments
54 |
55 | warning_message
56 | This recipe will soon be removed. Please remove it from your list of recipes.
57 |
58 |
59 |
60 | Arguments
61 |
62 | destination_path
63 | %RECIPE_CACHE_DIR%/unpack
64 | flat_pkg_path
65 | %pathname%
66 |
67 | Processor
68 | FlatPkgUnpacker
69 |
70 |
71 | Arguments
72 |
73 | pkgdirs
74 |
75 | pkgroot
76 | %RECIPE_CACHE_DIR%/repack
77 |
78 | Processor
79 | PkgRootCreator
80 |
81 |
82 | Arguments
83 |
84 | pattern
85 | %RECIPE_CACHE_DIR%/unpack/munkitools_core-*
86 |
87 | Processor
88 | FileFinder
89 |
90 |
91 | Arguments
92 |
93 | destination_pkg
94 | %RECIPE_CACHE_DIR%/repack/munkitools_core.pkg
95 | source_flatpkg_dir
96 | %found_filename%
97 |
98 | Processor
99 | FlatPkgPacker
100 |
101 |
102 | Arguments
103 |
104 | pattern
105 | %RECIPE_CACHE_DIR%/unpack/munkitools_admin-*
106 |
107 | Processor
108 | FileFinder
109 |
110 |
111 | Arguments
112 |
113 | destination_pkg
114 | %RECIPE_CACHE_DIR%/repack/munkitools_admin.pkg
115 | source_flatpkg_dir
116 | %found_filename%
117 |
118 | Processor
119 | FlatPkgPacker
120 |
121 |
122 | Arguments
123 |
124 | pattern
125 | %RECIPE_CACHE_DIR%/unpack/munkitools_app-*
126 |
127 | Processor
128 | FileFinder
129 |
130 |
131 | Arguments
132 |
133 | destination_pkg
134 | %RECIPE_CACHE_DIR%/repack/munkitools_app.pkg
135 | source_flatpkg_dir
136 | %found_filename%
137 |
138 | Processor
139 | FlatPkgPacker
140 |
141 |
142 | Arguments
143 |
144 | pattern
145 | %RECIPE_CACHE_DIR%/unpack/munkitools_app_usage-*
146 |
147 | Processor
148 | FileFinder
149 |
150 |
151 | Arguments
152 |
153 | destination_pkg
154 | %RECIPE_CACHE_DIR%/repack/munkitools_app_usage.pkg
155 | source_flatpkg_dir
156 | %found_filename%
157 |
158 | Processor
159 | FlatPkgPacker
160 |
161 |
162 | Arguments
163 |
164 | pattern
165 | %RECIPE_CACHE_DIR%/unpack/munkitools_launchd-*
166 |
167 | Processor
168 | FileFinder
169 |
170 |
171 | Arguments
172 |
173 | destination_pkg
174 | %RECIPE_CACHE_DIR%/repack/munkitools_launchd.pkg
175 | source_flatpkg_dir
176 | %found_filename%
177 |
178 | Processor
179 | FlatPkgPacker
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/android_sdk/AndroidExtraXMLParser.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 |
18 | """See docstring for AndroidExtraXMLParser class."""
19 |
20 | # Disabling warnings for env members and imports that only affect recipe-
21 | # specific processors.
22 | # pylint: disable=e1101,f0401
23 |
24 | from __future__ import absolute_import, print_function
25 |
26 | import urllib2
27 | import xml.etree.cElementTree as ET
28 |
29 | from autopkglib import Processor, ProcessorError
30 |
31 | __all__ = ["AndroidExtraXMLParser"]
32 |
33 |
34 | def get_element_children_dict(element, schema):
35 | result_dict = dict()
36 | tag = ""
37 | if len(element.getchildren()) >= 1:
38 | for child in element.getchildren():
39 | tag = child.tag.replace(schema, "")
40 | if not child.getchildren():
41 | result_dict[tag] = child.text
42 | # the tag name gets the value of the text
43 | else:
44 | # if there are children, each child needs to be converted into a dict
45 | templist = list()
46 | for newchild in child.getchildren():
47 | templist.append(get_element_children_dict(newchild, schema))
48 | result_dict[tag] = templist
49 | else:
50 | # no grandchildren
51 | result_dict[element.tag.replace(schema, "")] = element.text
52 | return result_dict
53 |
54 |
55 | def find_value_in_dict(thedict, key):
56 | """Iterate through a dict to find all matching keys, even if inside another
57 | dict."""
58 | resultlist = list()
59 | if key not in thedict:
60 | # it might be buried inside a dict as a value
61 | for value in thedict.values():
62 | if type(value) == list:
63 | templist = list()
64 | for newvalue in value:
65 | result = find_value_in_dict(newvalue, key)
66 | if result:
67 | templist.append(result)
68 | if len(templist) == 1:
69 | resultlist = templist[0]
70 | else:
71 | resultlist.extend(templist)
72 | else:
73 | "Adding to dict 2 %s" % key
74 | resultlist.append(thedict[key])
75 | return resultlist
76 |
77 |
78 | class AndroidExtraXMLParser(Processor):
79 | # pylint: disable=missing-docstring
80 | description = "Parse the addons XML file for a variable match."
81 | input_variables = {
82 | "xml_file": {"required": True, "description": "Path or URL to XML file."},
83 | "name": {"required": True, "description": "Item name to match."},
84 | "tags": {
85 | "required": True,
86 | "description": (
87 | "Dictionary of tags to search for, and variables to "
88 | "name them - {'vendor-display': 'VendorDisplay'"
89 | ),
90 | },
91 | }
92 | output_variables = {"found_value": {"description": "Result of found attribute."}}
93 |
94 | __doc__ = description
95 |
96 | def main(self):
97 | if "http" in self.env["xml_file"]:
98 | try:
99 | tree = ET.ElementTree(file=urllib2.urlopen(self.env["xml_file"]))
100 | except urllib2.URLError as err:
101 | raise ProcessorError(err)
102 | else:
103 | try:
104 | tree = ET.ElementTree(file=self.env["xml_file"])
105 | except IOError as err:
106 | raise ProcessorError(err)
107 | root = tree.getroot()
108 | schema = root.tag.split("}")[0] + "}"
109 | # Look for everything else
110 | match = root.findall("%s%s" % (schema, "extra"))
111 | # Now look through the records
112 | for record in match:
113 | result_dict = get_element_children_dict(record, schema)
114 | # We match records by name-display field
115 | if record.find("%sname-display" % schema).text != self.env["name"]:
116 | continue
117 | for key, outputVar in self.env["tags"].iteritems():
118 | print("Key: %s" % key)
119 | if key == "license":
120 | # Look for license - it's a special case
121 | match = root.findall("%s%s" % (schema, "license"))
122 | self.env[self.env["tags"]["license"]] = (
123 | match[-1].text.encode("ascii", "ignore").encode("string-escape")
124 | )
125 | self.output("Found license.")
126 | continue
127 | if key == "uses-license":
128 | self.env[self.env["tags"]["uses-license"]] = record.find(
129 | "%s%s" % (schema, "uses-license")
130 | ).attrib["ref"]
131 | self.output(
132 | "Found license-ref: %s"
133 | % self.env[self.env["tags"]["uses-license"]]
134 | )
135 | continue
136 | # Look for revision - third special case
137 | if key == "revision":
138 | major = find_value_in_dict(result_dict, "revision")[0][0].get(
139 | "major", ""
140 | )
141 | minor = find_value_in_dict(result_dict, "revision")[0][1].get(
142 | "minor", ""
143 | )
144 | micro = find_value_in_dict(result_dict, "revision")[0][2]["micro"]
145 | self.env[self.env["tags"]["revision"]] = "%s.%s.%s" % (
146 | major,
147 | minor,
148 | micro,
149 | )
150 | self.output("Revision: %s" % self.env[self.env["tags"]["revision"]])
151 | continue
152 | value = find_value_in_dict(result_dict, key)
153 | print("Found value: %s" % value)
154 |
155 |
156 | if __name__ == "__main__":
157 | PROCESSOR = AndroidExtraXMLParser()
158 | PROCESSOR.execute_shell()
159 |
--------------------------------------------------------------------------------
/munkitools/munkitools4.pkg.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright
6 | Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
7 | Description
8 | Note: munkitools does not include a code signature. If your
9 | organization requires code signature, it is recommend to internally sign
10 | the application.
11 |
12 | Downloads and imports version 4 of the Munki tools via
13 | the official releases listing on GitHub. You can set INCLUDE_PRERELEASES
14 | to any value to have this recipe pull prerelease versions.
15 |
16 | Note that Munki 4 includes two additional component pkgs, munkitools_python
17 | and munkitools_no_python.
18 | This recipe imports this to the Munki with the appropriate 'requires' key,
19 | however as it is considered an optional component, this recipe does not
20 | add it as an update_for any Munki component. Admins should add
21 | munkitools_app_usage to a manifest manually if its installation on clients
22 | is desired.
23 |
24 | This recipe cannot be overridden to pull a download from an
25 | alternate location such as munkibuilds.org - it will only download the
26 | official releases. For this, use the munkitools2-autobuild.munki
27 | recipe with a manually-provided DOWNLOAD_URL variable.
28 |
29 | The GitHubReleasesInfoProvider processor used by this recipe also
30 | respects an input variable: 'sort_by_highest_tag_names', which
31 | if set, will ignore the post dates of the releases and instead sort
32 | descending by tag names according to LooseVersion semantics.
33 |
34 | MUNKI_ICON should be overridden with your icon name.
35 |
36 | Identifier
37 | com.facebook.autopkg.pkg.munkitools4
38 | Input
39 |
40 | INCLUDE_PRERELEASES
41 |
42 | NAME
43 | munkitools4
44 |
45 | MinimumVersion
46 | 0.5.0
47 | ParentRecipe
48 | com.facebook.autopkg.download.munkitools4
49 | Process
50 |
51 |
52 | Arguments
53 |
54 | destination_path
55 | %RECIPE_CACHE_DIR%/unpack
56 | flat_pkg_path
57 | %pathname%
58 |
59 | Processor
60 | FlatPkgUnpacker
61 |
62 |
63 | Arguments
64 |
65 | pkgdirs
66 |
67 | pkgroot
68 | %RECIPE_CACHE_DIR%/repack
69 |
70 | Processor
71 | PkgRootCreator
72 |
73 |
74 | Arguments
75 |
76 | pattern
77 | %RECIPE_CACHE_DIR%/unpack/munkitools_core-*
78 |
79 | Processor
80 | FileFinder
81 |
82 |
83 | Arguments
84 |
85 | destination_pkg
86 | %RECIPE_CACHE_DIR%/repack/munkitools_core.pkg
87 | source_flatpkg_dir
88 | %found_filename%
89 |
90 | Processor
91 | FlatPkgPacker
92 |
93 |
94 | Arguments
95 |
96 | pattern
97 | %RECIPE_CACHE_DIR%/unpack/munkitools_admin-*
98 |
99 | Processor
100 | FileFinder
101 |
102 |
103 | Arguments
104 |
105 | destination_pkg
106 | %RECIPE_CACHE_DIR%/repack/munkitools_admin.pkg
107 | source_flatpkg_dir
108 | %found_filename%
109 |
110 | Processor
111 | FlatPkgPacker
112 |
113 |
114 | Arguments
115 |
116 | pattern
117 | %RECIPE_CACHE_DIR%/unpack/munkitools_app-*
118 |
119 | Processor
120 | FileFinder
121 |
122 |
123 | Arguments
124 |
125 | destination_pkg
126 | %RECIPE_CACHE_DIR%/repack/munkitools_app.pkg
127 | source_flatpkg_dir
128 | %found_filename%
129 |
130 | Processor
131 | FlatPkgPacker
132 |
133 |
134 | Arguments
135 |
136 | pattern
137 | %RECIPE_CACHE_DIR%/unpack/munkitools_app_usage-*
138 |
139 | Processor
140 | FileFinder
141 |
142 |
143 | Arguments
144 |
145 | destination_pkg
146 | %RECIPE_CACHE_DIR%/repack/munkitools_app_usage.pkg
147 | source_flatpkg_dir
148 | %found_filename%
149 |
150 | Processor
151 | FlatPkgPacker
152 |
153 |
154 | Arguments
155 |
156 | pattern
157 | %RECIPE_CACHE_DIR%/unpack/munkitools_launchd-*
158 |
159 | Processor
160 | FileFinder
161 |
162 |
163 | Arguments
164 |
165 | destination_pkg
166 | %RECIPE_CACHE_DIR%/repack/munkitools_launchd.pkg
167 | source_flatpkg_dir
168 | %found_filename%
169 |
170 | Processor
171 | FlatPkgPacker
172 |
173 |
174 | Arguments
175 |
176 | pattern
177 | %RECIPE_CACHE_DIR%/unpack/munkitools_python-*
178 |
179 | Processor
180 | FileFinder
181 |
182 |
183 | Arguments
184 |
185 | destination_pkg
186 | %RECIPE_CACHE_DIR%/repack/munkitools_python.pkg
187 | source_flatpkg_dir
188 | %found_filename%
189 |
190 | Processor
191 | FlatPkgPacker
192 |
193 |
194 | Arguments
195 |
196 | pattern
197 | %RECIPE_CACHE_DIR%/unpack/munkitools_no_python-*
198 |
199 | Processor
200 | FileFinder
201 |
202 |
203 | Arguments
204 |
205 | destination_pkg
206 | %RECIPE_CACHE_DIR%/repack/munkitools_no_python.pkg
207 | source_flatpkg_dir
208 | %found_filename%
209 |
210 | Processor
211 | FlatPkgPacker
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefLaunchd.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for ChefLaunchd class."""
9 |
10 | from __future__ import absolute_import
11 |
12 | from autopkglib import Processor
13 |
14 | __all__ = ["ChefLaunchd"]
15 |
16 |
17 | class ChefLaunchd(Processor):
18 | description = (
19 | "Produces a cookbook_file Chef block. See "
20 | "https://docs.chef.io/resource_launchd.html."
21 | )
22 | input_variables = {
23 | "resource_name": {
24 | "required": True,
25 | "description": (
26 | "Name for the resource. This can be a single "
27 | "string or an array of strings. If an array is "
28 | "provided, the first item in the array will be the "
29 | "resource name and the rest will be turned "
30 | "into an array."
31 | ),
32 | },
33 | "launchd_resource_array": {
34 | "required": False,
35 | "description": "Does the resource_name represent an array variable?",
36 | },
37 | "launchd_action": {
38 | "required": True,
39 | "description": "Resource action. See documentation.",
40 | },
41 | "launchd_notifies": {
42 | "required": False,
43 | "description": (
44 | "Which resource takes action when this resource's state changes."
45 | ),
46 | },
47 | "launchd_launchd_name": {
48 | "required": False,
49 | "description": ("The name of the launchd."),
50 | },
51 | "launchd_subscribes": {
52 | "required": False,
53 | "description": (
54 | "Specify that this resource is to listen "
55 | "to another resource, and then take action "
56 | "when that resource's state changes."
57 | ),
58 | },
59 | "launchd_only_if": {"required": False, "description": "only_if guard phrase."},
60 | "launchd_not_if": {"required": False, "description": "not_if guard phrase."},
61 | "launchd_extra_indentation": {
62 | "required": False,
63 | "description": "Indent this block. Defaults to empty.",
64 | },
65 | "launchd_indentation_end": {
66 | "required": False,
67 | "description": "Should this end an indented section? Defaults to empty.",
68 | },
69 | "launchd_path": {
70 | "required": False,
71 | "description": "Explicit path to plist file.",
72 | },
73 | }
74 | output_variables = {"chef_block": {"description": "Chef block."}}
75 |
76 | __doc__ = description
77 |
78 | def main(self):
79 | # chef block variables
80 | prefix = "launchd_"
81 | block_name = "launchd"
82 |
83 | # formatting variables
84 | extra_formatting = ""
85 | end_text = "end\n"
86 | self.env["chef_block"] = ""
87 | each_do_beginning = "[\n"
88 | each_do_end = ".each do |item|\n"
89 | self.env["chef_block"] = each_do_beginning
90 | name = "item"
91 | notif_text = "not_if"
92 | onlyif_text = "only_if"
93 | indent_block = ""
94 |
95 | # Should this block be indented?
96 | if self.env.get("%sextra_indentation" % prefix):
97 | self.output("Adding indentation.")
98 | indent_block = " "
99 | end_text = " " + end_text
100 | extra_formatting = " "
101 | # Should this end an indented block?
102 | if self.env.get("%sindentation_end" % prefix):
103 | end_text = end_text + "end\n"
104 |
105 | # Check to see if only one item was passed
106 | if len(self.env["resource_name"].split(",")) == 1:
107 | if self.env.get("%sresource_array" % prefix):
108 | # it's a node variable representating an array
109 | self.env["chef_block"] = (
110 | indent_block
111 | + block_name
112 | + " "
113 | + self.env["resource_name"]
114 | + each_do_end
115 | )
116 | else:
117 | self.env["chef_block"] = (
118 | indent_block
119 | + block_name
120 | + " "
121 | + self.env["resource_name"]
122 | + " do\n"
123 | )
124 | else:
125 | for resource_name in self.env["resource_name"].split(","):
126 | self.env["chef_block"] += " %s,\n" % resource_name
127 | self.env["chef_block"] += "]" + each_do_end
128 | # Remove trailing comma
129 | self.env["chef_block"] = self.env["chef_block"].replace(",\n]", "\n]")
130 | self.env["chef_block"] += "%s %s do\n" % (block_name, name)
131 | # Insert an extra tab before everything
132 | extra_formatting = " "
133 | end_text = indent_block + "end\n\n"
134 |
135 | input_list = sorted(self.input_variables.keys())
136 | # Start the block
137 | # Remove the indentation keys
138 | input_list.remove("%sextra_indentation" % prefix)
139 | input_list.remove("%sindentation_end" % prefix)
140 | # Place not_if guards first
141 | if self.env.get("%snot_if" % prefix):
142 | self.env["chef_block"] += "%s %s %s\n" % (
143 | extra_formatting,
144 | notif_text,
145 | self.env["%snot_if" % prefix],
146 | )
147 | input_list.remove("%snot_if" % prefix)
148 | # Place only_if guards next
149 | if self.env.get("%sonly_if" % prefix):
150 | self.env["chef_block"] += "%s %s %s\n" % (
151 | extra_formatting,
152 | onlyif_text,
153 | self.env["%sonly_if" % prefix],
154 | )
155 | input_list.remove("%sonly_if" % prefix)
156 | # Remove the special keys
157 | input_list.remove("%sresource_array" % prefix)
158 | input_list.remove("resource_name")
159 | # Loop through all remaining keys
160 | for key in input_list:
161 | if self.env.get(key, ""):
162 | key_text = "%s" % key.replace("%s" % prefix, "")
163 | self.env["chef_block"] += "%s %s %s\n" % (
164 | extra_formatting,
165 | key_text,
166 | self.env[key],
167 | )
168 | # Clear out the key so it doesn't poison future runs
169 | self.env[key] = ""
170 | # end it
171 | self.env["chef_block"] += end_text + "\n"
172 | self.output("Chef block:\n%s" % self.env["chef_block"])
173 | # Clean up the keys that weren't iterated through
174 | self.env["%sextra_indentation" % prefix] = ""
175 | self.env["%sindentation_end" % prefix] = ""
176 | self.env["%snot_if" % prefix] = ""
177 | self.env["%sonly_if" % prefix] = ""
178 |
179 |
180 | if __name__ == "__main__":
181 | PROCESSOR = ChefLaunchd()
182 | PROCESSOR.execute_shell()
183 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefRemotePackage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for ChefRemotePackage class."""
9 |
10 | from __future__ import absolute_import
11 |
12 | from autopkglib import Processor
13 |
14 | __all__ = ["ChefRemotePackage"]
15 |
16 |
17 | class ChefRemotePackage(Processor):
18 | description = "Produces a cpe_remote_package Chef block."
19 | input_variables = {
20 | "resource_name": {
21 | "required": True,
22 | "description": (
23 | "Name for the resource. This can be a single "
24 | "string or an array of strings. If an array is "
25 | "provided, the first item in the array will be the "
26 | "resource name and the rest will be turned "
27 | "into an array."
28 | ),
29 | },
30 | "resource_array": {
31 | "required": False,
32 | "description": "Does the resource_name represent an array variable?",
33 | },
34 | "app": {"required": False, "description": "Name of the app being installed."},
35 | "checksum": {"required": True, "description": "SHA256 checksum for package."},
36 | "cleanup": {
37 | "required": False,
38 | "description": (
39 | "Specify whether we should keep the downloaded package."
40 | ),
41 | },
42 | "pkg_name": {
43 | "required": False,
44 | "description": (
45 | "Name of the package if it is not the same as ",
46 | "`app`-`version`, or if the name has spaces.",
47 | ),
48 | },
49 | "receipt": {
50 | "required": True,
51 | "description": (
52 | "The package receipt to determine if it's already installed."
53 | ),
54 | },
55 | "remote": {
56 | "required": False,
57 | "description": (
58 | "Specify whether we should try to download the package."
59 | ),
60 | },
61 | "version": {
62 | "required": True,
63 | "description": (
64 | "The version of the package receipt to determine "
65 | "if it's already installed."
66 | ),
67 | },
68 | "only_if": {"required": False, "description": "only_if guard phrase."},
69 | "not_if": {"required": False, "description": "not_if guard phrase."},
70 | "extra_indentation": {
71 | "required": False,
72 | "description": "Indent this block. Defaults to empty.",
73 | },
74 | "indentation_end": {
75 | "required": False,
76 | "description": "Should this end an indented section? Defaults to empty.",
77 | },
78 | }
79 | output_variables = {"chef_block": {"description": "Chef block."}}
80 |
81 | __doc__ = description
82 |
83 | def main(self):
84 | # chef block variables
85 | prefix = ""
86 | block_name = "cpe_remote_pkg"
87 |
88 | # formatting variables
89 | extra_formatting = ""
90 | end_text = "end\n"
91 | self.env["chef_block"] = ""
92 | each_do_beginning = "[\n"
93 | each_do_end = ".each do |item|\n"
94 | self.env["chef_block"] = each_do_beginning
95 | name = "item"
96 | notif_text = "not_if"
97 | onlyif_text = "only_if"
98 | indent_block = ""
99 |
100 | # Should this block be indented?
101 | if self.env.get("%sextra_indentation" % prefix):
102 | self.output("Adding indentation.")
103 | indent_block = " "
104 | end_text = " " + end_text
105 | extra_formatting = " "
106 | # Should this end an indented block?
107 | if self.env.get("%sindentation_end" % prefix):
108 | end_text = end_text + "end\n"
109 |
110 | # Check to see if only one item was passed
111 | if len(self.env["resource_name"].split(",")) == 1:
112 | if self.env.get("%sresource_array" % prefix):
113 | # it's a node variable representating an array
114 | self.env["chef_block"] = (
115 | indent_block
116 | + block_name
117 | + " "
118 | + self.env["resource_name"]
119 | + each_do_end
120 | )
121 | else:
122 | self.env["chef_block"] = (
123 | indent_block
124 | + block_name
125 | + " "
126 | + self.env["resource_name"]
127 | + " do\n"
128 | )
129 | else:
130 | for resource_name in self.env["resource_name"].split(","):
131 | self.env["chef_block"] += " %s,\n" % resource_name
132 | self.env["chef_block"] += "]" + each_do_end
133 | # Remove trailing comma
134 | self.env["chef_block"] = self.env["chef_block"].replace(",\n]", "\n]")
135 | self.env["chef_block"] += "%s %s do\n" % (block_name, name)
136 | # Insert an extra tab before everything
137 | extra_formatting = " "
138 | end_text = indent_block + "end\n"
139 |
140 | input_list = sorted(self.input_variables.keys())
141 | # Start the block
142 | # Remove the indentation keys
143 | try:
144 | input_list.remove("%sextra_indentation" % prefix)
145 | input_list.remove("%sindentation_end" % prefix)
146 | except ValueError:
147 | pass
148 | # Place not_if guards first
149 | if self.env.get("%snot_if" % prefix):
150 | self.env["chef_block"] += "%s %s %s\n" % (
151 | extra_formatting,
152 | notif_text,
153 | self.env["%snot_if" % prefix],
154 | )
155 | input_list.remove("%snot_if" % prefix)
156 | # Place only_if guards next
157 | if self.env.get("%sonly_if" % prefix):
158 | self.env["chef_block"] += "%s %s %s\n" % (
159 | extra_formatting,
160 | onlyif_text,
161 | self.env["%sonly_if" % prefix],
162 | )
163 | input_list.remove("%sonly_if" % prefix)
164 | # Remove the special keys
165 | try:
166 | input_list.remove("%sresource_array" % prefix)
167 | input_list.remove("resource_name")
168 | except ValueError:
169 | pass
170 | # Loop through all remaining keys
171 | for key in input_list:
172 | if self.env.get(key, ""):
173 | key_text = "%s" % key.replace("%s" % prefix, "")
174 | self.env["chef_block"] += "%s %s %s\n" % (
175 | extra_formatting,
176 | key_text,
177 | self.env[key],
178 | )
179 | # Clear out the key so it doesn't poison future runs
180 | self.env[key] = ""
181 | # end it
182 | self.env["chef_block"] += end_text
183 | self.output("Chef block:\n%s" % self.env["chef_block"])
184 | # Clean up the keys that weren't iterated through
185 | self.env["%sextra_indentation" % prefix] = ""
186 | self.env["%sindentation_end" % prefix] = ""
187 | self.env["%snot_if" % prefix] = ""
188 | self.env["%sonly_if" % prefix] = ""
189 |
190 |
191 | if __name__ == "__main__":
192 | PROCESSOR = ChefRemotePackage()
193 | PROCESSOR.execute_shell()
194 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefMacOSXUserDefaults.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for ChefMacOSXUserDefaults class."""
9 |
10 | from __future__ import absolute_import
11 |
12 | from autopkglib import Processor
13 |
14 | __all__ = ["ChefMacOSXUserDefaults"]
15 |
16 |
17 | class ChefMacOSXUserDefaults(Processor):
18 | description = (
19 | "Produces a mac_os_x_user_defaults Chef block. See README in mac_os_x."
20 | )
21 | input_variables = {
22 | "resource_name": {
23 | "required": True,
24 | "description": (
25 | "Name for the resource. This can be a single "
26 | "string or an array of strings. If an array is "
27 | "provided, the first item in the array will be the "
28 | "resource name and the rest will be turned "
29 | "into an array."
30 | ),
31 | },
32 | "userdefaults_resource_array": {
33 | "required": False,
34 | "description": "Does the resource_name represent an array variable?",
35 | },
36 | "userdefaults_action": {
37 | "required": False,
38 | "description": "Resource action. Only action allowed is :write.",
39 | },
40 | "userdefaults_domain": {"required": True, "description": "Domain to write."},
41 | "userdefaults_global": {
42 | "required": False,
43 | "description": "Bool for global domain.",
44 | },
45 | "userdefaults_current_host": {
46 | "required": False,
47 | "description": "Bool for current host.",
48 | },
49 | "userdefaults_key": {"required": True, "description": "Key to write to."},
50 | "userdefaults_value": {
51 | "required": True,
52 | "description": "Value to write to key.",
53 | },
54 | "userdefaults_type": {
55 | "required": False,
56 | "description": ("Type of key to write."),
57 | },
58 | "userdefaults_user": {"required": False, "description": ("User to write to.")},
59 | "userdefaults_sudo": {
60 | "required": False,
61 | "description": ("Bool to use sudo or not."),
62 | },
63 | "userdefaults_is_set": {
64 | "required": False,
65 | "description": ("Bool to determine if is set or not."),
66 | },
67 | "userdefaults_only_if": {
68 | "required": False,
69 | "description": "only_if guard phrase.",
70 | },
71 | "userdefaults_not_if": {
72 | "required": False,
73 | "description": "not_if guard phrase.",
74 | },
75 | "userdefaults_extra_indentation": {
76 | "required": False,
77 | "description": "Indent this block. Defaults to empty.",
78 | },
79 | "userdefaults_indentation_end": {
80 | "required": False,
81 | "description": "Should this end an indented section? Defaults to empty.",
82 | },
83 | }
84 | output_variables = {"chef_block": {"description": "Chef block."}}
85 |
86 | __doc__ = description
87 |
88 | def main(self):
89 | # chef block variables
90 | prefix = "userdefaults_"
91 | block_name = "mac_os_x_userdefaults"
92 |
93 | # formatting variables
94 | extra_formatting = ""
95 | end_text = "end\n"
96 | self.env["chef_block"] = ""
97 | each_do_beginning = "[\n"
98 | each_do_end = ".each do |item|\n"
99 | self.env["chef_block"] = each_do_beginning
100 | name = "item"
101 | notif_text = "not_if"
102 | onlyif_text = "only_if"
103 | indent_block = ""
104 |
105 | # Should this block be indented?
106 | if self.env.get("%sextra_indentation" % prefix):
107 | self.output("Adding indentation.")
108 | indent_block = " "
109 | end_text = " " + end_text
110 | extra_formatting = " "
111 | # Should this end an indented block?
112 | if self.env.get("%sindentation_end" % prefix):
113 | end_text = end_text + "end\n"
114 |
115 | # Check to see if only one item was passed
116 | if len(self.env["resource_name"].split(",")) == 1:
117 | if self.env.get("%sresource_array" % prefix):
118 | # it's a node variable representating an array
119 | self.env["chef_block"] = (
120 | indent_block
121 | + block_name
122 | + " "
123 | + self.env["resource_name"]
124 | + each_do_end
125 | )
126 | else:
127 | self.env["chef_block"] = (
128 | indent_block
129 | + block_name
130 | + " "
131 | + self.env["resource_name"]
132 | + " do\n"
133 | )
134 | else:
135 | for resource_name in self.env["resource_name"].split(","):
136 | self.env["chef_block"] += " %s,\n" % resource_name
137 | self.env["chef_block"] += "]" + each_do_end
138 | # Remove trailing comma
139 | self.env["chef_block"] = self.env["chef_block"].replace(",\n]", "\n]")
140 | self.env["chef_block"] += "%s %s do\n" % (block_name, name)
141 | # Insert an extra tab before everything
142 | extra_formatting = " "
143 | end_text = indent_block + "end\n\n"
144 |
145 | input_list = sorted(self.input_variables.keys())
146 | # Start the block
147 | # Remove the indentation keys
148 | input_list.remove("%sextra_indentation" % prefix)
149 | input_list.remove("%sindentation_end" % prefix)
150 | # Place not_if guards first
151 | if self.env.get("%snot_if" % prefix):
152 | self.env["chef_block"] += "%s %s %s\n" % (
153 | extra_formatting,
154 | notif_text,
155 | self.env["%snot_if" % prefix],
156 | )
157 | input_list.remove("%snot_if" % prefix)
158 | # Place only_if guards next
159 | if self.env.get("%sonly_if" % prefix):
160 | self.env["chef_block"] += "%s %s %s\n" % (
161 | extra_formatting,
162 | onlyif_text,
163 | self.env["%sonly_if" % prefix],
164 | )
165 | input_list.remove("%sonly_if" % prefix)
166 | # Remove the special keys
167 | input_list.remove("%sresource_array" % prefix)
168 | input_list.remove("resource_name")
169 | # Loop through all remaining keys
170 | for key in input_list:
171 | if self.env.get(key, ""):
172 | key_text = "%s" % key.replace("%s" % prefix, "")
173 | self.env["chef_block"] += "%s %s %s\n" % (
174 | extra_formatting,
175 | key_text,
176 | self.env[key],
177 | )
178 | # Clear out the key so it doesn't poison future runs
179 | self.env[key] = ""
180 | # end it
181 | self.env["chef_block"] += end_text + "\n"
182 | self.output("Chef block:\n%s" % self.env["chef_block"])
183 | # Clean up the keys that weren't iterated through
184 | self.env["%sextra_indentation" % prefix] = ""
185 | self.env["%sindentation_end" % prefix] = ""
186 | self.env["%snot_if" % prefix] = ""
187 | self.env["%sonly_if" % prefix] = ""
188 |
189 |
190 | if __name__ == "__main__":
191 | PROCESSOR = ChefMacOSXUserDefaults()
192 | PROCESSOR.execute_shell()
193 |
--------------------------------------------------------------------------------
/Chef_Processors/ChefRemoteDirectory.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) Facebook, Inc. and its affiliates.
5 | #
6 | # This source code is licensed under the BSD-style license found in the
7 | # LICENSE file in the root directory of this source tree.#
8 | """See docstring for ChefRemoteDirectory class."""
9 |
10 | from __future__ import absolute_import
11 |
12 | from autopkglib import Processor
13 |
14 | __all__ = ["ChefRemoteDirectory"]
15 |
16 |
17 | class ChefRemoteDirectory(Processor):
18 | description = (
19 | "Produces a remote_directory Chef block. See "
20 | "https://docs.chef.io/resource_remote_directory.html."
21 | )
22 | input_variables = {
23 | "resource_name": {
24 | "required": True,
25 | "description": (
26 | "Name for the resource. This can be a single "
27 | "string or an array of strings. If an array is "
28 | "provided, the first item in the array will be the "
29 | "resource name and the rest will be turned "
30 | "into an array."
31 | ),
32 | },
33 | "action": {
34 | "required": False,
35 | "description": "Resource action. See documentation.",
36 | },
37 | "cookbook": {
38 | "required": False,
39 | "description": "The cookbook in which a file is located.",
40 | },
41 | "files_backup": {
42 | "required": False,
43 | "description": (
44 | "The number of backup copies to keep for files in the directory."
45 | ),
46 | },
47 | "files_group": {
48 | "required": False,
49 | "description": (
50 | "Configure group permissions for files. A string or ID "
51 | "that identifies the group owner by group name."
52 | ),
53 | },
54 | "files_mode": {"required": False, "description": "The octal mode for a file."},
55 | "files_owner": {
56 | "required": False,
57 | "description": (
58 | "Configure owner permissions for files. A string or ID "
59 | "that identifies the group owner by group name."
60 | ),
61 | },
62 | "group": {
63 | "required": False,
64 | "description": "Use to configure permissions for directories.",
65 | },
66 | "ignore_failure": {
67 | "required": False,
68 | "description": (
69 | "Continue running a recipe if a resource fails for any reason."
70 | ),
71 | },
72 | "inherits": {
73 | "required": False,
74 | "description": (
75 | "Windows only. Whether a file inherits rights from "
76 | "its parent directory."
77 | ),
78 | },
79 | "mode": {
80 | "required": False,
81 | "description": (
82 | "A quoted 3-5 character string that defines the octal mode."
83 | ),
84 | },
85 | "notifies": {
86 | "required": False,
87 | "description": (
88 | "Which resource takes action when this resource's state changes."
89 | ),
90 | },
91 | "overwrite": {
92 | "required": False,
93 | "description": "Overwrite a file when it is different.",
94 | },
95 | "owner": {
96 | "required": False,
97 | "description": "Use to configure permissions for directories.",
98 | },
99 | "path": {"required": False, "description": "The path to the directory."},
100 | "provider": {
101 | "required": False,
102 | "description": "Optional. Explicitly specify a provider.",
103 | },
104 | "purge": {
105 | "required": False,
106 | "description": "Purge extra files found in the target directory.",
107 | },
108 | "recursive": {
109 | "required": False,
110 | "description": "Create or delete directories recursively.",
111 | },
112 | "retries": {
113 | "required": False,
114 | "description": (
115 | "The number of times to catch exceptions and retry the resource."
116 | ),
117 | },
118 | "retry_delay": {
119 | "required": False,
120 | "description": "The retry delay (in seconds).",
121 | },
122 | "rights": {
123 | "required": False,
124 | "description": (
125 | "Microsoft Windows only. The permissions for users and "
126 | "groups in a Microsoft Windows environment."
127 | ),
128 | },
129 | "source": {
130 | "required": True,
131 | "description": "The base name of the source file.",
132 | },
133 | "subscribes": {
134 | "required": False,
135 | "description": (
136 | "Specify that this resource is to listen to another "
137 | "resource, and then take action when that resource's "
138 | "state changes.."
139 | ),
140 | },
141 | "only_if": {"required": False, "description": "only_if guard phrase."},
142 | "not_if": {"required": False, "description": "not_if guard phrase."},
143 | }
144 | output_variables = {"chef_block": {"description": "Chef block."}}
145 |
146 | __doc__ = description
147 |
148 | def main(self):
149 | extra_formatting = ""
150 | block_name = "remote_directory"
151 | self.env["remote_directory"] = ""
152 | if not isinstance(self.env["chef_block"], basestring):
153 | # Not a string, assume it's an array of strings
154 | each_do_beginning = "[\n"
155 | each_do_end = "].each do |item|\n\t"
156 | self.env["remote_directory"] = each_do_beginning
157 | for resource_name in self.env["chef_block"]:
158 | self.env["remote_directory"] += "\t%s,\n" % resource_name
159 | self.env["remote_directory"] += each_do_end
160 | name = "item"
161 | # insert an extra tab before everything
162 | extra_formatting = "\t"
163 | end_text = "\tend\nend\n\n"
164 | else:
165 | name = self.env["chef_block"]
166 | notif_text = "\tnot_if"
167 | onlyif_text = "\tonly_if"
168 |
169 | input_list = sorted(self.input_variables.keys())
170 | # Start the block
171 | self.env["remote_directory"] += "%s %s do\n" % (block_name, name)
172 | # Place not_if guards first
173 | if self.env.get("not_if"):
174 | self.env["remote_directory"] += "%s\t%s %s\n" % (
175 | extra_formatting,
176 | notif_text,
177 | self.env["not_if"],
178 | )
179 | input_list.remove("not_if")
180 | # Place only_if guards next
181 | if self.env.get("only_if"):
182 | self.env["remote_directory"] += "%s\t%s %s\n" % (
183 | extra_formatting,
184 | onlyif_text,
185 | self.env["only_if"],
186 | )
187 | input_list.remove("only_if")
188 | input_list.remove("resource_name")
189 | # Loop through all keys
190 | for key in input_list:
191 | if self.env.get(key, ""):
192 | key_text = "\t%s" % key
193 | self.env["remote_directory"] += "%s\t%s %s\n" % (
194 | extra_formatting,
195 | key_text,
196 | self.env[key],
197 | )
198 | # clear out the key so it doesn't poison future runs
199 | self.env[key] = ""
200 | # end it
201 | self.env["remote_directory"] += end_text
202 | self.output("Chef block:\n%s" % self.env["remote_directory"])
203 |
204 |
205 | if __name__ == "__main__":
206 | PROCESSOR = ChefRemoteDirectory()
207 | PROCESSOR.execute_shell()
208 |
--------------------------------------------------------------------------------