pull/26/head
yumaojun 2015-11-17 22:17:18 +08:00
commit 70e6904eb7
31 changed files with 426 additions and 1386 deletions

8
.gitignore vendored
View File

@ -37,11 +37,9 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject
*.xlsx
node_modules
logs
keys
*.log
logs/*
keys/*
jumpserver.conf
nohup.out
tmp/*
db.sqlite3

View File

@ -25,7 +25,7 @@ from jumpserver.settings import LOG_DIR
login_user = get_object(User, username=getpass.getuser())
VIM_FLAG = False
try:
import termios
@ -68,127 +68,7 @@ def check_vim_status(command, ssh):
return False
def deal_command(str_r, ssh):
"""
处理命令中特殊字符
"""
t = time.time()
str_r = re.sub('\x07','',str_r) #删除响铃
patch_char = re.compile('\x08\x1b\[C') #删除方向左右一起的按键
while patch_char.search(str_r):
str_r = patch_char.sub('', str_r.rstrip())
result_command = '' #最后的结果
backspace_num = 0 #光标移动的个数
backspace_list = []
reach_backspace_flag = False #没有检测到光标键则为true
reach_backspace_second_flag = False
pattern_list = []
pattern_str=''
while str_r:
tmp = re.match(r'\s*\w+\s*', str_r) #获取字符串,其它特殊字符匹配暂时还不知道。。
if tmp:
if reach_backspace_flag :
if not reach_backspace_second_flag:
pattern_str +=str(tmp.group(0))
else:
pattern_list.append(pattern_str)
pattern_str=str(tmp.group(0))
reach_backspace_second_flag=False
str_r = str_r[len(str(tmp.group(0))):]
continue
else:
result_command += str(tmp.group(0))
str_r = str_r[len(str(tmp.group(0))):]
continue
tmp = re.match(r'\x1b\[K[\x08]*', str_r) #遇到删除确认符,确定删除数据
if tmp:
for x in backspace_list:
backspace_num += int(x)
if backspace_num > 0:
if backspace_num > len(result_command) :
result_command += ''.join(pattern_list)
result_command += pattern_str
result_command = result_command[0:-backspace_num]
else:
result_command = result_command[0:-backspace_num]
result_command += ''.join(pattern_list)
result_command += pattern_str
del_len = len(str(tmp.group(0)))-3
if del_len > 0:
result_command = result_command[0:-del_len]
reach_backspace_flag = False
reach_backspace_second_flag =False
backspace_num =0
del pattern_list[:]
del backspace_list[:]
pattern_str=''
str_r = str_r[len(str(tmp.group(0))):]
continue
tmp = re.match(r'\x08+', str_r) #将遇到的退格数字存放到队列中
if tmp:
if reach_backspace_flag:
reach_backspace_second_flag = True
else:
reach_backspace_flag = True
str_r = str_r[len(str(tmp.group(0))):]
if len(str_r) != 0: #如果退格键在最后,则放弃
backspace_list.append(len(str(tmp.group(0))))
continue
if reach_backspace_flag :
if not reach_backspace_second_flag:
pattern_str +=str_r[0]
else:
pattern_list.append(pattern_str)
pattern_str=str_r[0]
reach_backspace_second_flag=False
else :
result_command += str_r[0]
str_r = str_r[1:]
if pattern_str !='':
pattern_list.append(pattern_str)
#退格队列中还有腿哥键,则进行删除操作
if len(backspace_list) > 0 :
for backspace in backspace_list:
if int(backspace) >= len(result_command):
result_command = pattern_list[0]
else:
result_command = result_command[:-int(backspace)]
result_command += pattern_list[0]
pattern_list = pattern_list[1:]
control_char = re.compile(r"""
\x1b[ #%()*+\-.\/]. |
\r | #匹配 回车符(CR)
(?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd
(?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL)
(?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST)
\x1b. #匹配 转义过后的字符
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
""", re.X)
result_command = control_char.sub('', result_command.strip())
global VIM_FLAG
global VIM_COMMAND
if not VIM_FLAG:
if result_command.startswith('vi'):
VIM_FLAG = True
VIM_COMMAND = result_command
return result_command.decode('utf8',"ignore")
else:
if check_vim_status(VIM_COMMAND, ssh):
VIM_FLAG = False
VIM_COMMAND=''
if result_command.endswith(':wq') or result_command.endswith(':wq!') or result_command.endswith(':q!'):
return ''
return result_command.decode('utf8',"ignore")
else:
return ''
class Tty(object):
@ -217,6 +97,127 @@ class Tty(object):
return True
return False
@staticmethod
def deal_command(str_r, ssh):
"""
处理命令中特殊字符
"""
str_r = re.sub('\x07','',str_r) #删除响铃
patch_char = re.compile('\x08\x1b\[C') #删除方向左右一起的按键
while patch_char.search(str_r):
str_r = patch_char.sub('', str_r.rstrip())
result_command = '' #最后的结果
backspace_num = 0 #光标移动的个数
backspace_list = []
reach_backspace_flag = False #没有检测到光标键则为true
reach_backspace_second_flag = False
pattern_list = []
pattern_str=''
while str_r:
tmp = re.match(r'\s*\w+\s*', str_r) #获取字符串,其它特殊字符匹配暂时还不知道。。
if tmp:
if reach_backspace_flag :
if not reach_backspace_second_flag:
pattern_str +=str(tmp.group(0))
else:
pattern_list.append(pattern_str)
pattern_str=str(tmp.group(0))
reach_backspace_second_flag=False
str_r = str_r[len(str(tmp.group(0))):]
continue
else:
result_command += str(tmp.group(0))
str_r = str_r[len(str(tmp.group(0))):]
continue
tmp = re.match(r'\x1b\[K[\x08]*', str_r) #遇到删除确认符,确定删除数据
if tmp:
for x in backspace_list:
backspace_num += int(x)
if backspace_num > 0:
if backspace_num > len(result_command) :
result_command += ''.join(pattern_list)
result_command += pattern_str
result_command = result_command[0:-backspace_num]
else:
result_command = result_command[0:-backspace_num]
result_command += ''.join(pattern_list)
result_command += pattern_str
del_len = len(str(tmp.group(0)))-3
if del_len > 0:
result_command = result_command[0:-del_len]
reach_backspace_flag = False
reach_backspace_second_flag =False
backspace_num =0
del pattern_list[:]
del backspace_list[:]
pattern_str=''
str_r = str_r[len(str(tmp.group(0))):]
continue
tmp = re.match(r'\x08+', str_r) #将遇到的退格数字存放到队列中
if tmp:
if reach_backspace_flag:
reach_backspace_second_flag = True
else:
reach_backspace_flag = True
str_r = str_r[len(str(tmp.group(0))):]
if len(str_r) != 0: #如果退格键在最后,则放弃
backspace_list.append(len(str(tmp.group(0))))
continue
if reach_backspace_flag :
if not reach_backspace_second_flag:
pattern_str +=str_r[0]
else:
pattern_list.append(pattern_str)
pattern_str=str_r[0]
reach_backspace_second_flag=False
else :
result_command += str_r[0]
str_r = str_r[1:]
if pattern_str !='':
pattern_list.append(pattern_str)
#退格队列中还有腿哥键,则进行删除操作
if len(backspace_list) > 0 :
for backspace in backspace_list:
if int(backspace) >= len(result_command):
result_command = pattern_list[0]
else:
result_command = result_command[:-int(backspace)]
result_command += pattern_list[0]
pattern_list = pattern_list[1:]
control_char = re.compile(r"""
\x1b[ #%()*+\-.\/]. |
\r | #匹配 回车符(CR)
(?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd
(?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL)
(?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST)
\x1b. #匹配 转义过后的字符
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
""", re.X)
result_command = control_char.sub('', result_command.strip())
global VIM_FLAG
global VIM_COMMAND
if not VIM_FLAG:
if result_command.startswith('vi'):
VIM_FLAG = True
VIM_COMMAND = result_command
return result_command.decode('utf8',"ignore")
else:
if check_vim_status(VIM_COMMAND, ssh):
VIM_FLAG = False
VIM_COMMAND=''
if result_command.endswith(':wq') or result_command.endswith(':wq!') or result_command.endswith(':q!'):
return ''
return result_command.decode('utf8',"ignore")
else:
return ''
@staticmethod
def remove_control_char(str_r):
"""
@ -402,7 +403,7 @@ class SshTty(Tty):
input_mode = True
if str(x) in ['\r', '\n', '\r\n']:
data = self.remove_control_char(data)
data = self.deal_command(data, self.ssh)
TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save()
data = ''

View File

@ -1,6 +1,5 @@
sphinx-me==0.3
django==1.6
python-ldap==2.4.19
pycrypto==2.6.1
paramiko==1.15.2
ecdsa==0.13
@ -9,4 +8,9 @@ django-uuidfield==0.5.0
psutil==2.2.1
xlsxwriter==0.7.7
xlrd==0.9.4
django-bootstrap-form
django-bootstrap-form
tornado
ansible
pyinotify
passlib
argparse

View File

@ -9,11 +9,11 @@ log = debug
host = 127.0.0.1
port = 3306
user = jumpserver
password = mysql1234
password = mysql234
database = jumpserver
[websocket]
web_socket_host = 127.0.0.1:3000
web_socket_host = j:3000
[mail]
mail_enable = 1

View File

@ -197,9 +197,9 @@ def require_role(role='user'):
def _deco(func):
def __deco(request, *args, **kwargs):
request.session['pre_url'] = request.path
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
if role == 'admin':
# if request.session.get('role_id', 0) < 1:
if request.user.role == 'CU':

Binary file not shown.

View File

@ -235,7 +235,7 @@ def Login(request):
request.session['role_id'] = 1
else:
request.session['role_id'] = 0
return HttpResponseRedirect(request.GET.get('next', '/'), )
return HttpResponseRedirect(request.session.get('pre_url', '/'))
# response.set_cookie('username', username, expires=604800)
# response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800)
# return response

View File

@ -11,17 +11,21 @@ urlpatterns = patterns('juser.views',
(r'^group_list/$', group_list),
(r'^group_del/$', group_del),
(r'^group_edit/$', group_edit),
(r'^user_add/$', user_add),
(r'^user_del/$', 'user_del'),
(r'^user_list/$', user_list),
(r'^user_edit/$', user_edit),
(r'^user_detail/$', 'user_detail'),
(r'^profile/$', 'profile'),
(r'^send_mail_retry/$', send_mail_retry),
(r'^reset_password/$', reset_password),
(r'^forget_password/$', forget_password),
(r'^user_detail/$', 'user_detail'),
(r'^user_del/$', 'user_del'),
(r'^user_edit/$', user_edit),
(r'^profile/$', 'profile'),
(r'^change_info/$', 'change_info'),
(r'^regen_ssh_key/$', 'regen_ssh_key'),
(r'^change_role/$', 'chg_role'),
(r'^regen_ssh_key/$', 'regen_ssh_key'),
(r'^down_key/$', 'down_key'),
)

View File

@ -86,13 +86,14 @@ def db_update_user(**kwargs):
groups_post = kwargs.pop('groups')
admin_groups_post = kwargs.pop('admin_groups')
user_id = kwargs.pop('user_id')
user = User.objects.get(id=user_id)
user = User.objects.filter(id=user_id)
user_get = User.objects.get(id=user_id)
if user:
pwd = kwargs.pop('password')
user.update(**kwargs)
if pwd != '':
user.set_password(pwd)
user.save()
user_get.set_password(pwd)
user_get.save()
else:
return None
@ -101,10 +102,10 @@ def db_update_user(**kwargs):
for group_id in groups_post:
group = UserGroup.objects.filter(id=group_id)
group_select.extend(group)
user.group = group_select
user_get.group = group_select
if admin_groups_post != '':
user.admingroup_set.all().delete()
user_get.admingroup_set.all().delete()
for group_id in admin_groups_post:
group = get_object(UserGroup, id=group_id)
AdminGroup(user=user, group=group).save()
@ -121,8 +122,7 @@ def db_del_user(username):
def gen_ssh_key(username, password='',
key_dir=os.path.join(BASE_DIR, 'role_keys/user/'),
key_dir=os.path.join(KEY_DIR, 'user'),
authorized_keys=True, home="/home", length=2048):
"""
@ -130,9 +130,10 @@ def gen_ssh_key(username, password='',
生成一个用户ssh密钥对
"""
private_key_file = os.path.join(key_dir, username)
mkdir(private_key_file, username)
if os.path.isfile(private_key_file):
os.unlink(private_key_file)
ret = bash('ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))
ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))
if authorized_keys:
auth_key_dir = os.path.join(home, username, '.ssh')

View File

@ -8,14 +8,11 @@ import uuid as uuid_r
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.template import RequestContext
from django.db.models import ObjectDoesNotExist
from jumpserver.settings import EMAIL_HOST_USER
from juser.user_api import *
from jperm.perm_api import _public_perm_api, perm_user_api, user_permed
MAIL_FROM = EMAIL_HOST_USER
def chg_role(request):
role = {'SU': 2, 'GA': 1, 'CU': 0}
if request.session['role_id'] > 0:
@ -142,54 +139,6 @@ def group_edit(request):
return my_render('juser/group_edit.html', locals(), request)
# @require_role(role='admin')
# def group_edit_adm(request):
# error = ''
# msg = ''
# header_title, path1, path2 = '修改小组信息', '用户管理', '编辑小组'
# user, dept = get_session_user_dept(request)
# if request.method == 'GET':
# group_id = request.GET.get('id', '')
# if not validate(request, user_group=[group_id]):
# return HttpResponseRedirect('/juser/group_list/')
# group = UserGroup.objects.filter(id=group_id)
# if group:
# group = group[0]
# users_all = dept.user_set.all()
# users_selected = group.user_set.all()
# users = [user for user in users_all if user not in users_selected]
#
# return render_to_response('juser/group_edit.html', locals(), context_instance=RequestContext(request))
# else:
# group_id = request.POST.get('group_id', '')
# group_name = request.POST.get('group_name', '')
# comment = request.POST.get('comment', '')
# users_selected = request.POST.getlist('users_selected')
#
# users = []
# try:
# if not validate(request, user=users_selected):
# raise ServerError(u'右侧非部门用户')
#
# if not validate(request, user_group=[group_id]):
# raise ServerError(u'没有权限修改本组')
#
# for user_id in users_selected:
# users.extend(User.objects.filter(id=user_id))
#
# user_group = UserGroup.objects.filter(id=group_id)
# if user_group:
# user_group.update(name=group_name, comment=comment, dept=dept)
# user_group = user_group[0]
# user_group.user_set.clear()
# user_group.user_set = users
#
# except ServerError, e:
# error = e
#
# return HttpResponseRedirect('/juser/group_list/')
@login_required(login_url='/login')
@require_role(role='super')
def user_add(request):
@ -210,7 +159,7 @@ def user_add(request):
uuid = uuid_r.uuid1()
ssh_key_pwd = PyCrypt.gen_rand_pass(16)
extra = request.POST.getlist('extra', [])
is_active = True if '0' in extra else False
is_active = False if '0' in extra else True
ssh_key_login_need = True if '1' in extra else False
send_mail_need = True if '2' in extra else False
@ -437,7 +386,6 @@ def user_edit(request):
admin_groups=admin_groups,
role=role_post,
is_active=is_active)
_public_perm_api({'type': 'del_user', 'user': user, 'asset': user_permed(user)})
if email_need:
msg = u"""
@ -475,7 +423,7 @@ def profile(request):
def change_info(request):
header_title, path1, path2 = '修改信息', '用户管理', '修改个人信息'
user_id = request.user.id
user = get_object(User, id=user_id)
user = User.objects.get(id=user_id)
error = ''
if not user:
return HttpResponseRedirect('/')
@ -485,18 +433,19 @@ def change_info(request):
password = request.POST.get('password', '')
email = request.POST.get('email', '')
if '' in [name, password, email]:
if '' in [name, email]:
error = '不能为空'
if len(password) < 6:
if len(password) > 0 and len(password) < 6:
error = '密码须大于6位'
if not error:
# if password != user.password:
# password = CRYPTOR.md5_crypt(password)
user.update(name=name, email=email)
user.set_password(password)
User.objects.filter(id=user_id).update(name=name, email=email)
if len(password) > 0:
user.set_password(password)
user.save()
msg = '修改成功'
return render_to_response('juser/change_info.html', locals(), context_instance=RequestContext(request))
@ -528,7 +477,7 @@ def down_key(request):
user = get_object(User, id=user_id)
if user:
username = user.username
private_key_file = os.path.join(BASE_DIR, 'role_keys/jumpserver', username + ".pem")
private_key_file = os.path.join(KEY_DIR, 'user', username)
if os.path.isfile(private_key_file):
f = open(private_key_file)
data = f.read()

3
keys/README.md Normal file
View File

@ -0,0 +1,3 @@
看山是山,看水是水
看山不是山,看水不是水
看山是山,看水是水

View File

@ -1,83 +0,0 @@
#!/usr/bin/python
# coding: utf-8
import os
import re
import time
import psutil
from datetime import datetime
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
import django
#django.setup()
from jlog.models import Log
def log_hanler(id):
log = Log.objects.get(id=id)
pattern = re.compile(r'([\[.*@.*\][\$#].*)|(.*mysql>.*)')
if log:
filename = log.log_path
if os.path.isfile(filename):
f_his = filename + '.his'
f1 = open(filename)
f2 = open(f_his, 'a')
lines = f1.readlines()
for line in lines[7:]:
match = pattern.match(line)
if match:
newline = re.sub('\[[A-Z]', '', line)
f2.write(newline)
f1.close()
f2.close()
log.log_finished = True
log.save()
def set_finish(id):
log = Log.objects.filter(id=id)
if log:
log.update(is_finished=1, end_time=datetime.now())
def kill_pid(pid):
try:
os.kill(pid, 9)
except OSError:
pass
def get_pids():
pids1, pids2 = [], []
pids1_obj = Log.objects.filter(is_finished=0)
pids2_obj = Log.objects.filter(is_finished=1, log_finished=0)
for pid_obj in pids1_obj:
pids1.append((pid_obj.id, pid_obj.pid, pid_obj.log_path, pid_obj.is_finished, pid_obj.log_finished, pid_obj.start_time))
for pid_obj in pids2_obj:
pids2.append(pid_obj.id)
return pids1, pids2
def run():
pids1, pids2 = get_pids()
for pid_id in pids2:
log_hanler(pid_id)
for pid_id, pid, log_path, is_finished, log_finished, start_time in pids1:
try:
file_time = int(os.stat(log_path).st_ctime)
now_time = int(time.time())
if now_time - file_time > 18000:
if psutil.pid_exists(pid):
kill_pid(pid)
set_finish(pid_id)
log_hanler(pid_id)
except OSError:
pass
if __name__ == '__main__':
while True:
run()
time.sleep(5)

1
logs/README.md Normal file
View File

@ -0,0 +1 @@
永远年轻,永远热泪盈眶

View File

View File

@ -1,17 +0,0 @@
- hosts: the_del_group
tasks:
- name: del user
user: name={{ item }} state=absent remove=yes
with_items: [ the_del_users ]
- hosts: the_new_group
tasks:
- name: add user
user: name={{ item }} state=present
with_items: [ the_new_users ]
- name: .ssh direcotory
file: name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory
with_items: [ the_new_users ]
- name: set authorizied_file
copy: src=KEY_DIR/{{ item }}.pub dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
with_items: [ the_new_users ]

View File

@ -236,7 +236,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if data.get('data'):
self.term.input_mode = True
if str(data['data']) in ['\r', '\n', '\r\n']:
TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.remove_control_char(self.term.data)).save()
TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.deal_command(self.term.data, self.term.ssh)).save()
self.term.data = ''
self.term.input_mode = False
self.term.channel.send(data['data'])

Binary file not shown.

View File

@ -17,10 +17,19 @@ function check_all(form) {
}
function checkAll(){
// 选择该页面所有checkbox
$('input[type=checkbox]').each(function(){
$(this).attr('checked', true)
})
var checklist = document.getElementsByName ("checked");
if(document.getElementById("check_all").checked)
{
for(var i=0;i<checklist.length;i++)
{
checklist[i].checked = 1;
}
}else{
for(var j=0;j<checklist.length;j++)
{
checklist[j].checked = 0;
}
}
}
//提取指定行的数据JSON格式

View File

@ -0,0 +1,196 @@
/* ShiftCheckbox jQuery plugin
*
* Copyright (C) 2011-2012 James Nylen
*
* Released under MIT license
* For details see:
* https://github.com/nylen/shiftcheckbox
*
* Requires jQuery v1.7 or higher.
*/
(function($) {
var ns = '.shiftcheckbox';
$.fn.shiftcheckbox = function(opts) {
opts = $.extend({
checkboxSelector : null,
selectAll : null,
onChange : null,
ignoreClick : null
}, opts);
if (typeof opts.onChange != 'function') {
opts.onChange = function(checked) { };
}
$.fn.scb_changeChecked = function(opts, checked) {
this.prop('checked', checked);
opts.onChange.call(this, checked);
return this;
}
var $containers,
$checkboxes,
$containersSelectAll,
$checkboxesSelectAll,
$otherSelectAll,
$containersAll,
$checkboxesAll;
if (opts.selectAll) {
// We need to set up a "select all" control
$containersSelectAll = $(opts.selectAll);
if ($containersSelectAll && !$containersSelectAll.length) {
$containersSelectAll = false;
}
}
if ($containersSelectAll) {
$checkboxesSelectAll = $containersSelectAll
.filter(':checkbox')
.add($containersSelectAll.find(':checkbox'));
$containersSelectAll = $containersSelectAll.not(':checkbox');
$otherSelectAll = $containersSelectAll.filter(function() {
return !$(this).find($checkboxesSelectAll).length;
});
$containersSelectAll = $containersSelectAll.filter(function() {
return !!$(this).find($checkboxesSelectAll).length;
}).each(function() {
$(this).data('childCheckbox', $(this).find($checkboxesSelectAll)[0]);
});
}
if (opts.checkboxSelector) {
// checkboxSelector means that the elements we need to attach handlers to
// ($containers) are not actually checkboxes but contain them instead
$containersAll = this.filter(function() {
return !!$(this).find(opts.checkboxSelector).filter(':checkbox').length;
}).each(function() {
$(this).data('childCheckbox', $(this).find(opts.checkboxSelector).filter(':checkbox')[0]);
}).add($containersSelectAll);
$checkboxesAll = $containersAll.map(function() {
return $(this).data('childCheckbox');
});
} else {
$checkboxesAll = this.filter(':checkbox');
}
if ($checkboxesSelectAll && !$checkboxesSelectAll.length) {
$checkboxesSelectAll = false;
} else {
$checkboxesAll = $checkboxesAll.add($checkboxesSelectAll);
}
if ($otherSelectAll && !$otherSelectAll.length) {
$otherSelectAll = false;
}
if ($containersAll) {
$containers = $containersAll.not($containersSelectAll);
}
$checkboxes = $checkboxesAll.not($checkboxesSelectAll);
if (!$checkboxes.length) {
return;
}
var lastIndex = -1;
var checkboxClicked = function(e) {
var checked = !!$(this).prop('checked');
var curIndex = $checkboxes.index(this);
if (curIndex < 0) {
if ($checkboxesSelectAll.filter(this).length) {
$checkboxesAll.scb_changeChecked(opts, checked);
}
return;
}
if (e.shiftKey && lastIndex != -1) {
var di = (curIndex > lastIndex ? 1 : -1);
for (var i = lastIndex; i != curIndex; i += di) {
$checkboxes.eq(i).scb_changeChecked(opts, checked);
}
}
if ($checkboxesSelectAll) {
if (checked && !$checkboxes.not(':checked').length) {
$checkboxesSelectAll.scb_changeChecked(opts, true);
} else if (!checked) {
$checkboxesSelectAll.scb_changeChecked(opts, false);
}
}
lastIndex = curIndex;
};
if ($checkboxesSelectAll) {
$checkboxesSelectAll
.prop('checked', !$checkboxes.not(':checked').length)
.filter(function() {
return !$containersAll.find(this).length;
}).on('click' + ns, checkboxClicked);
}
if ($otherSelectAll) {
$otherSelectAll.on('click' + ns, function() {
var checked;
if ($checkboxesSelectAll) {
checked = !!$checkboxesSelectAll.eq(0).prop('checked');
} else {
checked = !!$checkboxes.eq(0).prop('checked');
}
$checkboxesAll.scb_changeChecked(opts, !checked);
});
}
if (opts.checkboxSelector) {
$containersAll.on('click' + ns, function(e) {
if ($(e.target).closest(opts.ignoreClick).length) {
return;
}
var $checkbox = $($(this).data('childCheckbox'));
$checkbox.not(e.target).each(function() {
var checked = !$checkbox.prop('checked');
$(this).scb_changeChecked(opts, checked);
});
$checkbox[0].focus();
checkboxClicked.call($checkbox, e);
// If the user clicked on a label inside the row that points to the
// current row's checkbox, cancel the event.
var $label = $(e.target).closest('label');
var labelFor = $label.attr('for');
if (labelFor && labelFor == $checkbox.attr('id')) {
if ($label.find($checkbox).length) {
// Special case: The label contains the checkbox.
if ($checkbox[0] != e.target) {
return false;
}
} else {
return false;
}
}
}).on('mousedown' + ns, function(e) {
if (e.shiftKey) {
// Prevent selecting text by Shift+click
return false;
}
});
} else {
$checkboxes.on('click' + ns, checkboxClicked);
}
return this;
};
})(jQuery);

View File

@ -14,7 +14,6 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
{# <div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>#}
<small>All user</small>
</div>
</div>
@ -27,7 +26,6 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
{# <div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>#}
<small>All host</small>
</div>
</div>
@ -37,7 +35,7 @@
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary pull-right">Online</span>
<h5>实时在线用户</h5>
<h5>在线用户</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1>
@ -55,7 +53,6 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
{# <div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>#}
<small>Connected host</small>
</div>
</div>
@ -169,7 +166,7 @@
</div>
</div>
<div class="ibox-content ibox-heading">
<h3><i class="fa fa-user"></i> 一周Top10资产 </h3>
<h3><i class="fa fa-inbox"></i> 一周Top10资产 </h3>
<small><i class="fa fa-map-marker"></i> 登录次数及最近一次登录记录. </small>
</div>
<div class="ibox-content inspinia-timeline">
@ -309,14 +306,7 @@
</div>
</div>
</div>
<!--</div>-->
<!--<div class="col-xm-6" id="top10" style="width:50%;height:400px;"></div>-->
<!--<div class="col-xm-6" id="usertop10" style="width:50%;height:400px;"></div>-->
<!--<div class="row">-->
<!--<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>-->
<!--</div>-->
</div>
</div>
</div>
{% endblock %}

View File

@ -41,7 +41,7 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码<span class="red-fonts">*</span></label>
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-8">
<input id="password" name="password" placeholder="Password" type="password" class="form-control">
<span class="help-block m-b-none">
@ -91,7 +91,7 @@ $('#userForm').validator({
fields: {
"password": {
rule: "required;length[6~50]",
rule: "length[6~50]",
tip: "输入密码",
ok: "",
msg: {required: "必须填写!"}

View File

@ -43,7 +43,7 @@
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="select_all" onclick="selectAll()" name="select_all">
<input type="checkbox" id="select_all" name="select_all">
</th>
<th class="text-center">组名</th>
<th class="text-center">成员数目</th>
@ -55,7 +55,8 @@
{% for group in user_groups.object_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="selected" value="{{ group.id }}">
<input class="shiftCheckbox"
type="checkbox" name="selected" value="{{ group.id }}">
</td>
<td class="text-center"> {{ group.name }} </td>
<td class="text-center"><a href="/juser/user_list/?gid={{ group.id }}"> {{ group.id | members_count }}</a> </td>
@ -83,6 +84,10 @@
</div>
{% endblock %}
{% block self_head_css_js %}
{% load staticfiles %}
<script src="{% static 'js/jquery.shiftcheckbox.js' %}"></script>
{% endblock %}
{% block self_footer_js %}
<script>
$(document).ready(function(){
@ -115,7 +120,13 @@
)
}
})
});
$("tbody tr").shiftcheckbox({
checkboxSelector: 'input:checkbox',
selectAll: $('#select_all'),
ignoreClick: 'a'
});
$('.shiftCheckbox').shiftcheckbox();
});
</script>
{% endblock %}
{% endblock %}

View File

@ -93,10 +93,10 @@
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label">额外</label>
<div class="form-group"><label class="col-sm-2 control-label">其它</label>
<div class="col-sm-2">
<div class="checkbox i-checks">
<label><input type="checkbox" value="0" name="extra" ></label>
<label><input type="checkbox" value="0" name="extra" ></label>
</div>
</div>
<div class="col-sm-2">

View File

@ -42,7 +42,7 @@
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="select_all" onclick="selectAll()" name="select_all">
<input type="checkbox" id="check_all" onclick="checkAll()">
</th>
<th class="text-center">用户名</th>
<th class="text-center">姓名</th>
@ -57,7 +57,7 @@
{% for user in users.object_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="selected" value="{{ user.id }}">
<input type="checkbox" name="checked" value="{{ user.id }}">
</td>
<td class="text-center"> {{ user.username }} </td>
<td class="text-center"> {{ user.name }} </td>
@ -91,10 +91,15 @@
{% endblock %}
{% block self_head_css_js %}
{% load staticfiles %}
<script src="{% static 'js/jquery.shiftcheckbox.js' %}"></script>
{% endblock %}
{% block self_footer_js %}
<script>
$(document).ready(function(){
$('.del').click(function(){
var row = $(this).closest('tr');
if (confirm("确定删除")) {
$.get(
$(this).attr('value'),
{},
@ -102,7 +107,7 @@
row.remove();
alert(data);
}
)
)}
});
$('#del_btn').click(function(){
@ -129,7 +134,13 @@
alert(data)
}
)
})
});
$("tbody tr").shiftcheckbox({
checkboxSelector: 'input:checkbox',
selectAll: $('#select_all'),
ignoreClick: 'a'
});
$('.shiftCheckbox').shiftcheckbox();
});
</script>
{% endblock %}

View File

@ -4,10 +4,10 @@
<ul class="nav" id="side-menu">
{% include 'nav_li_profile.html' %}
<li id="index">
<a href="/"><i class="fa fa-th-large"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
<a href="/"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
</li>
<li id="juser">
<a href="#"><i class="fa fa-rebel"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
<a href="#"><i class="fa fa-group"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="group_list group_edit"><a href="/juser/group_list/">查看用户组</a></li>
<li class="group_add"><a href="/juser/group_add/">添加用户组</a></li>
@ -16,7 +16,7 @@
</ul>
</li>
<li id="jasset">
<a><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
<a><i class="fa fa-inbox"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="group_add"><a href="/jasset/group_add/">添加资产组</a></li>
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li>
@ -44,7 +44,7 @@
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
</li>
<li id="setting">
<a href="/setting/"><i class="fa fa-files-o"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
<a href="/setting/"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
</li>
<li class="special_link">
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a>

View File

@ -47,13 +47,19 @@
var old_href = $(this).attr('href').replace('?', '');
var searchArray = searchStr.split('&');
if (searchStr == ''){
searchStr = '?page=1'
}
if (searchStr.indexOf('page')>=0){
searchArray.pop();
}
searchArray.push(old_href);
if (searchArray.length > 1){
if (searchArray.length > 1) {
$(this).attr('href', searchArray.join('&'));
}
{# sleep(1000)#}
})
});

View File

@ -1 +0,0 @@
1.1

View File

@ -1,17 +0,0 @@
#!/usr/bin/env node
var program = require('commander');
nodetail = require('../src/node-tail.js');
var options = {};
program
.usage('[options] file...')
.option('-p, --port <port>', 'custom port');
program.parse(process.argv);
nodetail.run({
port: program.port,
file: program.args[0]
});

View File

@ -1,126 +0,0 @@
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var spawn = require('child_process').spawn;
var request = require("request");
var fs = require("fs");
var Tail = require('tail').Tail;
app.get('/', function(req, res){
res.send('<h1>Welcome Realtime Server</h1>');
});
//在线用户
var onlineUsers = {};
//当前在线人数
var onlineCount = 0;
io.on('connection', function(socket){
//console.log('a user connected');
//监听新用户加入
socket.on('login', function(obj){
request({
uri:"http://127.0.0.1/node_auth/",
method:"POST",
form:{
username:obj.username,
seed:obj.seed,
filename:obj.filename
}
},function(error,response,body){
try{
var result = JSON.parse(body)
console.log(body);
if(result['auth']['result'] != 'failed'){
fs.exists(obj.filename, function(result) {
//将新加入用户的唯一标识当作socket的名称后面退出的时候会用到
socket.name = obj.userid;
socket.fileName = obj.filename;
var tail = new Tail(obj.filename);
//2015-03-06 当用户打开监控窗口时,会把已存在的文件内容打印出来
fs.readFile(obj.filename, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
var existData = {userid:obj.userid,username:obj.username,content:data,option:'exist'};
socket.emit('message',existData);
});
tail.on('line',function(data) {
//console.log(data);
var newData = {userid:obj.userid,username:obj.username,content:data,option:'new'};
socket.emit('message',newData);
});
socket.tail = tail;
//检查在线列表,如果不在里面就加入
if(!onlineUsers.hasOwnProperty(obj.userid)) {
onlineUsers[obj.userid] = obj.username;
//在线人数+1
onlineCount++;
}
});
}
}catch(err){
console.log(err)
}
});
//var tail = spawn("tail", ['-f', obj.filename]);
//tail.stdout.on('data',function(data){
// var content = data.toString();
// //console.log(content);
// var newData = {userid:obj.userid,username:obj.username,content:content};
// socket.emit('message',newData);
//});
//向所有客户端广播用户加入
//io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
//console.log(obj.username+'加入了聊天室');
});
//监听用户退出
socket.on('disconnect', function(){
//将退出的用户从在线列表中删除
if(onlineUsers.hasOwnProperty(socket.name)) {
//退出用户的信息
var obj = {userid:socket.name, username:onlineUsers[socket.name]};
if( socket.tail){
socket.tail.unwatch();
}
//删除
delete onlineUsers[socket.name];
//在线人数-1
onlineCount--;
//向所有客户端广播用户退出
//io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
////console.log(obj.username+'退出了聊天室');
}
});
//监听用户发布聊天内容
socket.on('message', function(obj){
//向所有客户端广播发布的消息
//io.emit('message', obj);
socket.emit('message',obj);
////console.log(obj.username+'说:'+obj.content);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});

View File

@ -1,888 +0,0 @@
0 info it worked if it ends with ok
1 verbose cli [ '/opt/node/bin/node', '/opt/node/bin/npm', 'install' ]
2 info using npm@1.4.28
3 info using node@v0.10.33
4 warn package.json web-socket@0.0.1 No repository field.
5 warn package.json web-socket@0.0.1 No README data
6 verbose readDependencies using package.json deps
7 verbose install where, deps [ '/mnt/hgfs/jumpserver/websocket',
7 verbose install [ 'express', 'socket.io', 'node-tail', 'tail' ] ]
8 info preinstall web-socket@0.0.1
9 verbose readDependencies using package.json deps
10 verbose cache add [ 'express@~4.10.1', null ]
11 verbose cache add name=undefined spec="express@~4.10.1" args=["express@~4.10.1",null]
12 verbose parsed url { protocol: null,
12 verbose parsed url slashes: null,
12 verbose parsed url auth: null,
12 verbose parsed url host: null,
12 verbose parsed url port: null,
12 verbose parsed url hostname: null,
12 verbose parsed url hash: null,
12 verbose parsed url search: null,
12 verbose parsed url query: null,
12 verbose parsed url pathname: 'express@~4.10.1',
12 verbose parsed url path: 'express@~4.10.1',
12 verbose parsed url href: 'express@~4.10.1' }
13 verbose cache add [ 'socket.io@~1.2.0', null ]
14 verbose cache add name=undefined spec="socket.io@~1.2.0" args=["socket.io@~1.2.0",null]
15 verbose parsed url { protocol: null,
15 verbose parsed url slashes: null,
15 verbose parsed url auth: null,
15 verbose parsed url host: null,
15 verbose parsed url port: null,
15 verbose parsed url hostname: null,
15 verbose parsed url hash: null,
15 verbose parsed url search: null,
15 verbose parsed url query: null,
15 verbose parsed url pathname: 'socket.io@~1.2.0',
15 verbose parsed url path: 'socket.io@~1.2.0',
15 verbose parsed url href: 'socket.io@~1.2.0' }
16 verbose cache add [ 'node-tail@0.0.4', null ]
17 verbose cache add name=undefined spec="node-tail@0.0.4" args=["node-tail@0.0.4",null]
18 verbose parsed url { protocol: null,
18 verbose parsed url slashes: null,
18 verbose parsed url auth: null,
18 verbose parsed url host: null,
18 verbose parsed url port: null,
18 verbose parsed url hostname: null,
18 verbose parsed url hash: null,
18 verbose parsed url search: null,
18 verbose parsed url query: null,
18 verbose parsed url pathname: 'node-tail@0.0.4',
18 verbose parsed url path: 'node-tail@0.0.4',
18 verbose parsed url href: 'node-tail@0.0.4' }
19 verbose cache add [ 'tail@~0.4.0', null ]
20 verbose cache add name=undefined spec="tail@~0.4.0" args=["tail@~0.4.0",null]
21 verbose parsed url { protocol: null,
21 verbose parsed url slashes: null,
21 verbose parsed url auth: null,
21 verbose parsed url host: null,
21 verbose parsed url port: null,
21 verbose parsed url hostname: null,
21 verbose parsed url hash: null,
21 verbose parsed url search: null,
21 verbose parsed url query: null,
21 verbose parsed url pathname: 'tail@~0.4.0',
21 verbose parsed url path: 'tail@~0.4.0',
21 verbose parsed url href: 'tail@~0.4.0' }
22 verbose cache add name="express" spec="~4.10.1" args=["express","~4.10.1"]
23 verbose parsed url { protocol: null,
23 verbose parsed url slashes: null,
23 verbose parsed url auth: null,
23 verbose parsed url host: null,
23 verbose parsed url port: null,
23 verbose parsed url hostname: null,
23 verbose parsed url hash: null,
23 verbose parsed url search: null,
23 verbose parsed url query: null,
23 verbose parsed url pathname: '~4.10.1',
23 verbose parsed url path: '~4.10.1',
23 verbose parsed url href: '~4.10.1' }
24 verbose addNamed [ 'express', '~4.10.1' ]
25 verbose addNamed [ null, '>=4.10.1-0 <4.11.0-0' ]
26 verbose cache add name="socket.io" spec="~1.2.0" args=["socket.io","~1.2.0"]
27 verbose parsed url { protocol: null,
27 verbose parsed url slashes: null,
27 verbose parsed url auth: null,
27 verbose parsed url host: null,
27 verbose parsed url port: null,
27 verbose parsed url hostname: null,
27 verbose parsed url hash: null,
27 verbose parsed url search: null,
27 verbose parsed url query: null,
27 verbose parsed url pathname: '~1.2.0',
27 verbose parsed url path: '~1.2.0',
27 verbose parsed url href: '~1.2.0' }
28 verbose addNamed [ 'socket.io', '~1.2.0' ]
29 verbose addNamed [ null, '>=1.2.0-0 <1.3.0-0' ]
30 verbose cache add name="node-tail" spec="0.0.4" args=["node-tail","0.0.4"]
31 verbose parsed url { protocol: null,
31 verbose parsed url slashes: null,
31 verbose parsed url auth: null,
31 verbose parsed url host: null,
31 verbose parsed url port: null,
31 verbose parsed url hostname: null,
31 verbose parsed url hash: null,
31 verbose parsed url search: null,
31 verbose parsed url query: null,
31 verbose parsed url pathname: '0.0.4',
31 verbose parsed url path: '0.0.4',
31 verbose parsed url href: '0.0.4' }
32 verbose addNamed [ 'node-tail', '0.0.4' ]
33 verbose addNamed [ '0.0.4', '0.0.4' ]
34 verbose cache add name="tail" spec="~0.4.0" args=["tail","~0.4.0"]
35 verbose parsed url { protocol: null,
35 verbose parsed url slashes: null,
35 verbose parsed url auth: null,
35 verbose parsed url host: null,
35 verbose parsed url port: null,
35 verbose parsed url hostname: null,
35 verbose parsed url hash: null,
35 verbose parsed url search: null,
35 verbose parsed url query: null,
35 verbose parsed url pathname: '~0.4.0',
35 verbose parsed url path: '~0.4.0',
35 verbose parsed url href: '~0.4.0' }
36 verbose addNamed [ 'tail', '~0.4.0' ]
37 verbose addNamed [ null, '>=0.4.0-0 <0.5.0-0' ]
38 silly lockFile c572b5f8-express-4-10-1 express@~4.10.1
39 verbose lock express@~4.10.1 /root/.npm/c572b5f8-express-4-10-1.lock
40 silly lockFile c0bd7c21-socket-io-1-2-0 socket.io@~1.2.0
41 verbose lock socket.io@~1.2.0 /root/.npm/c0bd7c21-socket-io-1-2-0.lock
42 silly lockFile 7bc2e09d-node-tail-0-0-4 node-tail@0.0.4
43 verbose lock node-tail@0.0.4 /root/.npm/7bc2e09d-node-tail-0-0-4.lock
44 silly lockFile 81e86088-tail-0-4-0 tail@~0.4.0
45 verbose lock tail@~0.4.0 /root/.npm/81e86088-tail-0-4-0.lock
46 silly addNameRange { name: 'express',
46 silly addNameRange range: '>=4.10.1-0 <4.11.0-0',
46 silly addNameRange hasData: false }
47 silly addNameRange { name: 'socket.io',
47 silly addNameRange range: '>=1.2.0-0 <1.3.0-0',
47 silly addNameRange hasData: false }
48 silly addNameRange { name: 'tail', range: '>=0.4.0-0 <0.5.0-0', hasData: false }
49 verbose request where is /express
50 verbose request registry https://registry.npmjs.org/
51 verbose request id 07f88b54c82e7f84
52 verbose url raw /express
53 verbose url resolving [ 'https://registry.npmjs.org/', './express' ]
54 verbose url resolved https://registry.npmjs.org/express
55 verbose request where is https://registry.npmjs.org/express
56 info trying registry request attempt 1 at 14:35:44
57 verbose etag "2DZR7VK706IS8TAIMH81YR4GQ"
58 http GET https://registry.npmjs.org/express
59 verbose request where is /socket.io
60 verbose request registry https://registry.npmjs.org/
61 verbose url raw /socket.io
62 verbose url resolving [ 'https://registry.npmjs.org/', './socket.io' ]
63 verbose url resolved https://registry.npmjs.org/socket.io
64 verbose request where is https://registry.npmjs.org/socket.io
65 info trying registry request attempt 1 at 14:35:44
66 verbose etag "U3NL5HWOTJJX5QMHFQLTB5Z1"
67 http GET https://registry.npmjs.org/socket.io
68 verbose request where is /node-tail
69 verbose request registry https://registry.npmjs.org/
70 verbose url raw /node-tail
71 verbose url resolving [ 'https://registry.npmjs.org/', './node-tail' ]
72 verbose url resolved https://registry.npmjs.org/node-tail
73 verbose request where is https://registry.npmjs.org/node-tail
74 info trying registry request attempt 1 at 14:35:44
75 verbose etag "3O3MG0O1PBD2NBRQMCK50UX0W"
76 http GET https://registry.npmjs.org/node-tail
77 verbose request where is /tail
78 verbose request registry https://registry.npmjs.org/
79 verbose url raw /tail
80 verbose url resolving [ 'https://registry.npmjs.org/', './tail' ]
81 verbose url resolved https://registry.npmjs.org/tail
82 verbose request where is https://registry.npmjs.org/tail
83 info trying registry request attempt 1 at 14:35:44
84 verbose etag "92054A71KHLQVZ7G0DFM0WOD7"
85 http GET https://registry.npmjs.org/tail
86 http 304 https://registry.npmjs.org/express
87 silly registry.get cb [ 304,
87 silly registry.get { date: 'Sun, 19 Apr 2015 06:35:45 GMT',
87 silly registry.get server: 'Apache',
87 silly registry.get via: '1.1 varnish',
87 silly registry.get 'last-modified': 'Sun, 19 Apr 2015 06:35:45 GMT',
87 silly registry.get 'cache-control': 'max-age=60',
87 silly registry.get etag: '"2DZR7VK706IS8TAIMH81YR4GQ"',
87 silly registry.get age: '6',
87 silly registry.get 'x-served-by': 'cache-nrt6128-NRT',
87 silly registry.get 'x-cache': 'HIT',
87 silly registry.get 'x-cache-hits': '1',
87 silly registry.get 'x-timer': 'S1429425345.256295,VS0,VE4',
87 silly registry.get vary: 'Accept',
87 silly registry.get 'content-length': '0',
87 silly registry.get 'keep-alive': 'timeout=10, max=50',
87 silly registry.get connection: 'Keep-Alive' } ]
88 verbose etag https://registry.npmjs.org/express from cache
89 silly addNameRange number 2 { name: 'express', range: '>=4.10.1-0 <4.11.0-0', hasData: true }
90 silly addNameRange versions [ 'express',
90 silly addNameRange [ '0.14.0',
90 silly addNameRange '0.14.1',
90 silly addNameRange '1.0.0',
90 silly addNameRange '1.0.1',
90 silly addNameRange '1.0.2',
90 silly addNameRange '1.0.3',
90 silly addNameRange '1.0.4',
90 silly addNameRange '1.0.5',
90 silly addNameRange '1.0.6',
90 silly addNameRange '1.0.7',
90 silly addNameRange '1.0.8',
90 silly addNameRange '2.0.0',
90 silly addNameRange '2.1.0',
90 silly addNameRange '2.1.1',
90 silly addNameRange '2.2.0',
90 silly addNameRange '2.2.1',
90 silly addNameRange '2.2.2',
90 silly addNameRange '2.3.0',
90 silly addNameRange '2.3.1',
90 silly addNameRange '2.3.2',
90 silly addNameRange '2.3.3',
90 silly addNameRange '2.3.4',
90 silly addNameRange '2.3.5',
90 silly addNameRange '2.3.6',
90 silly addNameRange '2.3.7',
90 silly addNameRange '2.3.8',
90 silly addNameRange '2.3.9',
90 silly addNameRange '2.3.10',
90 silly addNameRange '2.3.11',
90 silly addNameRange '2.3.12',
90 silly addNameRange '2.4.0',
90 silly addNameRange '2.4.1',
90 silly addNameRange '2.4.2',
90 silly addNameRange '2.4.3',
90 silly addNameRange '2.4.4',
90 silly addNameRange '2.4.5',
90 silly addNameRange '2.4.6',
90 silly addNameRange '2.4.7',
90 silly addNameRange '2.5.0',
90 silly addNameRange '2.5.1',
90 silly addNameRange '2.5.2',
90 silly addNameRange '2.5.3',
90 silly addNameRange '2.5.4',
90 silly addNameRange '2.5.5',
90 silly addNameRange '2.5.6',
90 silly addNameRange '2.5.7',
90 silly addNameRange '2.5.8',
90 silly addNameRange '2.5.9',
90 silly addNameRange '2.5.10',
90 silly addNameRange '2.5.11',
90 silly addNameRange '3.0.0',
90 silly addNameRange '3.0.1',
90 silly addNameRange '3.0.2',
90 silly addNameRange '3.0.3',
90 silly addNameRange '3.0.4',
90 silly addNameRange '3.0.5',
90 silly addNameRange '3.0.6',
90 silly addNameRange '3.1.0',
90 silly addNameRange '3.1.1',
90 silly addNameRange '3.1.2',
90 silly addNameRange '3.2.0',
90 silly addNameRange '3.2.1',
90 silly addNameRange '3.2.2',
90 silly addNameRange '3.2.3',
90 silly addNameRange '3.2.4',
90 silly addNameRange '3.2.5',
90 silly addNameRange '3.2.6',
90 silly addNameRange '3.3.0',
90 silly addNameRange '3.3.1',
90 silly addNameRange '3.3.2',
90 silly addNameRange '3.3.3',
90 silly addNameRange '3.3.4',
90 silly addNameRange '3.3.5',
90 silly addNameRange '3.3.6',
90 silly addNameRange '1.0.0-beta',
90 silly addNameRange '1.0.0-beta2',
90 silly addNameRange '1.0.0-rc',
90 silly addNameRange '1.0.0-rc2',
90 silly addNameRange '1.0.0-rc3',
90 silly addNameRange '1.0.0-rc4',
90 silly addNameRange '2.0.0-beta',
90 silly addNameRange '2.0.0-beta2',
90 silly addNameRange '2.0.0-beta3',
90 silly addNameRange '2.0.0-rc',
90 silly addNameRange '2.0.0-rc2',
90 silly addNameRange '2.0.0-rc3',
90 silly addNameRange '3.0.0-alpha1',
90 silly addNameRange '3.0.0-alpha2',
90 silly addNameRange '3.0.0-alpha3',
90 silly addNameRange '3.0.0-alpha4',
90 silly addNameRange '3.0.0-alpha5',
90 silly addNameRange '3.0.0-beta1',
90 silly addNameRange '3.0.0-beta2',
90 silly addNameRange '3.0.0-beta3',
90 silly addNameRange '3.0.0-beta4',
90 silly addNameRange '3.0.0-beta6',
90 silly addNameRange '3.0.0-beta7',
90 silly addNameRange '3.0.0-rc1',
90 silly addNameRange '3.0.0-rc2',
90 silly addNameRange '3.0.0-rc3',
90 silly addNameRange '3.0.0-rc4',
90 silly addNameRange '3.0.0-rc5',
90 silly addNameRange '3.3.7',
90 silly addNameRange '3.3.8',
90 silly addNameRange '3.4.0',
90 silly addNameRange '3.4.1',
90 silly addNameRange '3.4.2',
90 silly addNameRange '3.4.3',
90 silly addNameRange '3.4.4',
90 silly addNameRange '3.4.5',
90 silly addNameRange '3.4.6',
90 silly addNameRange '3.4.7',
90 silly addNameRange '3.4.8',
90 silly addNameRange '4.0.0-rc1',
90 silly addNameRange '4.0.0-rc2',
90 silly addNameRange '3.5.0',
90 silly addNameRange '4.0.0-rc3',
90 silly addNameRange '4.0.0-rc4',
90 silly addNameRange '3.5.1',
90 silly addNameRange '4.0.0',
90 silly addNameRange '3.5.2',
90 silly addNameRange '4.1.0',
90 silly addNameRange '4.1.1',
90 silly addNameRange '3.5.3',
90 silly addNameRange '4.1.2',
90 silly addNameRange '3.6.0',
90 silly addNameRange '4.2.0',
90 silly addNameRange '3.7.0',
90 silly addNameRange '3.8.0',
90 silly addNameRange '4.3.0',
90 silly addNameRange '4.3.1',
90 silly addNameRange '3.8.1',
90 silly addNameRange '4.3.2',
90 silly addNameRange '3.9.0',
90 silly addNameRange '4.4.0',
90 silly addNameRange '4.4.1',
90 silly addNameRange '3.10.0',
90 silly addNameRange '3.10.1',
90 silly addNameRange '3.10.2',
90 silly addNameRange '3.10.3',
90 silly addNameRange '3.10.4',
90 silly addNameRange '4.4.2',
90 silly addNameRange '3.10.5',
90 silly addNameRange '4.4.3',
90 silly addNameRange '3.11.0',
90 silly addNameRange '4.4.4',
90 silly addNameRange '3.12.0',
90 silly addNameRange '3.12.1',
90 silly addNameRange '4.4.5',
90 silly addNameRange '3.13.0',
90 silly addNameRange '4.5.0',
90 silly addNameRange '4.5.1',
90 silly addNameRange '3.14.0',
90 silly addNameRange '4.6.0',
90 silly addNameRange '4.6.1',
90 silly addNameRange '3.15.0',
90 silly addNameRange '4.7.0',
90 silly addNameRange '3.15.1',
90 silly addNameRange '4.7.1',
90 silly addNameRange '3.15.2',
90 silly addNameRange '4.7.2',
90 silly addNameRange '4.7.3',
90 silly addNameRange '3.15.3',
90 silly addNameRange '4.7.4',
90 silly addNameRange '3.16.0',
90 silly addNameRange '4.8.0',
90 silly addNameRange '3.16.1',
90 silly addNameRange '4.8.1',
90 silly addNameRange '3.16.2',
90 silly addNameRange '4.8.2',
90 silly addNameRange '3.16.3',
90 silly addNameRange '3.16.4',
90 silly addNameRange '4.8.3',
90 silly addNameRange '3.16.5',
90 silly addNameRange '3.16.6',
90 silly addNameRange '4.8.4',
90 silly addNameRange '3.16.7',
90 silly addNameRange '4.8.5',
90 silly addNameRange '3.16.8',
90 silly addNameRange '4.8.6',
90 silly addNameRange '3.16.9',
90 silly addNameRange '4.8.7',
90 silly addNameRange '3.16.10',
90 silly addNameRange '4.8.8',
90 silly addNameRange '3.17.0',
90 silly addNameRange '3.17.1',
90 silly addNameRange '4.9.0',
90 silly addNameRange '3.17.2',
90 silly addNameRange '4.9.1',
90 silly addNameRange '4.9.2',
90 silly addNameRange '3.17.3',
90 silly addNameRange '4.9.3',
90 silly addNameRange '3.17.4',
90 silly addNameRange '4.9.4',
90 silly addNameRange '3.17.5',
90 silly addNameRange '4.9.5',
90 silly addNameRange '3.17.6',
90 silly addNameRange '3.17.7',
90 silly addNameRange '4.9.6',
90 silly addNameRange '4.9.7',
90 silly addNameRange '3.17.8',
90 silly addNameRange '4.9.8',
90 silly addNameRange '3.18.0',
90 silly addNameRange '3.18.1',
90 silly addNameRange '4.10.0',
90 silly addNameRange '3.18.2',
90 silly addNameRange '4.10.1',
90 silly addNameRange '5.0.0-alpha.1',
90 silly addNameRange '3.18.3',
90 silly addNameRange '4.10.2',
90 silly addNameRange '3.18.4',
90 silly addNameRange '4.10.3',
90 silly addNameRange '4.10.4',
90 silly addNameRange '4.10.5',
90 silly addNameRange '3.18.5',
90 silly addNameRange '3.18.6',
90 silly addNameRange '4.10.6',
90 silly addNameRange '4.10.7',
90 silly addNameRange '3.19.0',
90 silly addNameRange '4.10.8',
90 silly addNameRange '4.11.0',
90 silly addNameRange '3.19.1',
90 silly addNameRange '4.11.1',
90 silly addNameRange '3.19.2',
90 silly addNameRange '4.11.2',
90 silly addNameRange '3.20.0',
90 silly addNameRange '4.12.0',
90 silly addNameRange '3.20.1',
90 silly addNameRange '4.12.1',
90 silly addNameRange '4.12.2',
90 silly addNameRange '3.20.2',
90 silly addNameRange '4.12.3' ] ]
91 verbose addNamed [ 'express', '4.10.8' ]
92 verbose addNamed [ '4.10.8', '4.10.8' ]
93 silly lockFile 44558bf5-express-4-10-8 express@4.10.8
94 verbose lock express@4.10.8 /root/.npm/44558bf5-express-4-10-8.lock
95 silly lockFile 44558bf5-express-4-10-8 express@4.10.8
96 silly lockFile 44558bf5-express-4-10-8 express@4.10.8
97 silly lockFile c572b5f8-express-4-10-1 express@~4.10.1
98 silly lockFile c572b5f8-express-4-10-1 express@~4.10.1
99 http 304 https://registry.npmjs.org/socket.io
100 silly registry.get cb [ 304,
100 silly registry.get { date: 'Sun, 19 Apr 2015 06:35:45 GMT',
100 silly registry.get server: 'Apache',
100 silly registry.get via: '1.1 varnish',
100 silly registry.get 'last-modified': 'Sun, 19 Apr 2015 06:35:45 GMT',
100 silly registry.get 'cache-control': 'max-age=60',
100 silly registry.get etag: '"U3NL5HWOTJJX5QMHFQLTB5Z1"',
100 silly registry.get age: '0',
100 silly registry.get 'x-served-by': 'cache-nrt6120-NRT',
100 silly registry.get 'x-cache': 'HIT',
100 silly registry.get 'x-cache-hits': '1',
100 silly registry.get 'x-timer': 'S1429425345.256029,VS0,VE173',
100 silly registry.get vary: 'Accept',
100 silly registry.get 'content-length': '0',
100 silly registry.get 'keep-alive': 'timeout=10, max=50',
100 silly registry.get connection: 'Keep-Alive' } ]
101 verbose etag https://registry.npmjs.org/socket.io from cache
102 silly addNameRange number 2 { name: 'socket.io', range: '>=1.2.0-0 <1.3.0-0', hasData: true }
103 silly addNameRange versions [ 'socket.io',
103 silly addNameRange [ '0.3.8',
103 silly addNameRange '0.4.0',
103 silly addNameRange '0.4.1',
103 silly addNameRange '0.5.1',
103 silly addNameRange '0.5.3',
103 silly addNameRange '0.6.0',
103 silly addNameRange '0.6.1',
103 silly addNameRange '0.6.3',
103 silly addNameRange '0.6.4',
103 silly addNameRange '0.6.5',
103 silly addNameRange '0.6.6',
103 silly addNameRange '0.6.7',
103 silly addNameRange '0.6.8',
103 silly addNameRange '0.6.9',
103 silly addNameRange '0.6.10',
103 silly addNameRange '0.6.11',
103 silly addNameRange '0.6.12',
103 silly addNameRange '0.6.14',
103 silly addNameRange '0.6.15',
103 silly addNameRange '0.6.16',
103 silly addNameRange '0.6.17',
103 silly addNameRange '0.6.18',
103 silly addNameRange '0.7.0',
103 silly addNameRange '0.7.1',
103 silly addNameRange '0.7.2',
103 silly addNameRange '0.7.3',
103 silly addNameRange '0.7.4',
103 silly addNameRange '0.7.5',
103 silly addNameRange '0.7.6',
103 silly addNameRange '0.7.7',
103 silly addNameRange '0.7.8',
103 silly addNameRange '0.7.9',
103 silly addNameRange '0.7.10',
103 silly addNameRange '0.7.11',
103 silly addNameRange '0.8.0',
103 silly addNameRange '0.8.1',
103 silly addNameRange '0.8.2',
103 silly addNameRange '0.8.3',
103 silly addNameRange '0.8.4',
103 silly addNameRange '0.8.5',
103 silly addNameRange '0.8.6',
103 silly addNameRange '0.8.7',
103 silly addNameRange '0.9.0',
103 silly addNameRange '0.9.1',
103 silly addNameRange '0.9.1-1',
103 silly addNameRange '0.9.2',
103 silly addNameRange '0.9.3',
103 silly addNameRange '0.9.4',
103 silly addNameRange '0.9.5',
103 silly addNameRange '0.9.6',
103 silly addNameRange '0.9.7',
103 silly addNameRange '0.9.8',
103 silly addNameRange '0.9.9',
103 silly addNameRange '0.9.10',
103 silly addNameRange '0.9.11',
103 silly addNameRange '0.9.12',
103 silly addNameRange '0.9.13',
103 silly addNameRange '0.9.14',
103 silly addNameRange '0.9.15',
103 silly addNameRange '0.9.16',
103 silly addNameRange '1.0.0-pre',
103 silly addNameRange '1.0.0-pre2',
103 silly addNameRange '1.0.0-pre3',
103 silly addNameRange '1.0.0-pre4',
103 silly addNameRange '1.0.0-pre5',
103 silly addNameRange '0.9.17',
103 silly addNameRange '1.0.0',
103 silly addNameRange '1.0.1',
103 silly addNameRange '1.0.2',
103 silly addNameRange '1.0.3',
103 silly addNameRange '1.0.4',
103 silly addNameRange '1.0.5',
103 silly addNameRange '1.0.6',
103 silly addNameRange '1.1.0',
103 silly addNameRange '1.2.0',
103 silly addNameRange '1.2.1',
103 silly addNameRange '1.3.0',
103 silly addNameRange '1.3.1',
103 silly addNameRange '1.3.2',
103 silly addNameRange '1.3.3',
103 silly addNameRange '1.3.4',
103 silly addNameRange '1.3.5' ] ]
104 verbose addNamed [ 'socket.io', '1.2.1' ]
105 verbose addNamed [ '1.2.1', '1.2.1' ]
106 silly lockFile 77e414a6-socket-io-1-2-1 socket.io@1.2.1
107 verbose lock socket.io@1.2.1 /root/.npm/77e414a6-socket-io-1-2-1.lock
108 silly lockFile 77e414a6-socket-io-1-2-1 socket.io@1.2.1
109 silly lockFile 77e414a6-socket-io-1-2-1 socket.io@1.2.1
110 silly lockFile c0bd7c21-socket-io-1-2-0 socket.io@~1.2.0
111 silly lockFile c0bd7c21-socket-io-1-2-0 socket.io@~1.2.0
112 http 304 https://registry.npmjs.org/node-tail
113 silly registry.get cb [ 304,
113 silly registry.get { date: 'Sun, 19 Apr 2015 06:35:45 GMT',
113 silly registry.get server: 'Apache',
113 silly registry.get via: '1.1 varnish',
113 silly registry.get 'last-modified': 'Sun, 19 Apr 2015 06:35:45 GMT',
113 silly registry.get 'cache-control': 'max-age=60',
113 silly registry.get etag: '"3O3MG0O1PBD2NBRQMCK50UX0W"',
113 silly registry.get age: '0',
113 silly registry.get 'x-served-by': 'cache-nrt6128-NRT',
113 silly registry.get 'x-cache': 'HIT',
113 silly registry.get 'x-cache-hits': '1',
113 silly registry.get 'x-timer': 'S1429425345.255202,VS0,VE706',
113 silly registry.get vary: 'Accept',
113 silly registry.get 'content-length': '0',
113 silly registry.get 'keep-alive': 'timeout=10, max=50',
113 silly registry.get connection: 'Keep-Alive' } ]
114 verbose etag https://registry.npmjs.org/node-tail from cache
115 silly lockFile 7bc2e09d-node-tail-0-0-4 node-tail@0.0.4
116 silly lockFile 7bc2e09d-node-tail-0-0-4 node-tail@0.0.4
117 http 304 https://registry.npmjs.org/tail
118 silly registry.get cb [ 304,
118 silly registry.get { date: 'Sun, 19 Apr 2015 06:35:45 GMT',
118 silly registry.get server: 'Apache',
118 silly registry.get via: '1.1 varnish',
118 silly registry.get 'last-modified': 'Sun, 19 Apr 2015 06:35:46 GMT',
118 silly registry.get 'cache-control': 'max-age=60',
118 silly registry.get etag: '"92054A71KHLQVZ7G0DFM0WOD7"',
118 silly registry.get age: '0',
118 silly registry.get 'x-served-by': 'cache-nrt6124-NRT',
118 silly registry.get 'x-cache': 'HIT',
118 silly registry.get 'x-cache-hits': '1',
118 silly registry.get 'x-timer': 'S1429425345.700815,VS0,VE732',
118 silly registry.get vary: 'Accept',
118 silly registry.get 'content-length': '0',
118 silly registry.get 'keep-alive': 'timeout=10, max=50',
118 silly registry.get connection: 'Keep-Alive' } ]
119 verbose etag https://registry.npmjs.org/tail from cache
120 silly addNameRange number 2 { name: 'tail', range: '>=0.4.0-0 <0.5.0-0', hasData: true }
121 silly addNameRange versions [ 'tail',
121 silly addNameRange [ '0.0.3',
121 silly addNameRange '0.0.4',
121 silly addNameRange '0.1.0',
121 silly addNameRange '0.1.1',
121 silly addNameRange '0.1.2',
121 silly addNameRange '0.2.0',
121 silly addNameRange '0.2.1',
121 silly addNameRange '0.2.2',
121 silly addNameRange '0.2.3',
121 silly addNameRange '0.2.4',
121 silly addNameRange '0.3.0',
121 silly addNameRange '0.3.1',
121 silly addNameRange '0.3.2',
121 silly addNameRange '0.3.5',
121 silly addNameRange '0.3.6',
121 silly addNameRange '0.3.7',
121 silly addNameRange '0.3.8',
121 silly addNameRange '0.3.9',
121 silly addNameRange '0.4.0' ] ]
122 verbose addNamed [ 'tail', '0.4.0' ]
123 verbose addNamed [ '0.4.0', '0.4.0' ]
124 silly lockFile e7d4c0e4-tail-0-4-0 tail@0.4.0
125 verbose lock tail@0.4.0 /root/.npm/e7d4c0e4-tail-0-4-0.lock
126 silly lockFile e7d4c0e4-tail-0-4-0 tail@0.4.0
127 silly lockFile e7d4c0e4-tail-0-4-0 tail@0.4.0
128 silly lockFile 81e86088-tail-0-4-0 tail@~0.4.0
129 silly lockFile 81e86088-tail-0-4-0 tail@~0.4.0
130 silly resolved [ { name: 'express',
130 silly resolved description: 'Fast, unopinionated, minimalist web framework',
130 silly resolved version: '4.10.8',
130 silly resolved author: { name: 'TJ Holowaychuk', email: 'tj@vision-media.ca' },
130 silly resolved contributors:
130 silly resolved [ [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object] ],
130 silly resolved license: 'MIT',
130 silly resolved repository: { type: 'git', url: 'https://github.com/strongloop/express' },
130 silly resolved homepage: 'http://expressjs.com/',
130 silly resolved keywords:
130 silly resolved [ 'express',
130 silly resolved 'framework',
130 silly resolved 'sinatra',
130 silly resolved 'web',
130 silly resolved 'rest',
130 silly resolved 'restful',
130 silly resolved 'router',
130 silly resolved 'app',
130 silly resolved 'api' ],
130 silly resolved dependencies:
130 silly resolved { accepts: '~1.1.4',
130 silly resolved 'content-disposition': '0.5.0',
130 silly resolved 'cookie-signature': '1.0.5',
130 silly resolved debug: '~2.1.1',
130 silly resolved depd: '~1.0.0',
130 silly resolved 'escape-html': '1.0.1',
130 silly resolved etag: '~1.5.1',
130 silly resolved finalhandler: '0.3.3',
130 silly resolved fresh: '0.2.4',
130 silly resolved 'media-typer': '0.3.0',
130 silly resolved methods: '1.1.1',
130 silly resolved 'on-finished': '~2.2.0',
130 silly resolved parseurl: '~1.3.0',
130 silly resolved 'path-to-regexp': '0.1.3',
130 silly resolved 'proxy-addr': '~1.0.5',
130 silly resolved qs: '2.3.3',
130 silly resolved 'range-parser': '~1.0.2',
130 silly resolved send: '0.10.1',
130 silly resolved 'serve-static': '~1.7.2',
130 silly resolved 'type-is': '~1.5.5',
130 silly resolved vary: '~1.0.0',
130 silly resolved cookie: '0.1.2',
130 silly resolved 'merge-descriptors': '0.0.2',
130 silly resolved 'utils-merge': '1.0.0' },
130 silly resolved devDependencies:
130 silly resolved { after: '0.8.1',
130 silly resolved istanbul: '0.3.5',
130 silly resolved mocha: '~2.0.0',
130 silly resolved should: '~4.3.1',
130 silly resolved supertest: '~0.15.0',
130 silly resolved ejs: '~1.0.0',
130 silly resolved marked: '0.3.2',
130 silly resolved hjs: '~0.0.6',
130 silly resolved 'body-parser': '~1.10.1',
130 silly resolved 'connect-redis': '~2.1.0',
130 silly resolved 'cookie-parser': '~1.3.3',
130 silly resolved 'express-session': '~1.9.2',
130 silly resolved jade: '~1.8.2',
130 silly resolved 'method-override': '~2.3.1',
130 silly resolved morgan: '~1.5.1',
130 silly resolved multiparty: '~4.1.0',
130 silly resolved vhost: '~3.0.0' },
130 silly resolved engines: { node: '>= 0.10.0' },
130 silly resolved files: [ 'LICENSE', 'History.md', 'Readme.md', 'index.js', 'lib/' ],
130 silly resolved scripts:
130 silly resolved { test: 'mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/',
130 silly resolved 'test-cov': 'istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/',
130 silly resolved 'test-tap': 'mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/',
130 silly resolved 'test-travis': 'istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/' },
130 silly resolved gitHead: '08939683c7a2e5d7dc928d310ebab65878bffff3',
130 silly resolved bugs: { url: 'https://github.com/strongloop/express/issues' },
130 silly resolved _id: 'express@4.10.8',
130 silly resolved _shasum: '2d83571e065c0efb2679c0a5f9ae66aeaa47024a',
130 silly resolved _from: 'express@~4.10.1',
130 silly resolved _npmVersion: '1.4.28',
130 silly resolved _npmUser: { name: 'dougwilson', email: 'doug@somethingdoug.com' },
130 silly resolved maintainers:
130 silly resolved [ [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object],
130 silly resolved [Object] ],
130 silly resolved dist:
130 silly resolved { shasum: '2d83571e065c0efb2679c0a5f9ae66aeaa47024a',
130 silly resolved tarball: 'http://registry.npmjs.org/express/-/express-4.10.8.tgz' },
130 silly resolved directories: {},
130 silly resolved _resolved: 'https://registry.npmjs.org/express/-/express-4.10.8.tgz',
130 silly resolved readme: 'ERROR: No README data found!' },
130 silly resolved { name: 'socket.io',
130 silly resolved version: '1.2.1',
130 silly resolved description: 'node.js realtime framework server',
130 silly resolved keywords:
130 silly resolved [ 'realtime',
130 silly resolved 'framework',
130 silly resolved 'websocket',
130 silly resolved 'tcp',
130 silly resolved 'events',
130 silly resolved 'socket',
130 silly resolved 'io' ],
130 silly resolved repository: { type: 'git', url: 'git://github.com/Automattic/socket.io' },
130 silly resolved scripts: { test: 'make test' },
130 silly resolved dependencies:
130 silly resolved { 'engine.io': '1.4.3',
130 silly resolved 'socket.io-parser': '2.2.2',
130 silly resolved 'socket.io-client': '1.2.1',
130 silly resolved 'socket.io-adapter': '0.3.1',
130 silly resolved 'has-binary-data': '0.1.3',
130 silly resolved debug: '0.7.4' },
130 silly resolved devDependencies:
130 silly resolved { mocha: '1.16.2',
130 silly resolved 'expect.js': '0.3.1',
130 silly resolved supertest: '0.8.2',
130 silly resolved superagent: '0.17.0',
130 silly resolved istanbul: '0.2.3' },
130 silly resolved contributors: [ [Object], [Object], [Object], [Object] ],
130 silly resolved gitHead: '24d06d76ddf0808ac370e39fd57329d3048d73e4',
130 silly resolved bugs: { url: 'https://github.com/Automattic/socket.io/issues' },
130 silly resolved homepage: 'https://github.com/Automattic/socket.io',
130 silly resolved _id: 'socket.io@1.2.1',
130 silly resolved _shasum: '84400af534c0d32baa9ac88937eedb5b8465ee92',
130 silly resolved _from: 'socket.io@~1.2.0',
130 silly resolved _npmVersion: '1.4.21',
130 silly resolved _npmUser: { name: 'rauchg', email: 'rauchg@gmail.com' },
130 silly resolved maintainers: [ [Object] ],
130 silly resolved dist:
130 silly resolved { shasum: '84400af534c0d32baa9ac88937eedb5b8465ee92',
130 silly resolved tarball: 'http://registry.npmjs.org/socket.io/-/socket.io-1.2.1.tgz' },
130 silly resolved directories: {},
130 silly resolved _resolved: 'https://registry.npmjs.org/socket.io/-/socket.io-1.2.1.tgz',
130 silly resolved readme: 'ERROR: No README data found!' },
130 silly resolved { name: 'node-tail',
130 silly resolved version: '0.0.4',
130 silly resolved author: { name: 'rhrn', email: 'me@rhrn.ru' },
130 silly resolved preferGlobal: 'false',
130 silly resolved bin: { 'node-tail': './bin/node-tail' },
130 silly resolved dependencies: { 'socket.io': 'latest', commander: '~1.1.1' },
130 silly resolved repository: { type: 'git', url: 'https://github.com/rhrn/node-tail.git' },
130 silly resolved engines: { node: 'latest' },
130 silly resolved readme: '#node-tail\n\n Web `tail` - display last part of a file\n\n##install\n\n```\nnpm install -g node-tail\n```\n\n##usage\n\n```\nnode-tail -p 3000 ~/file.log\n```\n\nopen in browser\n```\nhttp://localhost:3000/\n```\n',
130 silly resolved readmeFilename: 'README.md',
130 silly resolved _id: 'node-tail@0.0.4',
130 silly resolved description: 'Web `tail` - display last part of a file',
130 silly resolved dist:
130 silly resolved { shasum: '60d6456c71a22427ebe794565cb1954709978501',
130 silly resolved tarball: 'http://registry.npmjs.org/node-tail/-/node-tail-0.0.4.tgz' },
130 silly resolved _from: 'node-tail@0.0.4',
130 silly resolved _npmVersion: '1.2.14',
130 silly resolved _npmUser: { name: 'rhrn', email: 'nester@bk.ru' },
130 silly resolved maintainers: [ [Object] ],
130 silly resolved directories: {},
130 silly resolved _shasum: '60d6456c71a22427ebe794565cb1954709978501',
130 silly resolved _resolved: 'https://registry.npmjs.org/node-tail/-/node-tail-0.0.4.tgz',
130 silly resolved bugs: { url: 'https://github.com/rhrn/node-tail/issues' },
130 silly resolved homepage: 'https://github.com/rhrn/node-tail' },
130 silly resolved { author: { name: 'Luca Grulla' },
130 silly resolved contributors: [ [Object], [Object], [Object] ],
130 silly resolved name: 'tail',
130 silly resolved description: 'tail a file in node',
130 silly resolved version: '0.4.0',
130 silly resolved repository:
130 silly resolved { type: 'git',
130 silly resolved url: 'git://github.com/lucagrulla/node-tail.git' },
130 silly resolved main: 'tail',
130 silly resolved engines: { node: '>= 0.4.0' },
130 silly resolved dependencies: {},
130 silly resolved devDependencies: { 'coffee-script': '1.7.1' },
130 silly resolved bugs: { url: 'https://github.com/lucagrulla/node-tail/issues' },
130 silly resolved homepage: 'https://github.com/lucagrulla/node-tail',
130 silly resolved _id: 'tail@0.4.0',
130 silly resolved scripts: {},
130 silly resolved _shasum: 'd29de72750cc99db1e053aff13c359ecfb713002',
130 silly resolved _from: 'tail@~0.4.0',
130 silly resolved _npmVersion: '1.4.15',
130 silly resolved _npmUser: { name: 'lucagrulla', email: 'luca.grulla@gmail.com' },
130 silly resolved maintainers: [ [Object] ],
130 silly resolved dist:
130 silly resolved { shasum: 'd29de72750cc99db1e053aff13c359ecfb713002',
130 silly resolved tarball: 'http://registry.npmjs.org/tail/-/tail-0.4.0.tgz' },
130 silly resolved directories: {},
130 silly resolved _resolved: 'https://registry.npmjs.org/tail/-/tail-0.4.0.tgz',
130 silly resolved readme: 'ERROR: No README data found!' } ]
131 info install express@4.10.8 into /mnt/hgfs/jumpserver/websocket
132 info install socket.io@1.2.1 into /mnt/hgfs/jumpserver/websocket
133 info install node-tail@0.0.4 into /mnt/hgfs/jumpserver/websocket
134 info install tail@0.4.0 into /mnt/hgfs/jumpserver/websocket
135 info installOne express@4.10.8
136 info installOne socket.io@1.2.1
137 info installOne node-tail@0.0.4
138 warn engine node-tail@0.0.4: wanted: {"node":"latest"} (current: {"node":"0.10.33","npm":"1.4.28"})
139 info installOne tail@0.4.0
140 verbose node_modules/express unbuild
141 verbose node_modules/socket.io unbuild
142 verbose node_modules/node-tail unbuild
143 verbose node_modules/tail unbuild
144 verbose tar unpack /root/.npm/express/4.10.8/package.tgz
145 silly lockFile de0ac3f3-r-websocket-node-modules-express tar:///mnt/hgfs/jumpserver/websocket/node_modules/express
146 verbose lock tar:///mnt/hgfs/jumpserver/websocket/node_modules/express /root/.npm/de0ac3f3-r-websocket-node-modules-express.lock
147 silly lockFile da9ae1a7-t-npm-express-4-10-8-package-tgz tar:///root/.npm/express/4.10.8/package.tgz
148 verbose lock tar:///root/.npm/express/4.10.8/package.tgz /root/.npm/da9ae1a7-t-npm-express-4-10-8-package-tgz.lock
149 verbose tar unpack /root/.npm/socket.io/1.2.1/package.tgz
150 silly lockFile 380be7e1-websocket-node-modules-socket-io tar:///mnt/hgfs/jumpserver/websocket/node_modules/socket.io
151 verbose lock tar:///mnt/hgfs/jumpserver/websocket/node_modules/socket.io /root/.npm/380be7e1-websocket-node-modules-socket-io.lock
152 silly lockFile d3c35dc3--npm-socket-io-1-2-1-package-tgz tar:///root/.npm/socket.io/1.2.1/package.tgz
153 verbose lock tar:///root/.npm/socket.io/1.2.1/package.tgz /root/.npm/d3c35dc3--npm-socket-io-1-2-1-package-tgz.lock
154 verbose tar unpack /root/.npm/node-tail/0.0.4/package.tgz
155 silly lockFile fe049280-websocket-node-modules-node-tail tar:///mnt/hgfs/jumpserver/websocket/node_modules/node-tail
156 verbose lock tar:///mnt/hgfs/jumpserver/websocket/node_modules/node-tail /root/.npm/fe049280-websocket-node-modules-node-tail.lock
157 silly lockFile 053f900c--npm-node-tail-0-0-4-package-tgz tar:///root/.npm/node-tail/0.0.4/package.tgz
158 verbose lock tar:///root/.npm/node-tail/0.0.4/package.tgz /root/.npm/053f900c--npm-node-tail-0-0-4-package-tgz.lock
159 verbose tar unpack /root/.npm/tail/0.4.0/package.tgz
160 silly lockFile 62713ce4-rver-websocket-node-modules-tail tar:///mnt/hgfs/jumpserver/websocket/node_modules/tail
161 verbose lock tar:///mnt/hgfs/jumpserver/websocket/node_modules/tail /root/.npm/62713ce4-rver-websocket-node-modules-tail.lock
162 silly lockFile 1ed23799--root-npm-tail-0-4-0-package-tgz tar:///root/.npm/tail/0.4.0/package.tgz
163 verbose lock tar:///root/.npm/tail/0.4.0/package.tgz /root/.npm/1ed23799--root-npm-tail-0-4-0-package-tgz.lock
164 silly gunzTarPerm modes [ '755', '644' ]
165 silly gunzTarPerm modes [ '755', '644' ]
166 silly gunzTarPerm modes [ '755', '644' ]
167 silly gunzTarPerm modes [ '755', '644' ]
168 silly gunzTarPerm extractEntry package.json
169 silly gunzTarPerm modified mode [ 'package.json', 438, 420 ]
170 silly gunzTarPerm extractEntry package.json
171 silly gunzTarPerm extractEntry package.json
172 silly gunzTarPerm extractEntry package.json
173 silly gunzTarPerm extractEntry LICENSE
174 silly gunzTarPerm modified mode [ 'LICENSE', 438, 420 ]
175 silly gunzTarPerm extractEntry index.js
176 silly gunzTarPerm modified mode [ 'index.js', 438, 420 ]
177 silly gunzTarPerm extractEntry .npmignore
178 silly gunzTarPerm extractEntry LICENSE
179 silly gunzTarPerm extractEntry .npmignore
180 silly gunzTarPerm extractEntry README.md
181 silly gunzTarPerm extractEntry README.md
182 silly gunzTarPerm extractEntry tail.js
183 error Error: EPERM, chown '/mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json'
183 error { [Error: EPERM, chown '/mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json']
183 error errno: 50,
183 error code: 'EPERM',
183 error path: '/mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json',
183 error fstream_finish_call: 'chown',
183 error fstream_type: 'File',
183 error fstream_path: '/mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json',
183 error fstream_class: 'FileWriter',
183 error fstream_stack:
183 error [ '/opt/node/lib/node_modules/npm/node_modules/fstream/lib/writer.js:308:19',
183 error '/opt/node/lib/node_modules/npm/node_modules/graceful-fs/polyfills.js:143:7',
183 error 'Object.oncomplete (evalmachine.<anonymous>:107:15)' ] }
184 error Please try running this command again as root/Administrator.
185 error System Linux 2.6.32-358.el6.x86_64
186 error command "/opt/node/bin/node" "/opt/node/bin/npm" "install"
187 error cwd /mnt/hgfs/jumpserver/websocket
188 error node -v v0.10.33
189 error npm -v 1.4.28
190 error path /mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json
191 error fstream_path /mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json
192 error fstream_type File
193 error fstream_class FileWriter
194 error fstream_finish_call chown
195 error code EPERM
196 error errno 50
197 error stack Error: EPERM, chown '/mnt/hgfs/jumpserver/websocket/node_modules/node-tail/package.json'
198 error fstream_stack /opt/node/lib/node_modules/npm/node_modules/fstream/lib/writer.js:308:19
198 error fstream_stack /opt/node/lib/node_modules/npm/node_modules/graceful-fs/polyfills.js:143:7
198 error fstream_stack Object.oncomplete (evalmachine.<anonymous>:107:15)
199 verbose exit [ 50, true ]

View File

@ -1,12 +0,0 @@
{
"name": "web-socket",
"version": "0.0.1",
"description": "my first realtime server",
"dependencies": {
"express": "~4.10.1",
"socket.io": "~1.2.0",
"node-tail": "0.0.4",
"tail": "~0.4.0",
"request": "~2.55.0"
}
}