On Static Verification of Puppet System Configurations

Puppet is a configuration management system used by hundreds of organizations to manage thousands of machines. It is designed to automate tasks such as application configuration, service orchestration, VM provisioning, and more. The heart of Puppet is a declarative domain-specific language that specifies a collection of resources (packages, user accounts, files, etc.), their desired state (e.g., installed or not installed), and the dependencies between them. Although Puppet performs some static checking, there are many opportunities for errors to occur. Puppet configurations are often underconstrained (to allow them to be composed with each other) and underspecified (to allow them to be applied to a variety of machine states), which makes errors difficult to detect and debug. Even if a configuration is bug-free, when a machine is updated to a new configuration, it is easy for the machine state and its configuration to “drift” apart. In this paper, we identify determinism as the essential property that allows us to reason about configuration correctness and configuration updates. First, we present a sound, complete, and scalable algorithm to verify that configurations are deterministic. Our approach is to encode configurations as logical formulas in an SMT solver and apply partial order reduction and program slicing to achieve scalability. We apply our tool to real-world Puppet configurations gleaned from open-source projects that suffered determinacy bugs. Second, we consider the configuration update problem: a live update from version 1 to version 2 does not have the same effect as applying version 2 to a new machine. By treating configurations as functions—which we can do after we verify that they are deterministic—we build a simple program synthesis tool to calculate an update to version 1 that has the same effect that version 2 would have had on the original machine.

[1]  Paul Anderson,et al.  Towards a High-Level Machine Configuration System , 1994, LISA.

[2]  Rupak Majumdar,et al.  Tools and Algorithms for the Construction and Analysis of Systems , 1997, Lecture Notes in Computer Science.

[3]  Ranjit Jhala,et al.  Deterministic parallelism via liquid effects , 2012, PLDI '12.

[4]  Tom Ridge,et al.  SibylFS: formal specification and oracle-based testing for POSIX and real-world file systems , 2015, SOSP.

[5]  Koushik Sen,et al.  Asserting and checking determinism for multithreaded programs , 2009, ESEC/FSE '09.

[6]  Jeffrey Overbey,et al.  A type and effect system for deterministic parallel Java , 2009, OOPSLA '09.

[7]  Stephen N. Freund,et al.  SingleTrack: A Dynamic Determinism Checker for Multithreaded Programs , 2009, ESOP.

[8]  Carroll Morgan,et al.  Specification of the UNIX Filing System , 1984, IEEE Transactions on Software Engineering.

[9]  Viktor Kuncak,et al.  Verifying a File System Implementation , 2004, ICFEM.

[10]  Benjamin C. Pierce,et al.  Boomerang: resourceful lenses for string data , 2008, POPL '08.

[11]  Rupak Majumdar,et al.  Engage: a deployment management system , 2012, PLDI '12.

[12]  Andres Löh,et al.  NixOS: a purely functional Linux distribution , 2008, ICFP.

[13]  B. Hagemark,et al.  Site: a language and system for configuring many computers as one computer site , 1989 .

[14]  Sanjit A. Seshia,et al.  Combinatorial sketching for finite programs , 2006, ASPLOS XII.

[15]  Vivek Sarkar,et al.  Automatic Verification of Determinism for Structured Parallel Programs , 2010, SAS.

[16]  Sorin Lerner,et al.  OPIUM: Optimal Package Install/Uninstall Manager , 2007, 29th International Conference on Software Engineering (ICSE'07).

[17]  John McCarthy,et al.  Towards a Mathematical Science of Computation , 1962, IFIP Congress.

[18]  K. Rustan M. Leino,et al.  Formalizing and Verifying a Modern Build Language , 2014, FM.

[19]  Philippa Gardner,et al.  Local Reasoning about POSIX File Systems , 2013 .