INT32 _sptUsrSsh::construct( const _sptArguments &arg, _sptReturnVal &rval, bson::BSONObj &detail) { INT32 rc = SDB_OK ; string passwd ; string errmsg ; INT32 port = SPT_SSH_PORT ; rc = arg.getString( 0, _host ) ; if ( SDB_OUT_OF_BOUND == rc ) { detail = BSON( SPT_ERR << "hostname must be config" ) ; } else if ( rc ) { detail = BSON( SPT_ERR << "hostname must be string" ) ; } PD_RC_CHECK( rc, PDERROR, "Failed to get hostname, rc: %d", rc ) ; rc = arg.getString( 1, _user ) ; if ( rc && SDB_OUT_OF_BOUND != rc ) { detail = BSON( SPT_ERR << "user must be string" ) ; PD_RC_CHECK( rc, PDERROR, "Failed to get user, rc: %d", rc ) ; } rc = arg.getString( 2, passwd ) ; if ( rc && SDB_OUT_OF_BOUND != rc ) { detail = BSON( SPT_ERR << "password must be string" ) ; PD_RC_CHECK( rc, PDERROR, "Failed to get password, rc: %d", rc ) ; } rc = arg.getNative( 3, (void*)&port, SPT_NATIVE_INT32 ) ; if ( rc && SDB_OUT_OF_BOUND != rc ) { detail = BSON( SPT_ERR << "port must be uint or int" ) ; PD_RC_CHECK( rc, PDERROR, "Failed to get port, rc: %d", rc ) ; } _session = SDB_OSS_NEW _sptLibssh2Session( _host.c_str(), _user.c_str(), passwd.c_str(), &port ) ; if ( NULL == _session ) { PD_LOG( PDERROR, "failed to allocate mem." ) ; rc = SDB_OOM ; goto error ; } rc = _session->open() ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to open ssh session:%d", rc ) ; _session->getLastError( errmsg ) ; goto error ; } _localIP = _session->getLocalIPAddr() ; _peerIP = _session->getPeerIPAddr() ; rval.addSelfProperty("_host")->setValue( _host ) ; rval.addSelfProperty("_port")->setValue( port ) ; rval.addSelfProperty("_usrname")->setValue( _user ) ; done: return rc ; error: SAFE_OSS_DELETE( _session ) ; if ( detail.isEmpty() ) { if ( !errmsg.empty() ) { detail = BSON( SPT_ERR << errmsg ) ; } else { detail = BSON( SPT_ERR << "failed to ssh to specified host" ) ; } } goto done ; }
INT32 _sptUsrCmd::start( const _sptArguments & arg, _sptReturnVal & rval, BSONObj & detail ) { INT32 rc = SDB_OK ; string ev ; ossCmdRunner runner ; UINT32 useShell = TRUE ; UINT32 usePipe = TRUE ; _command.clear() ; rc = arg.getString( 0, _command ) ; if ( SDB_OK != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "cmd must be config" ) ; goto error ; } utilStrTrim( _command ) ; rc = arg.getString( 1, ev ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "environment should be a string" ) ; goto error ; } else if ( SDB_OK == rc ) { _command += " " ; _command += ev ; } // useShell, default : 1 rc = arg.getNative( 2, (void*)&useShell, SPT_NATIVE_INT32 ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "useShell should be a number" ) ; goto error ; } rc = SDB_OK ; // usePipe, default : 1 rc = arg.getNative( 3, (void*)&usePipe, SPT_NATIVE_INT32 ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "usePipe should be a number" ) ; goto error ; } rc = SDB_OK ; _strOut = "" ; _retCode = 0 ; rc = runner.exec( _command.c_str(), _retCode, TRUE, -1, FALSE, NULL, useShell ? TRUE : FALSE, usePipe ? TRUE : FALSE ) ; if ( SDB_OK != rc ) { stringstream ss ; ss << "run[" << _command << "] failed" ; detail = BSON( SPT_ERR << ss.str() ) ; goto error ; } else { OSSPID pid = runner.getPID() ; rval.setNativeVal( "", NumberInt, (const void*)&pid ) ; if ( usePipe ) { ossSleep( 100 ) ; if ( !ossIsProcessRunning( pid ) ) { rc = runner.read( _strOut ) ; if ( rc ) { stringstream ss ; ss << "read run command[" << _command << "] result failed" ; detail = BSON( SPT_ERR << ss.str() ) ; goto error ; } } } } done: return rc ; error: goto done ; }
INT32 _sptUsrSsh::copyFromRemote( const _sptArguments &arg, _sptReturnVal &rval, bson::BSONObj &detail ) { INT32 rc = SDB_OK ; string remote ; string local ; INT32 mode = 0 ; string errMsg ; rc = arg.getString( 0, remote ) ; if ( SDB_OUT_OF_BOUND == rc ) { detail = BSON( SPT_ERR << "remote_file must be config" ) ; } else if ( rc ) { detail = BSON( SPT_ERR << "remote_file must be string" ) ; } PD_RC_CHECK( rc, PDERROR, "Failed to get remote_file, rc: %d", rc ) ; rc = arg.getString( 1, local ) ; if ( SDB_OUT_OF_BOUND == rc ) { detail = BSON( SPT_ERR << "local_file must be config" ) ; } else if ( rc ) { detail = BSON( SPT_ERR << "local_file must be string" ) ; } PD_RC_CHECK( rc, PDERROR, "Failed to get local_file, rc: %d", rc ) ; rc = arg.getNative( 2, &mode, SPT_NATIVE_INT32 ) ; if ( rc && SDB_OUT_OF_BOUND != rc ) { detail = BSON( SPT_ERR << "mode must be native type" ) ; PD_RC_CHECK( rc, PDERROR, "Failed to get mode, rc: %d", rc ) ; } if ( !_session->isOpened() ) { detail = BSON( SPT_ERR << "connection is shutdown" ) ; rc = SDB_NETWORK ; goto error ; } rc = _session->copyFromRemote( SPT_CP_PROTOCOL_SCP, remote.c_str(), local.c_str(), mode ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to copy file:%d", rc ) ; _session->getLastError( errMsg ) ; goto error ; } done: return rc ; error: if ( !errMsg.empty() ) { detail = BSON( SPT_ERR << errMsg ) ; } goto done ; }
INT32 _sptUsrCmd::exec( const _sptArguments &arg, _sptReturnVal &rval, bson::BSONObj &detail ) { INT32 rc = SDB_OK ; string ev ; UINT32 timeout = 0 ; UINT32 useShell = TRUE ; ossCmdRunner runner ; _command.clear() ; rc = arg.getString( 0, _command ) ; if ( SDB_OK != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "cmd must be config" ) ; goto error ; } utilStrTrim( _command ) ; rc = arg.getString( 1, ev ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "environment should be a string" ) ; goto error ; } else if ( SDB_OK == rc && !ev.empty() ) { _command += " " ; _command += ev ; } rc = arg.getNative( 2, (void*)&timeout, SPT_NATIVE_INT32 ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "timeout should be a number" ) ; goto error ; } rc = SDB_OK ; // useShell, default : 1 rc = arg.getNative( 3, (void*)&useShell, SPT_NATIVE_INT32 ) ; if ( SDB_OK != rc && SDB_OUT_OF_BOUND != rc ) { rc = SDB_INVALIDARG ; detail = BSON( SPT_ERR << "useShell should be a number" ) ; goto error ; } rc = SDB_OK ; _strOut = "" ; _retCode = 0 ; rc = runner.exec( _command.c_str(), _retCode, FALSE, 0 == timeout ? -1 : (INT64)timeout, FALSE, NULL, useShell ? TRUE : FALSE ) ; if ( SDB_OK != rc ) { stringstream ss ; ss << "run[" << _command << "] failed" ; detail = BSON( SPT_ERR << ss.str() ) ; goto error ; } else { rc = runner.read( _strOut ) ; if ( rc ) { stringstream ss ; ss << "read run command[" << _command << "] result failed" ; detail = BSON( SPT_ERR << ss.str() ) ; goto error ; } else if ( SDB_OK != _retCode ) { detail = BSON( SPT_ERR << _strOut ) ; rc = _retCode ; goto error ; } rval.setStringVal( "", _strOut.c_str() ) ; } done: return rc ; error: goto done ; }