ssh-wrapper: perf optimizations
- make key timestamp update pure sql so we don't generate model import overhead - code cleanups
This commit is contained in:
parent
7486eea956
commit
c3da01c179
2 changed files with 52 additions and 20 deletions
|
|
@ -23,8 +23,9 @@ import re
|
|||
import logging
|
||||
import datetime
|
||||
import configparser
|
||||
from sqlalchemy import Table
|
||||
|
||||
from rhodecode.model.db import Session, User, UserSshKeys
|
||||
from rhodecode.lib.utils2 import AttributeDict
|
||||
from rhodecode.model.scm import ScmModel
|
||||
|
||||
from .hg import MercurialServer
|
||||
|
|
@ -39,11 +40,11 @@ class SshWrapper(object):
|
|||
svn_cmd_pat = re.compile(r'^svnserve -t')
|
||||
|
||||
def __init__(self, command, connection_info, mode,
|
||||
user, user_id, key_id, shell, ini_path, env):
|
||||
user, user_id, key_id: int, shell, ini_path: str, env):
|
||||
self.command = command
|
||||
self.connection_info = connection_info
|
||||
self.mode = mode
|
||||
self.user = user
|
||||
self.username = user
|
||||
self.user_id = user_id
|
||||
self.key_id = key_id
|
||||
self.shell = shell
|
||||
|
|
@ -59,14 +60,38 @@ class SshWrapper(object):
|
|||
return parser
|
||||
|
||||
def update_key_access_time(self, key_id):
|
||||
key = UserSshKeys().query().filter(
|
||||
UserSshKeys.ssh_key_id == key_id).scalar()
|
||||
if key:
|
||||
key.accessed_on = datetime.datetime.utcnow()
|
||||
Session().add(key)
|
||||
Session().commit()
|
||||
from rhodecode.model.meta import raw_query_executor, Base
|
||||
|
||||
table = Table('user_ssh_keys', Base.metadata, autoload=False)
|
||||
stmt = (
|
||||
table.update()
|
||||
.where(table.c.ssh_key_id == key_id)
|
||||
.values(accessed_on=datetime.datetime.utcnow())
|
||||
.returning(table.c.accessed_on, table.c.ssh_key_fingerprint)
|
||||
)
|
||||
|
||||
scalar_res = None
|
||||
with raw_query_executor() as session:
|
||||
result = session.execute(stmt)
|
||||
if result.rowcount:
|
||||
scalar_res = result.first()
|
||||
|
||||
if scalar_res:
|
||||
atime, ssh_key_fingerprint = scalar_res
|
||||
log.debug('Update key id:`%s` fingerprint:`%s` access time',
|
||||
key_id, key.ssh_key_fingerprint)
|
||||
key_id, ssh_key_fingerprint)
|
||||
|
||||
def get_user(self, user_id):
|
||||
user = AttributeDict()
|
||||
# lazy load db imports
|
||||
from rhodecode.model.db import User
|
||||
dbuser = User.get(user_id)
|
||||
if not dbuser:
|
||||
return None
|
||||
user.user_id = dbuser.user_id
|
||||
user.username = dbuser.username
|
||||
user.auth_user = dbuser.AuthUser()
|
||||
return user
|
||||
|
||||
def get_connection_info(self):
|
||||
"""
|
||||
|
|
@ -186,7 +211,7 @@ class SshWrapper(object):
|
|||
|
||||
def wrap(self):
|
||||
mode = self.mode
|
||||
user = self.user
|
||||
username = self.username
|
||||
user_id = self.user_id
|
||||
key_id = self.key_id
|
||||
shell = self.shell
|
||||
|
|
@ -194,29 +219,30 @@ class SshWrapper(object):
|
|||
scm_detected, scm_repo, scm_mode = self.get_repo_details(mode)
|
||||
|
||||
log.debug(
|
||||
'Mode: `%s` User: `%s:%s` Shell: `%s` SSH Command: `\"%s\"` '
|
||||
'Mode: `%s` User: `name:%s : id:%s` Shell: `%s` SSH Command: `\"%s\"` '
|
||||
'SCM_DETECTED: `%s` SCM Mode: `%s` SCM Repo: `%s`',
|
||||
mode, user, user_id, shell, self.command,
|
||||
mode, username, user_id, shell, self.command,
|
||||
scm_detected, scm_mode, scm_repo)
|
||||
|
||||
# update last access time for this key
|
||||
self.update_key_access_time(key_id)
|
||||
|
||||
log.debug('SSH Connection info %s', self.get_connection_info())
|
||||
|
||||
# update last access time for this key
|
||||
if key_id:
|
||||
self.update_key_access_time(key_id)
|
||||
|
||||
if shell and self.command is None:
|
||||
log.info('Dropping to shell, no command given and shell is allowed')
|
||||
os.execl('/bin/bash', '-l')
|
||||
exit_code = 1
|
||||
|
||||
elif scm_detected:
|
||||
user = User.get(user_id)
|
||||
user = self.get_user(user_id)
|
||||
if not user:
|
||||
log.warning('User with id %s not found', user_id)
|
||||
exit_code = -1
|
||||
return exit_code
|
||||
|
||||
auth_user = user.AuthUser()
|
||||
auth_user = user.auth_user
|
||||
permissions = auth_user.permissions['repositories']
|
||||
repo_branch_permissions = auth_user.get_branch_permissions(scm_repo)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ SQLAlchemy Metadata and Session object
|
|||
|
||||
from sqlalchemy.orm import declarative_base
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
|
||||
from sqlalchemy.orm import Session as SASession
|
||||
from rhodecode.lib import caching_query
|
||||
|
||||
__all__ = ['Base', 'Session']
|
||||
__all__ = ['Base', 'Session', 'raw_query_executor']
|
||||
|
||||
# scoped_session. Apply our custom CachingQuery class to it,
|
||||
# using a callable that will associate the dictionary
|
||||
|
|
@ -43,3 +43,9 @@ Session = scoped_session(
|
|||
|
||||
# The declarative Base
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
def raw_query_executor():
|
||||
engine = Base.metadata.bind
|
||||
session = SASession(engine)
|
||||
return session
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue