Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cc-node
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Mirror
cc-node
Commits
cffa3cba
Commit
cffa3cba
authored
12 years ago
by
Anael Beutot
Browse files
Options
Downloads
Patches
Plain Diff
Basics working with libev.
Authentication and host handler.
parent
fc74c9dc
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ccnode/node.py
+121
-112
121 additions, 112 deletions
ccnode/node.py
with
121 additions
and
112 deletions
ccnode/node.py
+
121
−
112
View file @
cffa3cba
import
time
import
signal
import
logging
from
threading
import
Thread
,
Lock
import
logging.config
import
pyev
from
sjrpc.core
import
RpcConnection
from
sjrpc.utils
import
ConnectionProxy
,
RpcHandler
from
ccnode
import
__version__
from
ccnode.config
import
NodeConfigParser
from
ccnode.tags
import
Tag
,
get_tags
...
...
@@ -42,124 +45,130 @@ class DefaultHandler(RpcHandler):
self
.
tags
.
pop
(
tag_name
,
None
)
class
Node
(
Thread
):
"""
Main class for ccnode.
"""
def
__init__
(
self
,
server_host
,
server_port
,
user_name
,
user_passwd
):
"""
:param string server_host: hostname for cc-server
:param int server_port: port for cc-server
:param string user_name: account name for authentication to cc-server
:param string user_passwd: password for cc-server authentication
"""
Thread
.
__init__
(
self
)
# run thread as daemon
self
.
daemon
=
True
# settings used as read only
self
.
server_host
=
server_host
self
.
server_port
=
int
(
server_port
)
self
.
user_name
=
user_name
self
.
user_passwd
=
user_passwd
#: ``sjRpc`` proxy
self
.
proxy
=
None
#: ``sjRpc`` connection
self
.
connection
=
None
#: role returned by cc-server (set to None unless the authentication
#: has succeed)
self
.
role
=
None
self
.
_connection_lock
=
Lock
()
def
init_rpc
(
self
):
"""
Init a new connection to ``cc-server``, create a ``sjRpc`` proxy.
"""
self
.
connection
=
RpcConnection
.
from_addr_ssl
(
addr
=
self
.
server_host
,
port
=
self
.
server_port
,
handler
=
DefaultHandler
(),
class
AuthHandler
(
object
):
"""
Handles rpc authentication to the remote cc-server.
"""
def
__init__
(
self
,
loop
):
self
.
loop
=
loop
self
.
watcher
=
loop
.
loop
.
timer
(.
5
,
5
,
self
.
cb
)
self
.
auth_id
=
None
def
cb
(
self
,
watcher
,
revents
):
logger
.
debug
(
'
Callback auth
'
)
# check is fallback mode on sjrpc is set otherwise our call would block
# the loop
if
not
self
.
loop
.
rpc_con
.
_event_fallback
.
is_set
():
logger
.
debug
(
'
Will try authentication again latter
'
)
return
if
self
.
auth_id
is
not
None
:
logger
.
error
(
'
Authentication is taking longer than expected
'
)
return
# try to authenticate
self
.
auth_id
=
self
.
loop
.
rpc_con
.
rpc
.
async_call_cb
(
self
.
cb_auth
,
'
authentify
'
,
self
.
loop
.
config
.
server_user
,
self
.
loop
.
config
.
server_passwd
,
)
self
.
proxy
=
ConnectionProxy
(
self
.
connection
)
def
authentify
(
self
):
"""
Try to authenticate to the server. If successfull, import and then
set :class:`Handler` corresponding to the role returned by the
``cc-server``.
def
cb_auth
(
self
,
call_id
,
response
=
None
,
error
=
None
):
assert
call_id
==
self
.
auth_id
:raise: exception raised by :func:`proxy.authentify`
"""
try
:
role
=
self
.
proxy
.
authentify
(
self
.
user_name
,
self
.
user_passwd
)
except
Exception
:
logger
.
exception
(
'
Unknow exception while authentifying
'
)
r
aise
if
error
is
not
None
:
# we got an error
logger
.
error
(
'
Error while authenticating with cc-server: %s(
"
%s
"
)
'
,
error
[
'
exception
'
],
error
.
get
(
'
message
'
,
''
)
)
# try to recconnect in 5 seconds
r
eturn
# set handler according to which role was returned by the cc-server
if
r
ol
e
==
u
'
host
'
:
if
r
espons
e
==
u
'
host
'
:
logger
.
debug
(
'
Role host affected
'
)
from
ccnode.host
import
Handler
as
HostHandler
self
.
connecti
on
.
rpc
.
set_handler
(
HostHandler
())
self
.
role
=
u
'
host
'
elif
r
ol
e
==
u
'
hv
'
:
self
.
loop
.
rpc_c
on
.
rpc
.
set_handler
(
HostHandler
())
self
.
loop
.
role
=
u
'
host
'
elif
r
espons
e
==
u
'
hv
'
:
logger
.
debug
(
'
Role hypervisor affected
'
)
from
ccnode.hypervisor
import
Handler
as
HypervisorHandler
self
.
connection
.
rpc
.
set_handler
(
HypervisorHandler
(
proxy
=
self
.
proxy
,
hypervisor_name
=
self
.
user_name
))
self
.
role
=
u
'
hv
'
self
.
loop
.
rpc_con
.
rpc
.
set_handler
(
HypervisorHandler
(
proxy
=
self
.
loop
.
proxy
,
hypervisor_name
=
self
.
loop
.
config
.
server_user
))
self
.
loop
.
role
=
u
'
hv
'
else
:
logger
.
debug
(
'
Wrong role returned: %s
'
,
role
)
role
=
None
time
.
sleep
(
2
)
self
.
role
=
role
def
rpc
(
self
):
"""
Runs ``sjRpc`` main loop. Catches exceptions. :func:`shutdown` the
connection before returning.
"""
try
:
self
.
connection
.
run
()
except
Exception
:
logger
.
exception
(
'
Unknown exception:
'
)
finally
:
self
.
shutdown
()
def
run
(
self
):
"""
Node main loop.
"""
while
True
:
# init rpc connection
while
True
:
try
:
self
.
init_rpc
()
except
Exception
as
e
:
logger
.
exception
(
'
Error in init.
'
)
else
:
break
time
.
sleep
(
2
)
# launch main rpc thread
rpc_thread
=
Thread
(
target
=
self
.
rpc
)
rpc_thread
.
daemon
=
True
rpc_thread
.
start
()
# launch auth thread, make sure rpc is still running
while
rpc_thread
.
is_alive
()
and
self
.
role
is
None
:
auth_thread
=
Thread
(
target
=
self
.
authentify
)
auth_thread
.
daemon
=
True
auth_thread
.
start
()
auth_thread
.
join
()
# FIXME for debug
time
.
sleep
(
4
)
# wait for rpc thread to terminates (it means error)
rpc_thread
.
join
()
logger
.
error
(
'
Reconnecting to server.
'
)
# reset settings
self
.
role
=
None
def
shutdown
(
self
):
"""
Shutdown the ``sjRpc`` connection and reset object state.
"""
with
self
.
_connection_lock
:
if
self
.
connection
is
not
None
:
self
.
connection
.
shutdown
()
self
.
connection
=
None
self
.
role
=
None
logger
.
info
(
'
Failed authentication, role returned: %s
'
,
response
)
self
.
loop
.
role
=
None
self
.
auth_id
=
None
return
if
self
.
loop
.
role
is
not
None
:
self
.
watcher
.
stop
()
logger
.
info
(
'
Successfully authenticated with role %s
'
,
response
)
self
.
auth_id
=
None
def
start
(
self
):
self
.
watcher
.
start
()
class
MainLoop
(
object
):
def
__init__
(
self
,
config_path
):
self
.
loop
=
pyev
.
default_loop
()
self
.
config_path
=
config_path
# set signal watchers
self
.
signals
=
{
signal
.
SIGINT
:
self
.
stop
,
signal
.
SIGTERM
:
self
.
stop
,
signal
.
SIGUSR1
:
self
.
reload
,
}
# turn into real watchers
self
.
signals
=
dict
((
signal
,
self
.
loop
.
signal
(
signal
,
cb
),
)
for
signal
,
cb
in
self
.
signals
.
iteritems
())
# load config variables
self
.
config
=
NodeConfigParser
(
self
.
config_path
)
# configure logging
logging
.
config
.
fileConfig
(
self
.
config_path
)
# rpc connection
self
.
rpc_con
=
None
self
.
auth
=
AuthHandler
(
self
)
# role
self
.
role
=
None
def
rpc_connect
(
self
):
# TODO async and error handling
self
.
rpc_con
=
RpcConnection
.
from_addr_ssl
(
addr
=
self
.
config
.
server_host
,
port
=
self
.
config
.
server_port
,
handler
=
DefaultHandler
(),
loop
=
self
.
loop
,
)
self
.
proxy
=
ConnectionProxy
(
self
.
rpc_con
)
def
start
(
self
):
for
signal
in
self
.
signals
.
itervalues
():
signal
.
start
()
logger
.
debug
(
'
About to connect
'
)
self
.
rpc_connect
()
self
.
auth
.
start
()
logger
.
debug
(
'
About to start ev_loop
'
)
self
.
loop
.
start
()
def
stop
(
self
,
watcher
=
None
,
revents
=
None
):
logger
.
info
(
'
Exiting node...
'
)
if
self
.
rpc_con
is
not
None
:
self
.
rpc_con
.
shutdown
()
self
.
loop
.
stop
()
def
reload
(
self
,
watcher
=
None
,
revents
=
None
):
logger
.
info
(
u
'
Reloading logging configuration...
'
)
logging
.
config
.
fileConfig
(
self
.
config_path
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment