grim/local-pipelines

f5dcfe140c79
Merged in seanfarley/local-pipelines (pull request #4)

Prevent secret environment variable (e.g. passwords) from being sent via command line
--- a/pipelines/core.py Wed Jul 27 10:05:15 2016 -0500
+++ b/pipelines/core.py Thu Jul 28 13:55:01 2016 -0500
@@ -84,10 +84,6 @@
v = None
if len(kv) > 1:
v = kv[1].strip()
- else:
- # the variable was passed as "-e FOO" so we should grab "FOO" from the
- # environment
- v = os.environ.get(k, "")
return k, v
--- a/pipelines/pipeline.py Wed Jul 27 10:05:15 2016 -0500
+++ b/pipelines/pipeline.py Thu Jul 28 13:55:01 2016 -0500
@@ -30,19 +30,31 @@
self.config = config
self.build_path = os.path.abspath(path)
self.branch = branch
- self.env = env or {}
+ self._env = env or {}
- self.steps = self._get_steps()
-
- def _get_steps(self):
+ @property
+ def steps(self):
+ ret = self.config["pipelines"]["default"]
if "branches" in self.config["pipelines"]:
branches = self.config["pipelines"]["branches"]
for pattern, steps in branches.iteritems():
if fnmatch.fnmatch(self.branch, pattern):
- return steps
+ ret = steps
+ break
+
+ return [Step.from_dict(s["step"]) for s in ret]
- return self.config["pipelines"]["default"]
+ @property
+ def public_env(self):
+ # dict of env vars that are not none
+ return {k: v for k, v in self._env.iteritems() if v is not None}
+
+ @property
+ def private_env(self):
+ # dict of env vars that are none (grabbed from os.environ)
+ return {k: os.environ.get(k, "") for k, v in self._env.iteritems()
+ if v is None}
def _determine_image(self, step):
return step.image or self.config.get("image")
@@ -72,26 +84,28 @@
" ".join(["-v " + v for v in volumes]),
"-w {}".format(workdir),
" ".join(["--label " + l for l in labels]),
- " ".join(["-e " + k + "=" + v for k, v in self.env.iteritems()]),
+ " ".join(["-e {}={}".format(k, v) for k, v in
+ self.public_env.iteritems()]),
+ " ".join(["-e " + k for k in self.private_env.keys()]),
self._determine_image(step),
script,
]
return " ".join(cmd)
- def _steps(self):
- return [Step.from_dict(s["step"]) for s in self.steps]
-
def run(self):
return_code = 0
+ subenv = os.environ.copy()
+ subenv.update(self.private_env)
- for n, step in enumerate(self._steps()):
+ for n, step in enumerate(self.steps):
script = step.script_file()
command = self._get_command(step, script)
try:
print('+ {}'.format(command))
- proc = subprocess.Popen(command.split())
+ proc = subprocess.Popen(command.split(),
+ env=subenv)
return_code = proc.wait()
if return_code != 0: