Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
coco
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
coco
Commits
b15b5efa
Commit
b15b5efa
authored
7 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 将recorde拆出来完成
parent
e9a6daa7
master
dev
multiprocess
realip
v52
1.5.2
1.5.1
1.5.0
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.0
v1.4.7
v1.4.4
No related merge requests found
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
191 additions
and
132 deletions
+191
-132
app.py
coco/app.py
+15
-6
forward.py
coco/forward.py
+8
-3
httpd.py
coco/httpd.py
+1
-1
interactive.py
coco/interactive.py
+9
-7
models.py
coco/models.py
+28
-10
record.py
coco/record.py
+100
-83
session.py
coco/session.py
+30
-22
No files found.
coco/app.py
View file @
b15b5efa
...
@@ -49,18 +49,27 @@ class Coco:
...
@@ -49,18 +49,27 @@ class Coco:
self
.
clients
=
[]
self
.
clients
=
[]
self
.
lock
=
threading
.
Lock
()
self
.
lock
=
threading
.
Lock
()
self
.
stop_evt
=
threading
.
Event
()
self
.
stop_evt
=
threading
.
Event
()
self
.
_service
=
None
self
.
_sshd
=
None
self
.
_httpd
=
None
@property
@property
def
service
(
self
):
def
service
(
self
):
return
AppService
(
self
)
if
self
.
_service
is
None
:
self
.
_service
=
AppService
(
self
)
return
self
.
_service
@property
@property
def
sshd
(
self
):
def
sshd
(
self
):
return
SSHServer
(
self
)
if
self
.
_sshd
is
None
:
self
.
_sshd
=
SSHServer
(
self
)
return
self
.
_sshd
@property
@property
def
httpd
(
self
):
def
httpd
(
self
):
return
HttpServer
(
self
)
if
self
.
_httpd
is
None
:
self
.
_httpd
=
HttpServer
(
self
)
return
self
.
_httpd
def
make_logger
(
self
):
def
make_logger
(
self
):
create_logger
(
self
)
create_logger
(
self
)
...
@@ -73,10 +82,10 @@ class Coco:
...
@@ -73,10 +82,10 @@ class Coco:
self
.
make_logger
()
self
.
make_logger
()
self
.
service
.
initial
()
self
.
service
.
initial
()
self
.
load_extra_conf_from_server
()
self
.
load_extra_conf_from_server
()
self
.
heartbeat
()
self
.
keep_
heartbeat
()
self
.
monitor_sessions
()
self
.
monitor_sessions
()
def
heartbeat
(
self
):
def
keep_
heartbeat
(
self
):
def
func
():
def
func
():
while
not
self
.
stop_evt
.
is_set
():
while
not
self
.
stop_evt
.
is_set
():
_sessions
=
[
s
.
to_json
()
for
s
in
self
.
sessions
]
_sessions
=
[
s
.
to_json
()
for
s
in
self
.
sessions
]
...
@@ -95,7 +104,7 @@ class Coco:
...
@@ -95,7 +104,7 @@ class Coco:
def
func
():
def
func
():
while
not
self
.
stop_evt
.
is_set
():
while
not
self
.
stop_evt
.
is_set
():
for
s
in
self
.
sessions
:
for
s
in
self
.
sessions
:
if
not
s
.
is_finished
:
if
not
s
.
stop_evt
.
is_set
()
:
continue
continue
if
s
.
date_finished
is
None
:
if
s
.
date_finished
is
None
:
self
.
remove_session
(
s
)
self
.
remove_session
(
s
)
...
...
This diff is collapsed.
Click to expand it.
coco/forward.py
View file @
b15b5efa
# coding: utf-8
# coding: utf-8
import
socket
import
socket
import
threading
import
threading
import
logging
import
logging
...
@@ -9,11 +8,13 @@ import paramiko
...
@@ -9,11 +8,13 @@ import paramiko
from
.session
import
Session
from
.session
import
Session
from
.models
import
Server
from
.models
import
Server
from
.record
import
FileRecorder
from
.utils
import
wrap_with_line_feed
as
wr
from
.utils
import
wrap_with_line_feed
as
wr
logger
=
logging
.
getLogger
(
__file__
)
logger
=
logging
.
getLogger
(
__file__
)
TIMEOUT
=
8
TIMEOUT
=
8
BUF_SIZE
=
4096
class
ProxyServer
:
class
ProxyServer
:
...
@@ -32,7 +33,11 @@ class ProxyServer:
...
@@ -32,7 +33,11 @@ class ProxyServer:
session
=
Session
(
self
.
client
,
self
.
server
)
session
=
Session
(
self
.
client
,
self
.
server
)
self
.
app
.
add_session
(
session
)
self
.
app
.
add_session
(
session
)
self
.
watch_win_size_change_async
()
self
.
watch_win_size_change_async
()
session
.
add_recorder
()
recorder
=
FileRecorder
(
self
.
app
,
session
)
session
.
add_recorder
(
recorder
)
session
.
record_async
()
self
.
server
.
add_recorder
(
recorder
)
self
.
server
.
record_command_async
()
session
.
bridge
()
session
.
bridge
()
session
.
stop_evt
.
set
()
session
.
stop_evt
.
set
()
...
@@ -55,7 +60,7 @@ class ProxyServer:
...
@@ -55,7 +60,7 @@ class ProxyServer:
self
.
app
.
service
.
get_system_user_auth_info
(
system_user
)
self
.
app
.
service
.
get_system_user_auth_info
(
system_user
)
def
get_server_conn
(
self
,
asset
,
system_user
):
def
get_server_conn
(
self
,
asset
,
system_user
):
logger
.
info
(
"Connect to
%
s"
%
asset
.
hostname
)
logger
.
info
(
"Connect to
{}"
.
format
(
asset
.
hostname
)
)
if
not
self
.
validate_permission
(
asset
,
system_user
):
if
not
self
.
validate_permission
(
asset
,
system_user
):
self
.
client
.
send
(
_
(
'No permission'
))
self
.
client
.
send
(
_
(
'No permission'
))
return
None
return
None
...
...
This diff is collapsed.
Click to expand it.
coco/httpd.py
View file @
b15b5efa
...
@@ -39,7 +39,7 @@ class BaseWehSocketHandler:
...
@@ -39,7 +39,7 @@ class BaseWehSocketHandler:
class
InteractiveWehSocketHandler
(
BaseWehSocketHandler
,
tornado
.
websocket
.
WebSocketHandler
):
class
InteractiveWehSocketHandler
(
BaseWehSocketHandler
,
tornado
.
websocket
.
WebSocketHandler
):
@tornado.web.authenticated
@tornado.web.authenticated
def
open
(
self
):
def
open
(
self
):
InteractiveServer
(
self
.
app
,
self
.
client
)
.
activate
_async
()
InteractiveServer
(
self
.
app
,
self
.
client
)
.
interact
_async
()
def
on_message
(
self
,
message
):
def
on_message
(
self
,
message
):
try
:
try
:
...
...
This diff is collapsed.
Click to expand it.
coco/interactive.py
View file @
b15b5efa
...
@@ -3,7 +3,6 @@ import logging
...
@@ -3,7 +3,6 @@ import logging
import
socket
import
socket
import
threading
import
threading
# Todo remove
from
jms.models
import
Asset
,
AssetGroup
from
jms.models
import
Asset
,
AssetGroup
from
.
import
char
from
.
import
char
...
@@ -12,7 +11,6 @@ from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \
...
@@ -12,7 +11,6 @@ from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \
is_obj_attr_has
,
is_obj_attr_eq
,
sort_assets
,
TtyIOParser
,
\
is_obj_attr_has
,
is_obj_attr_eq
,
sort_assets
,
TtyIOParser
,
\
ugettext
as
_
ugettext
as
_
from
.forward
import
ProxyServer
from
.forward
import
ProxyServer
from
.session
import
Session
logger
=
logging
.
getLogger
(
__file__
)
logger
=
logging
.
getLogger
(
__file__
)
...
@@ -172,9 +170,10 @@ class InteractiveServer:
...
@@ -172,9 +170,10 @@ class InteractiveServer:
self
.
display_search_result
()
self
.
display_search_result
()
def
display_search_result
(
self
):
def
display_search_result
(
self
):
if
len
(
self
.
search_result
)
==
0
:
# if len(self.search_result) == 0:
self
.
client
.
send
(
warning
(
"Nothing match"
))
# self.client.send(warning("Nothing match"))
return
# return
print
(
"Total assets: "
.
format
(
len
(
self
.
assets
)))
self
.
search_result
=
sort_assets
(
self
.
search_result
,
self
.
app
.
config
[
"ASSET_LIST_SORT_BY"
])
self
.
search_result
=
sort_assets
(
self
.
search_result
,
self
.
app
.
config
[
"ASSET_LIST_SORT_BY"
])
fake_asset
=
Asset
(
hostname
=
_
(
"Hostname"
),
ip
=
_
(
"IP"
),
system_users_join
=
_
(
"LoginAs"
),
comment
=
_
(
"Comment"
))
fake_asset
=
Asset
(
hostname
=
_
(
"Hostname"
),
ip
=
_
(
"IP"
),
system_users_join
=
_
(
"LoginAs"
),
comment
=
_
(
"Comment"
))
...
@@ -189,7 +188,9 @@ class InteractiveServer:
...
@@ -189,7 +188,9 @@ class InteractiveServer:
self
.
client
.
send
(
wr
(
title
(
header
.
format
(
fake_asset
,
"ID"
))))
self
.
client
.
send
(
wr
(
title
(
header
.
format
(
fake_asset
,
"ID"
))))
for
index
,
asset
in
enumerate
(
self
.
search_result
,
1
):
for
index
,
asset
in
enumerate
(
self
.
search_result
,
1
):
self
.
client
.
send
(
wr
(
line
.
format
(
asset
,
index
)))
self
.
client
.
send
(
wr
(
line
.
format
(
asset
,
index
)))
self
.
client
.
send
(
wr
(
_
(
"Total: {}"
)
.
format
(
len
(
self
.
search_result
)),
before
=
1
))
self
.
client
.
send
(
wr
(
_
(
"Total: {} Matched: {}"
)
.
format
(
len
(
self
.
assets
),
len
(
self
.
search_result
)),
before
=
1
)
)
def
search_and_display
(
self
,
q
):
def
search_and_display
(
self
,
q
):
self
.
search_assets
(
q
)
self
.
search_assets
(
q
)
...
@@ -204,6 +205,7 @@ class InteractiveServer:
...
@@ -204,6 +205,7 @@ class InteractiveServer:
def
get_user_assets
(
self
):
def
get_user_assets
(
self
):
self
.
assets
=
self
.
app
.
service
.
get_user_assets
(
self
.
client
.
user
)
self
.
assets
=
self
.
app
.
service
.
get_user_assets
(
self
.
client
.
user
)
logger
.
debug
(
"Get user {} assets total: {}"
.
format
(
self
.
client
.
user
,
len
(
self
.
assets
)))
def
get_user_assets_async
(
self
):
def
get_user_assets_async
(
self
):
thread
=
threading
.
Thread
(
target
=
self
.
get_user_assets
)
thread
=
threading
.
Thread
(
target
=
self
.
get_user_assets
)
...
@@ -260,7 +262,7 @@ class InteractiveServer:
...
@@ -260,7 +262,7 @@ class InteractiveServer:
break
break
self
.
close
()
self
.
close
()
def
activate
_async
(
self
):
def
interact
_async
(
self
):
thread
=
threading
.
Thread
(
target
=
self
.
interact
)
thread
=
threading
.
Thread
(
target
=
self
.
interact
)
thread
.
daemon
=
True
thread
.
daemon
=
True
thread
.
start
()
thread
.
start
()
...
...
This diff is collapsed.
Click to expand it.
coco/models.py
View file @
b15b5efa
...
@@ -2,11 +2,13 @@ import json
...
@@ -2,11 +2,13 @@ import json
import
queue
import
queue
import
threading
import
threading
import
datetime
import
datetime
import
logging
from
.
import
char
from
.
import
char
from
.
import
utils
from
.
import
utils
BUF_SIZE
=
4096
BUF_SIZE
=
4096
logger
=
logging
.
getLogger
(
__file__
)
class
Request
:
class
Request
:
...
@@ -66,6 +68,7 @@ class Server:
...
@@ -66,6 +68,7 @@ class Server:
self
.
system_user
=
system_user
self
.
system_user
=
system_user
self
.
send_bytes
=
0
self
.
send_bytes
=
0
self
.
recv_bytes
=
0
self
.
recv_bytes
=
0
self
.
stop_evt
=
threading
.
Event
()
self
.
input_data
=
[]
self
.
input_data
=
[]
self
.
output_data
=
[]
self
.
output_data
=
[]
...
@@ -74,7 +77,10 @@ class Server:
...
@@ -74,7 +77,10 @@ class Server:
self
.
_in_vim_state
=
False
self
.
_in_vim_state
=
False
self
.
recorders
=
[]
self
.
recorders
=
[]
self
.
queue
=
queue
.
Queue
()
self
.
filters
=
[]
self
.
_input
=
""
self
.
_output
=
""
self
.
command_queue
=
queue
.
Queue
()
def
add_recorder
(
self
,
recorder
):
def
add_recorder
(
self
,
recorder
):
self
.
recorders
.
append
(
recorder
)
self
.
recorders
.
append
(
recorder
)
...
@@ -82,13 +88,21 @@ class Server:
...
@@ -82,13 +88,21 @@ class Server:
def
remove_recorder
(
self
,
recorder
):
def
remove_recorder
(
self
,
recorder
):
self
.
recorders
.
remove
(
recorder
)
self
.
recorders
.
remove
(
recorder
)
def
record_command
(
self
,
_input
,
_output
):
def
add_filter
(
self
,
_filter
):
while
True
:
self
.
filters
.
append
(
_filter
)
_input
,
_output
=
self
.
queue
.
get
()
def
remove_filter
(
self
,
_filter
):
self
.
filters
.
remove
(
_filter
)
def
record_command_async
(
self
):
def
func
():
while
not
self
.
stop_evt
.
is_set
():
_input
,
_output
=
self
.
command_queue
.
get
()
logger
.
debug
(
"Record command: ({},{})"
.
format
(
_input
,
_output
))
for
recorder
in
self
.
recorders
:
for
recorder
in
self
.
recorders
:
t
=
threading
.
Thread
(
target
=
recorder
.
record_command
,
recorder
.
record_command
(
datetime
.
datetime
.
now
(),
_input
,
_output
)
args
=
(
_input
,
_output
)
)
thread
=
threading
.
Thread
(
target
=
func
)
t
.
start
()
thread
.
start
()
def
fileno
(
self
):
def
fileno
(
self
):
return
self
.
chan
.
fileno
()
return
self
.
chan
.
fileno
()
...
@@ -101,14 +115,18 @@ class Server:
...
@@ -101,14 +115,18 @@ class Server:
if
self
.
_have_enter_char
(
b
):
if
self
.
_have_enter_char
(
b
):
self
.
_in_input_state
=
False
self
.
_in_input_state
=
False
self
.
_input
=
self
.
_parse_input
()
else
:
else
:
if
not
self
.
_in_input_state
:
if
not
self
.
_in_input_state
:
print
(
"#"
*
30
+
" 新周期 "
+
"#"
*
30
)
print
(
"#"
*
30
+
" 新周期 "
+
"#"
*
30
)
_input
=
self
.
_parse_input
()
self
.
_output
=
self
.
_parse_output
()
_output
=
self
.
_parse_output
()
print
(
self
.
_input
)
self
.
record_command
(
_input
,
_output
)
print
(
self
.
_output
)
self
.
command_queue
.
put
((
self
.
_input
,
self
.
_output
))
del
self
.
input_data
[:]
del
self
.
input_data
[:]
del
self
.
output_data
[:]
del
self
.
output_data
[:]
self
.
_input
=
""
self
.
_output
=
""
self
.
_in_input_state
=
True
self
.
_in_input_state
=
True
return
self
.
chan
.
send
(
b
)
return
self
.
chan
.
send
(
b
)
...
...
This diff is collapsed.
Click to expand it.
coco/record.py
View file @
b15b5efa
...
@@ -2,11 +2,7 @@
...
@@ -2,11 +2,7 @@
#
#
import
abc
import
abc
import
multiprocessing
import
threading
import
time
import
time
import
datetime
import
socket
import
os
import
os
import
logging
import
logging
...
@@ -20,52 +16,17 @@ class Recorder(metaclass=abc.ABCMeta):
...
@@ -20,52 +16,17 @@ class Recorder(metaclass=abc.ABCMeta):
def
__init__
(
self
,
app
,
session
):
def
__init__
(
self
,
app
,
session
):
self
.
app
=
app
self
.
app
=
app
self
.
session
=
session
self
.
session
=
session
self
.
replay_queue
=
multiprocessing
.
Queue
()
self
.
command_queue
=
multiprocessing
.
Queue
()
self
.
stop_evt
=
multiprocessing
.
Event
()
@abc.abstractmethod
@abc.abstractmethod
def
record_replay
(
self
):
def
record_replay
(
self
,
now
,
timedelta
,
size
,
data
):
pass
pass
@abc.abstractmethod
@abc.abstractmethod
def
record_command
(
self
,
_input
,
_output
):
def
record_command
(
self
,
now
,
_input
,
_output
):
pass
class
FileRecorder
(
Recorder
):
def
record_replay
(
self
):
parent
,
child
=
socket
.
socketpair
()
self
.
session
.
add_watcher
(
parent
)
session_dir
=
self
.
app
.
config
[
"SESSION_DIR"
]
with
open
(
os
.
path
.
join
(
session_dir
,
session
.
id
+
".rec"
),
'wb'
)
as
dataf
,
\
open
(
os
.
path
.
join
(
session_dir
,
session
.
id
+
".time"
),
"w"
)
as
timef
:
dataf
.
write
(
"Script started on {}
\n
"
.
format
(
time
.
asctime
())
.
encode
(
"utf-8"
))
while
not
self
.
stop_evt
.
is_set
():
start_t
=
time
.
time
()
data
=
child
.
recv
(
BUF_SIZE
)
end_t
=
time
.
time
()
size
=
len
(
data
)
if
size
==
0
:
break
timef
.
write
(
"
%.4
f
%
s
\n
"
%
(
end_t
-
start_t
,
size
))
dataf
.
write
(
data
)
dataf
.
write
(
"Script done on {}
\n
"
.
format
(
time
.
asctime
())
.
encode
(
"utf-8"
))
def
record_command
(
self
,
_input
,
_output
):
pass
class
SessionReplay
(
metaclass
=
abc
.
ABCMeta
):
@abc.abstractmethod
def
write_meta
(
self
,
meta
):
pass
pass
@abc.abstractmethod
@abc.abstractmethod
def
write_data
(
self
,
data
):
def
start
(
self
):
pass
pass
@abc.abstractmethod
@abc.abstractmethod
...
@@ -73,51 +34,107 @@ class SessionReplay(metaclass=abc.ABCMeta):
...
@@ -73,51 +34,107 @@ class SessionReplay(metaclass=abc.ABCMeta):
pass
pass
class
SessionCommand
(
metaclass
=
abc
.
ABCMeta
):
class
FileRecorder
(
Recorder
):
@abc.abstractmethod
def
write
(
self
,
cmd
,
output
):
pass
class
FileSessionReplay
(
SessionReplay
):
def
__init__
(
self
,
dataf
,
metaf
):
self
.
dataf
=
dataf
self
.
metaf
=
metaf
self
.
playing
=
True
def
write_data
(
self
,
data
):
self
.
dataf
.
write
(
data
)
def
write_meta
(
self
,
meta
):
self
.
metaf
.
write
(
meta
)
def
replay
(
self
,
sock
):
@property
sock
.
send
(
self
.
dataf
.
readline
())
def
session_dir
(
self
):
for
l
in
self
.
metaf
:
session_dir
=
os
.
path
.
join
(
if
not
self
.
playing
:
self
.
app
.
config
[
"SESSION_DIR"
],
break
self
.
session
.
date_created
.
strftime
(
"
%
Y-
%
m-
%
d"
)
t
,
size
=
float
(
l
.
split
()[
0
]),
int
(
l
.
split
()[
1
])
)
data
=
self
.
dataf
.
read
(
size
)
if
not
os
.
path
.
isdir
(
session_dir
):
time
.
sleep
(
t
)
os
.
mkdir
(
session_dir
)
sock
.
send
(
data
)
return
session_dir
sock
.
send
(
"Replay session end"
)
@property
def
data_f
(
self
):
filename
=
os
.
path
.
join
(
self
.
session_dir
,
str
(
self
.
session
.
id
)
+
".rec"
)
try
:
f
=
open
(
filename
,
'wb'
)
except
IOError
:
logger
.
error
(
"Failed open file {} in recorder"
.
format
(
filename
))
raise
return
f
@property
def
time_f
(
self
):
filename
=
os
.
path
.
join
(
self
.
session_dir
,
str
(
self
.
session
.
id
)
+
".time"
)
try
:
f
=
open
(
filename
,
'w'
)
except
IOError
:
logger
.
error
(
"Failed open file {} in recorder"
.
format
(
filename
))
raise
return
f
@property
def
cmd_f
(
self
):
filename
=
os
.
path
.
join
(
self
.
session_dir
,
str
(
self
.
session
.
id
)
+
".cmd"
)
try
:
f
=
open
(
filename
,
"w"
)
except
IOError
:
logger
.
error
(
"Failed open file {} in recorder"
.
format
(
filename
))
raise
return
f
def
record_replay
(
self
,
now
,
timedelta
,
size
,
data
):
self
.
time_f
.
write
(
"
%.4
f
%
s
\n
"
%
(
timedelta
,
size
))
self
.
data_f
.
write
(
data
)
def
record_command
(
self
,
now
,
_input
,
_output
):
self
.
cmd_f
.
write
(
"{}
\n
"
.
format
(
now
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)))
self
.
cmd_f
.
write
(
"$ {}
\n
"
.
format
(
_input
))
self
.
cmd_f
.
write
(
"{}
\n\n
"
.
format
(
_output
))
def
start
(
self
):
self
.
data_f
.
write
(
"Session started on {}
\n
"
.
format
(
time
.
asctime
())
.
encode
(
"utf-8"
))
def
done
(
self
):
def
done
(
self
):
self
.
data_f
.
write
(
"Session done on {}
\n
"
.
format
(
time
.
asctime
())
.
encode
(
"utf-8"
))
for
f
in
[
self
.
data_f
,
self
.
time_f
,
self
.
cmd_f
]:
try
:
f
.
close
()
except
IOError
:
pass
pass
class
FileSessionCommand
(
SessionCommand
):
# class FileSessionReplay(SessionReplay):
#
def
__init__
(
self
,
f
):
# def __init__(self, dataf, metaf):
self
.
f
=
f
# self.dataf = dataf
# self.metaf = metaf
def
write
(
self
,
cmd
,
output
):
# self.playing = True
self
.
f
.
write
(
"{}
\n
"
.
format
(
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)))
#
self
.
f
.
write
(
"$ {}
\n
"
.
format
(
cmd
))
# def write_data(self, data):
self
.
f
.
write
(
"{}
\n\n
"
.
format
(
output
))
# self.dataf.write(data)
#
def
done
(
self
):
# def write_meta(self, meta):
pass
# self.metaf.write(meta)
#
# def replay(self, sock):
# sock.send(self.dataf.readline())
# for l in self.metaf:
# if not self.playing:
# break
# t, size = float(l.split()[0]), int(l.split()[1])
# data = self.dataf.read(size)
# time.sleep(t)
# sock.send(data)
# sock.send("Replay session end")
#
# def done(self):
# pass
#
#
# class FileSessionCommand(SessionCommand):
#
# def __init__(self, f):
# self.f = f
#
# def write(self, cmd, output):
# self.f.write("{}\n".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
# self.f.write("$ {}\n".format(cmd))
# self.f.write("{}\n\n".format(output))
#
# def done(self):
# pass
This diff is collapsed.
Click to expand it.
coco/session.py
View file @
b15b5efa
...
@@ -25,7 +25,7 @@ class Session:
...
@@ -25,7 +25,7 @@ class Session:
self
.
replaying
=
True
self
.
replaying
=
True
self
.
date_created
=
datetime
.
datetime
.
now
()
self
.
date_created
=
datetime
.
datetime
.
now
()
self
.
date_finished
=
None
self
.
date_finished
=
None
self
.
recorder
=
[]
self
.
recorder
s
=
[]
self
.
stop_evt
=
threading
.
Event
()
self
.
stop_evt
=
threading
.
Event
()
self
.
sel
=
selectors
.
DefaultSelector
()
self
.
sel
=
selectors
.
DefaultSelector
()
...
@@ -70,11 +70,16 @@ class Session:
...
@@ -70,11 +70,16 @@ class Session:
self
.
sel
.
unregister
(
sharer
)
self
.
sel
.
unregister
(
sharer
)
self
.
sharers
.
remove
(
sharer
)
self
.
sharers
.
remove
(
sharer
)
def
add_recorder
(
self
,
recorder
):
self
.
recorders
.
append
(
recorder
)
def
remove_recorder
(
self
,
recorder
):
self
.
recorders
.
remove
(
recorder
)
def
bridge
(
self
):
def
bridge
(
self
):
"""
"""
Bridge clients with server
Bridge clients with server
:return:
:return:
"""
"""
logger
.
info
(
"Start bridge session
%
s"
%
self
.
id
)
logger
.
info
(
"Start bridge session
%
s"
%
self
.
id
)
self
.
sel
.
register
(
self
.
client
,
selectors
.
EVENT_READ
)
self
.
sel
.
register
(
self
.
client
,
selectors
.
EVENT_READ
)
...
@@ -92,39 +97,42 @@ class Session:
...
@@ -92,39 +97,42 @@ class Session:
elif
sock
==
self
.
client
:
elif
sock
==
self
.
client
:
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
"Client {} close the session"
watcher
.
send
(
"Client {} close the session"
.
format
(
self
.
client
)
.
encode
(
"utf-8"
))
.
format
(
self
.
client
)
.
encode
(
"utf-8"
))
self
.
close
()
self
.
close
()
break
break
self
.
server
.
send
(
data
)
self
.
server
.
send
(
data
)
elif
sock
in
self
.
sharers
:
elif
sock
in
self
.
sharers
:
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
logger
.
info
(
"Sharer {} leave session {}"
logger
.
info
(
"Sharer {} leave session {}"
.
format
(
sock
,
self
.
id
))
.
format
(
sock
,
self
.
id
))
self
.
remove_sharer
(
sock
)
self
.
remove_sharer
(
sock
)
self
.
server
.
send
(
data
)
self
.
server
.
send
(
data
)
elif
sock
in
self
.
watchers
:
elif
sock
in
self
.
watchers
:
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
logger
.
info
(
"Watcher {} leave session {}"
logger
.
info
(
"Watcher {} leave session {}"
.
format
(
sock
,
self
.
id
))
.
format
(
sock
,
self
.
id
))
def
set_size
(
self
,
width
,
height
):
def
set_size
(
self
,
width
,
height
):
self
.
server
.
resize_pty
(
width
=
width
,
height
=
height
)
self
.
server
.
resize_pty
(
width
=
width
,
height
=
height
)
def
add_recorder
(
self
,
recorder
):
def
record_async
(
self
):
self
.
recorder
.
append
(
recorder
)
def
func
():
parent
,
child
=
socket
.
socketpair
()
def
remove_recorder
(
self
,
recorder
):
for
recorder
in
self
.
recorders
:
self
.
recorder
.
remove
(
recorder
)
recorder
.
start
()
while
not
self
.
stop_evt
.
is_set
():
def
record
(
self
):
start_t
=
time
.
time
()
"""
data
=
child
.
recv
(
BUF_SIZE
)
Record the session
end_t
=
time
.
time
()
:return:
size
=
len
(
data
)
"""
now
=
datetime
.
datetime
.
now
()
for
recorder
in
self
.
recorder
:
timedelta
=
'{.4f}'
.
format
(
end_t
-
start_t
)
recorder
.
record
(
self
)
if
size
==
0
:
break
for
recorder
in
self
.
recorders
:
recorder
.
record_replay
(
now
,
timedelta
,
size
,
data
)
for
recorder
in
self
.
recorders
:
recorder
.
done
()
thread
=
threading
.
Thread
(
target
=
func
)
thread
.
start
()
def
close
(
self
):
def
close
(
self
):
self
.
stop_evt
.
set
()
self
.
stop_evt
.
set
()
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment