Merge lp:~bcsaller/pyjuju/lxc-killpid into lp:pyjuju

Proposed by Benjamin Saller
Status: Work in progress
Proposed branch: lp:~bcsaller/pyjuju/lxc-killpid
Merge into: lp:pyjuju
Diff against target: 122 lines (+17/-28)
3 files modified
juju/lib/service.py (+10/-17)
juju/providers/local/__init__.py (+2/-1)
juju/providers/local/agent.py (+5/-10)
To merge this branch: bzr merge lp:~bcsaller/pyjuju/lxc-killpid
Reviewer Review Type Date Requested Status
Kapil Thangavelu (community) Needs Fixing
Review via email: mp+120497@code.launchpad.net

Description of the change

Properly destroy local provider environment

Stop using temp dir to hold pid
Properly pass juju-directory on destory-environment

https://codereview.appspot.com/6460118/

To post a comment you must log in.
Revision history for this message
Benjamin Saller (bcsaller) wrote :
Download full text (4.6 KiB)

Reviewers: mp+120497_code.launchpad.net,

Message:
Please take a look.

Description:
Properly destroy local provider environment

Stop using temp dir to hold pid
Properly pass juju-directory on destory-environment

https://code.launchpad.net/~bcsaller/juju/lxc-killpid/+merge/120497

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/6460118/

Affected files:
   A [revision details]
   M juju/lib/service.py
   M juju/providers/local/__init__.py
   M juju/providers/local/agent.py

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>

Index: juju/lib/service.py
=== modified file 'juju/lib/service.py'
--- juju/lib/service.py 2012-08-03 12:28:29 +0000
+++ juju/lib/service.py 2012-08-21 04:52:21 +0000
@@ -8,14 +8,18 @@

  def _check_call(args, env=None, output_path=None):
- if not output_path:
- output_path = os.devnull
+ if not output_path or not os.access(output_path, os.W_OK):
+ f = open(os.devnull, "a")
+ else:
+ f = open(output_path, "a")

- with open(output_path, "a") as f:
+ try:
          return subprocess.check_call(
              args,
              stdout=f.fileno(), stderr=f.fileno(),
              env=env)
+ finally:
+ f.close()

  def _cat(filename, use_sudo=False):
@@ -43,20 +47,11 @@
          self._description = None
          self._environ = None
          self._command = None
- self._output_path = None
+ self.output_path = None

          self._pid_path = pidfile
          self._pid = None

- @property
- def output_path(self):
- if self._output_path is not None:
- return self._output_path
- return "/tmp/%s.output" % self._name
-
- @output_path.setter
- def output_path(self, path):
- self._output_path = path

      def set_description(self, description):
          self._description = description
@@ -78,7 +73,7 @@

      @inlineCallbacks
      def _trash_output(self):
- if os.path.exists(self.output_path):
+ if self.output_path and os.path.exists(self.output_path):
              # Just using os.unlink will fail when we're running TEST_SUDO
              # tests which hit this code path (because root will own
              # self.output_path)
@@ -115,14 +110,12 @@
      def destroy(self):
          if (yield self.is_running()):
              yield self._call("kill", self.get_pid())
- yield self._trash_output()
+ yield self._trash_output()

      def get_pid(self):
          if self._pid != None:
              return self._pid

- if not os.path.exists(self._pid_path):
- return None
          r, data = _cat(self._pid_path, use_sudo=self._use_sudo)
          if r != 0:
              return None

Index: juju/providers/local/__init__.py
=== modified file 'juju/providers/local/__init__.py'
--- juju/providers/local/__init__.py 2012-07-20 17:28:17 +0000
+++ juju/providers/local/__in...

Read more...

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

On 2012/08/21 05:00:11, bcsaller wrote:
> Please take a look.

this was one of the original review items of the previous branch.
https://codereview.appspot.com/6404052/patch/2001/3004

in general please wait till the branch is actually marked approved
instead of relying on +1/lgtm in a review before merging.

https://codereview.appspot.com/6460118/

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

https://codereview.appspot.com/6460118/diff/1/juju/lib/service.py
File juju/lib/service.py (right):

https://codereview.appspot.com/6460118/diff/1/juju/lib/service.py#newcode112
juju/lib/service.py:112: yield self._call("kill", self.get_pid())
having seen wrap-around pid behavior where this refers to an entirely
different process, this makes me wary.

https://codereview.appspot.com/6460118/diff/1/juju/lib/service.py#newcode118
juju/lib/service.py:118:
what happens to the stop/destroy case if the pidfile doesn't exist?

https://codereview.appspot.com/6460118/

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

this implementation never quite worked for non global installation of libraries, as it passes env vars via a dict with sudo -e, which won't work for pythonpath. See the original implementation in the file history, the env vars must be passed on the cli, not via process env.

review: Needs Fixing
Revision history for this message
Kapil Thangavelu (hazmat) wrote :

i'm taking over this branch since it seems to have been abandoned and it should get merged for the next released. i found and fixed a half-dozen issues with it, lots of hardcoded path/ports, broken behavior wrt to env vars, invalid checks for file access, etc.

Unmerged revisions

564. By Benjamin Saller

properly kill daemons, properly pass juju_dir on destroy-environment/container destruction

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'juju/lib/service.py'
--- juju/lib/service.py 2012-08-03 12:28:29 +0000
+++ juju/lib/service.py 2012-08-21 05:01:09 +0000
@@ -8,14 +8,18 @@
88
99
10def _check_call(args, env=None, output_path=None):10def _check_call(args, env=None, output_path=None):
11 if not output_path:11 if not output_path or not os.access(output_path, os.W_OK):
12 output_path = os.devnull12 f = open(os.devnull, "a")
13 else:
14 f = open(output_path, "a")
1315
14 with open(output_path, "a") as f:16 try:
15 return subprocess.check_call(17 return subprocess.check_call(
16 args,18 args,
17 stdout=f.fileno(), stderr=f.fileno(),19 stdout=f.fileno(), stderr=f.fileno(),
18 env=env)20 env=env)
21 finally:
22 f.close()
1923
2024
21def _cat(filename, use_sudo=False):25def _cat(filename, use_sudo=False):
@@ -43,20 +47,11 @@
43 self._description = None47 self._description = None
44 self._environ = None48 self._environ = None
45 self._command = None49 self._command = None
46 self._output_path = None50 self.output_path = None
4751
48 self._pid_path = pidfile52 self._pid_path = pidfile
49 self._pid = None53 self._pid = None
5054
51 @property
52 def output_path(self):
53 if self._output_path is not None:
54 return self._output_path
55 return "/tmp/%s.output" % self._name
56
57 @output_path.setter
58 def output_path(self, path):
59 self._output_path = path
6055
61 def set_description(self, description):56 def set_description(self, description):
62 self._description = description57 self._description = description
@@ -78,7 +73,7 @@
7873
79 @inlineCallbacks74 @inlineCallbacks
80 def _trash_output(self):75 def _trash_output(self):
81 if os.path.exists(self.output_path):76 if self.output_path and os.path.exists(self.output_path):
82 # Just using os.unlink will fail when we're running TEST_SUDO77 # Just using os.unlink will fail when we're running TEST_SUDO
83 # tests which hit this code path (because root will own78 # tests which hit this code path (because root will own
84 # self.output_path)79 # self.output_path)
@@ -115,14 +110,12 @@
115 def destroy(self):110 def destroy(self):
116 if (yield self.is_running()):111 if (yield self.is_running()):
117 yield self._call("kill", self.get_pid())112 yield self._call("kill", self.get_pid())
118 yield self._trash_output()113 yield self._trash_output()
119114
120 def get_pid(self):115 def get_pid(self):
121 if self._pid != None:116 if self._pid != None:
122 return self._pid117 return self._pid
123118
124 if not os.path.exists(self._pid_path):
125 return None
126 r, data = _cat(self._pid_path, use_sudo=self._use_sudo)119 r, data = _cat(self._pid_path, use_sudo=self._use_sudo)
127 if r != 0:120 if r != 0:
128 return None121 return None
129122
=== modified file 'juju/providers/local/__init__.py'
--- juju/providers/local/__init__.py 2012-07-20 17:28:17 +0000
+++ juju/providers/local/__init__.py 2012-08-21 05:01:09 +0000
@@ -172,7 +172,8 @@
172172
173 # Stop the machine agent173 # Stop the machine agent
174 log.debug("Stopping machine agent...")174 log.debug("Stopping machine agent...")
175 agent = ManagedMachineAgent(self._qualified_name)175 agent = ManagedMachineAgent(self._qualified_name,
176 juju_directory=self._directory)
176 yield agent.stop()177 yield agent.stop()
177178
178 # Stop the storage server179 # Stop the storage server
179180
=== modified file 'juju/providers/local/agent.py'
--- juju/providers/local/agent.py 2012-08-03 10:55:21 +0000
+++ juju/providers/local/agent.py 2012-08-21 05:01:09 +0000
@@ -1,18 +1,10 @@
1import os
1import sys2import sys
2import tempfile
33
4from juju.lib.service import TwistedDaemonService4from juju.lib.service import TwistedDaemonService
5from juju.providers.common.cloudinit import get_default_origin, BRANCH5from juju.providers.common.cloudinit import get_default_origin, BRANCH
66
77
8def get_temp_filename(basename):
9 if basename:
10 basename += "-"
11
12 fd, fn = tempfile.mkstemp(prefix=basename, suffix=".pid")
13 return fn
14
15
16class ManagedMachineAgent(object):8class ManagedMachineAgent(object):
179
18 agent_module = "juju.agents.machine"10 agent_module = "juju.agents.machine"
@@ -51,7 +43,10 @@
51 if public_key:43 if public_key:
52 env["JUJU_PUBLIC_KEY"] = public_key44 env["JUJU_PUBLIC_KEY"] = public_key
5345
54 pidfile = get_temp_filename(juju_unit_namespace)46 pidfile = os.path.join(juju_directory,
47 "%s-machine-agent.pid" % (
48 juju_unit_namespace))
49
55 self._service = TwistedDaemonService(50 self._service = TwistedDaemonService(
56 "juju-%s-machine-agent" % juju_unit_namespace,51 "juju-%s-machine-agent" % juju_unit_namespace,
57 pidfile,52 pidfile,

Subscribers

People subscribed via source and target branches

to status/vote changes: