-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Save new/changed behavior on the robot through SSH #21
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,23 @@ | ||
{ | ||
"name": "FlexBE App", | ||
"version": "2.0.10", | ||
"name": "flexbe_app", | ||
"version": "2.0.11", | ||
"main": "src/main.js", | ||
"description": "flexbe_app provides a user interface (editor + runtime control) for the FlexBE behavior engine.", | ||
"license": "BSD-3-Clause", | ||
"repository": { | ||
"type": "git", | ||
"url": "[email protected]:FlexBE/flexbe_app.git" | ||
}, | ||
"readme": "README.md", | ||
"window": { | ||
"icon": "src/img/icon-128.png", | ||
"toolbar": false, | ||
"width": 1340, | ||
"height": 830, | ||
"min_width": 1340, | ||
"min_height": 650 | ||
}, | ||
"dependencies" : { | ||
"scp2" : "^0.5.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,13 +58,89 @@ IO.BehaviorSaver = new (function() { | |
} | ||
} | ||
|
||
String.prototype.format = function() { | ||
var formatted = this; | ||
for( var arg in arguments ) { | ||
formatted = formatted.replace("{" + arg + "}", arguments[arg]); | ||
} | ||
return formatted; | ||
}; | ||
|
||
var saveSuccessCallback = function() { | ||
T.logInfo("Save successful!"); | ||
UI.Panels.Terminal.hide(); | ||
UI.Settings.updateBehaviorlib(); | ||
UI.Tools.notifyRosCommand('save'); | ||
} | ||
} | ||
|
||
var saveOnRobot = function() { | ||
var names = Behavior.createNames(); | ||
var package_name = names.rosnode_name; | ||
var ssh_username = UI.Settings.getRobotUsername(); | ||
var ssh_hostname = UI.Settings.getRobotHostname(); | ||
var ssh_package_path = "" | ||
|
||
if(ssh_username === "" || ssh_hostname === "" /*|| ssh_password === ""*/) { | ||
T.logError("SSH configurations are not well defined, fix them from Configuration Tab -> Code Generation Box"); | ||
return; | ||
} | ||
|
||
var ssh_password = window.prompt("Please enter {0}:{1} password: ".format(ssh_username, ssh_hostname)); | ||
if(ssh_password == null || ssh_password == "") { | ||
return; | ||
} | ||
|
||
ROS.getPackagePath(package_name, (package_path) => | ||
{ | ||
try | ||
{ | ||
var SSHClient = require('ssh2').Client; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't ssh2 be an npm dependency as well? Even if included in scp2, it is referenced here directly. |
||
conn = new SSHClient(); | ||
conn.on('ready', function() { | ||
var ros_distro = process.env.ROS_DISTRO; | ||
conn.exec('bash -c "source .profile && rospack find {1}"'.format(ros_distro, package_name), function(err, stream) { | ||
if (err) { | ||
T.logError(err); | ||
} | ||
stream.on('close', function(code, signal) { | ||
conn.end(); | ||
}) | ||
.on('data', function(remote_package_path) { | ||
ssh_package_path = String(remote_package_path).trim(); | ||
T.logInfo('Path to package on the robot: ' + ssh_package_path); | ||
conn.end() | ||
var scp_client = require('scp2') | ||
var ssh_query = '{0}:{1}@{2}:{3}/'.format( | ||
ssh_username, | ||
ssh_password, | ||
ssh_hostname, | ||
ssh_package_path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This contains the password in plain text, right? Is there a way to encrypt? I have no experience with the scp2 package, but do you know how the query string would be further used? |
||
scp_client.scp(package_path+"/", String(ssh_query), function(err) { | ||
var err_str = String(err); | ||
if( err_str != 'undefined') { | ||
T.logError("scp failed "+err); | ||
} | ||
}); | ||
}).stderr.on('data', function(data) { | ||
T.logError(data+", Make sure robot's ROS environment is configured properly in \".profile\" script"); | ||
}) | ||
}); | ||
}) | ||
.on('error', function(err) { | ||
T.logError(err); | ||
T.logError("Please check your ssh configuration and entered password."); | ||
}) | ||
.connect({ | ||
host: ssh_hostname, | ||
username: ssh_username, | ||
password: ssh_password | ||
}); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if I understand the above code block correctly. To me it looks like there is an ssh connection created first and then, within this connection, another scp connection is opened to transfer the file. Do I get it wrong? Or what is the reason for this approach? |
||
catch(ex) { | ||
T.logError("An exception occurred: "+ex.message+", Make sure you installed the dependencies properly!") | ||
} | ||
}) | ||
} | ||
|
||
this.saveStateMachine = function() { | ||
T.clearLog(); | ||
|
@@ -91,15 +167,19 @@ IO.BehaviorSaver = new (function() { | |
return; | ||
} | ||
|
||
// store in file | ||
storeBehaviorCode(generated_code, () => { | ||
// make sure code file exists before creating the manifest | ||
// this reduces the risk for orphan manifests | ||
storeBehaviorManifest(generated_manifest, () => { | ||
saveSuccessCallback(); | ||
}); | ||
}); | ||
}); | ||
} | ||
// store in file | ||
storeBehaviorCode(generated_code, () => { | ||
// make sure code file exists before creating the manifest | ||
// this reduces the risk for orphan manifests | ||
storeBehaviorManifest(generated_manifest, () => { | ||
if(UI.Settings.isSaveOnRobotEnabled()) { | ||
//Save/Overwrite the behavior on the robot | ||
saveOnRobot(); | ||
} | ||
saveSuccessCallback(); | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
}) (); | ||
}) (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fails if npm is not installed. Do you see a way to automatically handle npm as a dependency?