Post date: Mar 19, 2016 12:25:16 AM
The next task was to add cloud support to the project. Since circuit simulation is computationally expensive and particularly students may not have high-end phones, it is desirable to offload the main computational load elsewhere. To do this, we use Secure Shell (SSH). SSH is a standard remote login utility for Linux and all modern unix-like operating systems, that also supports file transfer. Thus it fits or needs perfectly: Login to the remote machine, upload the netlist, execute ngspice and download the rawfile.
For using SSH from an Android app, or Java generally, a pure-Java implementation called JSch is the most mature solution. This supports most of the features of the SSH protocol and wraps them in relatively high level APIs. The only disadvantage to JSch is its poor documentation, only some examples that are overly verbose with non-android GUI code. However due to its maturity the library is well-discussed on Stack Overflow and blogs so this did not present a problem.
The flow we use here to to open a Jsch session (a.k.a a connection), and within that connectoin open two channels, one "exec" to run the process, and one "sftp" for all the file handling. We then upload the files, run the ngspice command remotely and download the results. The API is very high-level, the ChannelSFTP object having get(name, File) and put(File, name) methods, and the ChannelExec presenting a somewhat process-builder like interface.
Since this is likely to take some time, this an AsyncTask called SshAsyncTask was written to run this. This uses the exact same callbacks as the ProcessAsyncTask used to run locally to ease integration, though obviously slightly different parameters. SpiceRunner was then modified to check whether a local or remote run is desired and to call the appropriate function.
The SSH host and login details have to be configurable. To do this a PreferencesActivity was created, since this autogenerates much of the required user interface and SharedPreferences updates from a small XML file.
A binary option of use ssh or not was added, as well as text ields for SSH hostname, port, username and passwords.
A SshLoginDetails class was also created to represent a set of these, and given a member checkSshLoginDetails(Context) reads the details from the preferences database and returns either the configured set or null if SSH is disabled and a local run is desired.
Two further challenges were encountered. First JSch does host key checking by default, so we set a preference to disable this (JSch exports an config interface resembling the key-value pairs of an ssh.confg). A better solution would be to maintain a known hosts database properly,.
Secondly the remote hosts SSH server only allows clients to set certain environment variables. This is to prevent hacking the dynamic linker. Thus initially when SPICE ran it would complete but produce a binary rawfile since the SPICE_ASCIIRAWFILE varaiable was filtered. To resolve this, the hosts configuration had to be modified by adding "AcceptEnv SPICE*".
At present a login to a regular user is used. This is acceptable for proof of concept on the app side, however if providing a compute utility to many people it would be necessary to create severly limited user accounts that can only access their home directories and only run NGSPICE. This is beyond the scope of this project, but some research into the feasibility was done. A combination of chroot and the restricted shell (rsh) would prevent most file accesses. Then Linux cgroups could provide additional limits. nss_mysql allows the user database for a linux system to be taken from a mysql database (instead of LDAP) and thus a web management service could provision users easily. Using these, it is clear that an appropriate compute utility server could be constructed.
Further improvements on the client would be the use of SSH public-key login and enforcing hosts keys.