11import sh
22import os
3+ import json
34
45__version__ = '0.0.1'
56
@@ -27,9 +28,6 @@ def __init__(self, packerfile, exc=None, only=None, vars=None,
2728 self .exc = self ._validate_argtype (exc if exc else [], list )
2829 self .only = self ._validate_argtype (only if only else [], list )
2930 self .vars = self ._validate_argtype (vars if vars else {}, dict )
30- if not os .path .isfile (self .packerfile ):
31- raise OSError ('packerfile not found at path: {0}' .format (
32- self .packerfile ))
3331 self .packer = sh .Command (exec_path )
3432
3533 def build (self , parallel = True , debug = False , force = False ):
@@ -39,23 +37,26 @@ def build(self, parallel=True, debug=False, force=False):
3937 :param bool debug: Run in debug mode
4038 :param bool force: Force artifact output even if exists
4139 """
42- cmd = self .packer .build
43- cmd = self ._add_opt (cmd , '-parallel=true' if parallel else None )
44- cmd = self ._add_opt (cmd , '-debug' if debug else None )
45- cmd = self ._add_opt (cmd , '-force' if force else None )
46- cmd = self ._append_base_arguments (cmd )
47- cmd = cmd . bake (self .packerfile )
48- return cmd ()
40+ self . ccmd = self .packer .build
41+ self ._add_opt ('-parallel=true' if parallel else None )
42+ self ._add_opt ('-debug' if debug else None )
43+ self ._add_opt ('-force' if force else None )
44+ self ._append_base_arguments ()
45+ self . _add_opt (self .packerfile )
46+ return self . ccmd ()
4947
5048 def fix (self , to_file = None ):
5149 """Implements the `packer fix` function
50+
51+ :param string to_file: File to output fixed template to
5252 """
53- cmd = self .packer .fix
54- cmd = cmd . bake (self .packerfile )
55- result = cmd ()
53+ self . ccmd = self .packer .fix
54+ self . _add_opt (self .packerfile )
55+ result = self . ccmd ()
5656 if to_file :
5757 with open (to_file , 'w' ) as f :
5858 f .write (result .stdout )
59+ result .fixed = json .loads (result .stdout )
5960 return result
6061
6162 def inspect (self , mrf = True ):
@@ -85,12 +86,12 @@ def inspect(self, mrf=True):
8586 "name": "amazon"
8687 }
8788 ]
88- :param bool machine_readable : output in machine-readable form.
89+ :param bool mrf : output in machine-readable form.
8990 """
90- cmd = self .packer .inspect
91- cmd = self ._add_opt (cmd , '-machine-readable' if mrf else None )
92- cmd = cmd . bake (self .packerfile )
93- result = cmd ()
91+ self . ccmd = self .packer .inspect
92+ self ._add_opt ('-machine-readable' if mrf else None )
93+ self . _add_opt (self .packerfile )
94+ result = self . ccmd ()
9495 if mrf :
9596 result .parsed_output = self ._parse_inspection_output (
9697 result .stdout )
@@ -99,15 +100,13 @@ def inspect(self, mrf=True):
99100 def push (self , create = True , token = False ):
100101 """Implmenets the `packer push` function
101102
102- UNTESTED!
103+ UNTESTED! Must be used alongside an Atlas account
103104 """
104- command = self .packer .push
105- if create :
106- command = command .bake ('-create=true' )
107- if token :
108- command = command .bake ('-token={0}' .format (token ))
109- command = command .bake (self .packerfile )
110- return command ()
105+ self .ccmd = self .packer .push
106+ self ._add_opt ('-create=true' if create else None )
107+ self ._add_opt ('-tokn={0}' .format (token ) if token else None )
108+ self ._add_opt (self .packerfile )
109+ return self .ccmd ()
111110
112111 def validate (self , syntax_only = False ):
113112 """Validates a Packer Template file (`packer validate`)
@@ -116,15 +115,23 @@ def validate(self, syntax_only=False):
116115 :param bool syntax_only: Whether to validate the syntax only
117116 without validating the configuration itself.
118117 """
119- command = self .packer .validate
120- if syntax_only :
121- command = command .bake ('-syntax-only' )
122- command = self ._append_base_arguments (command )
123- command = command .bake (self .packerfile )
124- return command ()
125- # err.. need to return normal values with validation result
126- # validated.succeeded = True if validated.exit_code == 0 else False
127- # validated.failed = not validated.succeeded
118+ self .ccmd = self .packer .validate
119+ self ._add_opt ('-syntax-only' if syntax_only else None )
120+ self ._append_base_arguments ()
121+ self ._add_opt (self .packerfile )
122+ # as sh raises an exception rather than return a value when execution
123+ # fails we create an object to return the exception and the validation
124+ # state
125+ try :
126+ validation = self .ccmd ()
127+ validation .succeeded = True if validation .exit_code == 0 else False
128+ validation .error = None
129+ except Exception as ex :
130+ validation = ValidationObject ()
131+ validation .succeeded = False
132+ validation .failed = True
133+ validation .error = ex .message
134+ return validation
128135
129136 def version (self ):
130137 """Returns Packer's version number (`packer version`)
@@ -136,18 +143,17 @@ def version(self):
136143 """
137144 return self .packer .version ().split ('v' )[1 ].rstrip ('\n ' )
138145
139- def _add_opt (self , command , option ):
146+ def _add_opt (self , option ):
140147 if option :
141- return command .bake (option )
142- return command
148+ self .ccmd = self .ccmd .bake (option )
143149
144150 def _validate_argtype (self , arg , argtype ):
145151 if not isinstance (arg , argtype ):
146152 raise PackerException ('{0} argument must be of type {1}' .format (
147153 arg , argtype ))
148154 return arg
149155
150- def _append_base_arguments (self , command ):
156+ def _append_base_arguments (self ):
151157 """Appends base arguments to packer commands.
152158
153159 -except, -only, -var and -vars-file are appeneded to almost
@@ -157,14 +163,13 @@ def _append_base_arguments(self, command):
157163 if self .exc and self .only :
158164 raise PackerException ('Cannot provide both "except" and "only"' )
159165 elif self .exc :
160- command = command . bake ('-except={0}' .format (self ._joinc (self .exc )))
166+ self . _add_opt ('-except={0}' .format (self ._joinc (self .exc )))
161167 elif self .only :
162- command = command . bake ('-only={0}' .format (self ._joinc (self .only )))
168+ self . _add_opt ('-only={0}' .format (self ._joinc (self .only )))
163169 for var , value in self .vars .items ():
164- command = command . bake ("-var '{0}={1}'" .format (var , value ))
170+ self . _add_opt ("-var '{0}={1}'" .format (var , value ))
165171 if self .vars_file :
166- command = command .bake ('-vars-file={0}' .format (self .vars_file ))
167- return command
172+ self ._add_opt ('-vars-file={0}' .format (self .vars_file ))
168173
169174 def _joinc (self , lst ):
170175 """Returns a comma delimited string from a list"""
@@ -198,5 +203,14 @@ def _parse_inspection_output(self, output):
198203 return parts
199204
200205
206+ # class Install():
207+ # def __init__(self):
208+ # self.installer_path = os.environ['PACKER_INSTALLER_PATH']
209+
210+
211+ class ValidationObject ():
212+ pass
213+
214+
201215class PackerException (Exception ):
202216 pass
0 commit comments