Fix salt-call using RAET on Windows

salt/cli/caller.py:
- Avoid picking RAETCaller on Windows. Since no state from RAETCaller
is needed in the spawned child process, simply moved the child process
entry function outside of RAETCaller.
- Added Windows specific logic to detect if the lane is set up. We need
to use win32file.CreateFile for detection since Windows lanes don't use
regular files.

salt/transport/raet.py:
- Fixed obvious bugs that would cause this functionality to not work in
any OS.

Signed-off-by: Sergey Kizunov <sergey.kizunov@ni.com>
This commit is contained in:
Sergey Kizunov 2015-05-04 10:22:00 -05:00
parent b224d823eb
commit b0e7f590b5
2 changed files with 40 additions and 11 deletions

View file

@ -24,6 +24,7 @@ import salt.utils.args
import salt.utils.jid
import salt.defaults.exitcodes
from salt.log import LOG_LEVELS
from salt.utils import is_windows
from salt.utils import print_cli
from salt.utils import kinds
from salt.cli import daemons
@ -33,6 +34,9 @@ try:
from raet.lane.stacking import LaneStack
from raet.lane.yarding import RemoteYard, Yard
if is_windows():
import win32file
except ImportError:
# Don't die on missing transport libs since only one transport is required
pass
@ -264,6 +268,16 @@ class ZeroMQCaller(BaseCaller):
channel.send(load)
def raet_minion_run(cleanup_protecteds):
'''
Set up the minion caller. Should be run in its own process.
This function is intentionally left out of RAETCaller. This will avoid
needing to pickle the RAETCaller object on Windows.
'''
minion = daemons.Minion() # daemonizes here
minion.call(cleanup_protecteds=cleanup_protecteds) # caller minion.call_in uses caller.flo
class RAETCaller(BaseCaller):
'''
Object to wrap the calling of local salt modules for the salt-call command
@ -301,7 +315,7 @@ class RAETCaller(BaseCaller):
if (opts.get('__role') ==
kinds.APPL_KIND_NAMES[kinds.applKinds.caller]):
# spin up and fork minion here
self.process = multiprocessing.Process(target=self.minion_run,
self.process = multiprocessing.Process(target=raet_minion_run,
kwargs={'cleanup_protecteds': [self.stack.ha], })
self.process.start()
# wait here until '/var/run/salt/minion/alpha_caller.manor.uxd' exists
@ -309,10 +323,6 @@ class RAETCaller(BaseCaller):
super(RAETCaller, self).__init__(opts)
def minion_run(self, cleanup_protecteds):
minion = daemons.Minion() # daemonizes here
minion.call(cleanup_protecteds=cleanup_protecteds) # caller minion.call_in uses caller.flo
def run(self):
'''
Execute the salt call logic
@ -408,8 +418,27 @@ class RAETCaller(BaseCaller):
ha, dirpath = Yard.computeHa(dirpath, lanename, yardname)
while not ((os.path.exists(ha) and
not os.path.isfile(ha) and
not os.path.isdir(ha))):
time.sleep(0.1)
if is_windows():
# RAET lanes do not use files on Windows. Need to use win32file
# API to check for existence.
exists = False
while not exists:
try:
f = win32file.CreateFile(
ha,
win32file.GENERIC_WRITE | win32file.GENERIC_READ,
win32file.FILE_SHARE_READ,
None,
win32file.OPEN_EXISTING,
0,
None)
win32file.CloseHandle(f)
exists = True
except win32file.error:
time.sleep(0.1)
else:
while not ((os.path.exists(ha) and
not os.path.isfile(ha) and
not os.path.isdir(ha))):
time.sleep(0.1)
time.sleep(0.5)

View file

@ -99,7 +99,7 @@ class RAETReqChannel(ReqChannel):
if kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.master],
kinds.APPL_KIND_NAMES[kinds.applKinds.syndic]]:
lanename = 'master'
elif kind == [kinds.APPL_KIND_NAMES[kinds.applKinds.minion],
elif kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.minion],
kinds.APPL_KIND_NAMES[kinds.applKinds.caller]]:
lanename = "{0}_{1}".format(role, kind)
else:
@ -112,7 +112,7 @@ class RAETReqChannel(ReqChannel):
lanename=lanename,
sockdirpath=self.opts['sock_dir'])
stack.Pk = raeting.packKinds.pack
stack.Pk = raeting.PackKind.pack
stack.addRemote(RemoteYard(stack=stack,
name=ryn,
lanename=lanename,