ExpanDrive Blog

Development news on ExpanDrive and Strongspace

Strongspace and Cyberduck for the Mac

Jeff Mancuso March 24th, 2011    

Cyberduck is a great free SFTP client that you can use to connect to Strongspace. It’s available for both Mac and Windows.

One of the benefits of using an SFTP client like Cyberduck or Transmit is that it makes it easy to upload and download entire folders of files at once. They also allow you to easily restart a large upload or download that might’ve been interrupted.

Access Strongspace with Transmit via SFTP

Jeff Mancuso March 24th, 2011    

Here is a short screencast showing how to connect to Strongspace using Transmit via SFTP.

Commerical support for ZFS on OS X

Jeff Mancuso March 16th, 2011    

Found over on the macos-x-server mailing list: It looks like Don Brady, a former senior engineer at Apple, has started a company to finally bring ZFS to OS X

His company name is named Ten’s Compliment and he’s on on Twitter as @tenscomplement.

Very cool! Good luck Don!

ZFS+rsync = Time Machine in the Cloud

Jeff Mancuso February 15th, 2011    

I’m very happy to announce that we’re making public the beta for Strongspace.app for the Mac. The app provides continuous realtime backup, currently within a 10 minute window, of any folder on your Mac. It’s dead simple, it’s based on rsync, it’s being developed in public on GitHub and it just works. Here’s a screenshot, simple – right?

Add any other folder, and it gets pushed right up to Strongspace. Once it’s there, you can share any file or folder with one click via the web interface.

In addition, Strongspace.app automatically takes a full ZFS snapshot of everything you’re backing up once per hour and thins snapshots out to daily and weekly snapshots, just like Apple Time Machine.

It’s kind of like Time Machine in the cloud – pushing your data safely onto ZFS and letting you share anything, with anyone, using only one click.

Download the latest version here

We’re currently testing builds for Windows and should have a release in a matter of weeks.

Strongspace Files API

Jeff Mancuso December 16th, 2010    

Here is the API for managing files on Strongspace. Just like the rest of the API, successful API calls return HTTP status codes in the 200s and errors have codes 400 and higher.

Upload a file

POST /api/v1/files/:

Example:

$ curl -u hemancuso/token:******* -F file=@jeff.jpg https://www.strongspace.com/api/v1/files/hemancuso/home/jeff.jpg

Will return something like this

{"status":"success"}
{"status":"file already exists"}
{"status":"permission denied"}

Download a file

GET /api/v1/files/:path

Example:

$ curl -O -u hemancuso/token:******* https://www.strongspace.com/api/v1/files/hemancuso/home/jeff.jpg

Success returns the bytes of the file. In the example above -O indicates to write the stream to disk with the inferred name of the remote file.

Errors:

{"status":"permission denied"}
{"status":"not a file"}

Create a Folder

POST /api/v1/files/:path
   :op=mkdir

Example:

$ curl -u hemancuso/token:******* -F op=mkdir https://www.strongspace.com/api/v1/files/hemancuso/home/some_folder

Will return something like this

{"status":"success"}
{"status":"folder already exists"}
{"status":"permission denied"}

Delete a file or folder

This command deletes a file or recursively deletes a folder and everything inside of it.

DELETE /api/v1/files/:path

Example:

$ curl -X DELETE -u hemancuso/token:*******  https://www.strongspace.com/api/v1/files/hemancuso/home/jeff.jpg

Will return something like this

{"status":"success"}
{"status":"permission denied"}
{"status":"you can't delete an entire space"}

Copy or Move

PUT /api/v1/files/:path
    :op=[copy/move]
    :srcpath=[path, such as /jmancuso/home/original]

Example:

curl -X PUT -u hemancuso/token:******* -F op=move -F srcpath=/hemancuso/home/jeff.jpg https://www.strongspace.com/api/v1/files/jmancuso/home/jeff2.jpg

Will return something like this

{"status":"success"}
{"status":"permission denied"}
{"status":"destination file already exists"}
{"status":"source doesn't exist"}

Managing files via the command-line

Jeff Mancuso December 8th, 2010    

We just pushed out version 0.0.5 of our Strongspace Ruby Gem and command line utility – this adds the ability to upload, download, mkdir and delete files and folders from the command line. Since it is all in Ruby it works great on Mac, Windows, Linux and Solaris or wherever else you’ve got Ruby.

To install or update run sudo gem install strongspace

The updated command set:

$ strongspace help
=== General Commands
help                                              # show this usage
version                                           # show the gem version

upload <local_file> <remote_path>                 # upload a file
download <remote_path>                            # download a file from Strongspace to the current directory
mkdir <remote_path>                               # create a folder on Strongspace
delete <remote_path>                              # delete a file or recursively delete a folder on Strongspace

keys                                              # show your user's public keys
keys:add [<path to keyfile>]                      # add a public key
keys:remove <id>                                  # remove a key by id
keys:clear                                        # remove all keys

spaces                                            # show your user's spaces
spaces:create <space_name> [type]                 # add a new space. type => (normal,public,backup)
spaces:delete <space_name> [type]                 # remove a space by and destroy its data
spaces:snapshots <space_name>                     # show a space's snapshots
spaces:create_snapshot <space_name@snapshot_name> # take a space of a space.
spaces:delete_snapshot <space_name@snapshot_name> # remove a snapshot from a space

Strongspace SSH Keys API

Jeff Mancuso December 7th, 2010    

Here is the API for listing, creating and removing SSH Keys. Successful API calls return HTTP status codes in the 200s and errors have codes 400 and higher. This will be documented more fully in the future when we’ve settled on all the error codes across a wider array of functions.

The prettyjson command is optional, just for readability.

List your SSH Keys

GET /api/v1/ssh_keys

Example:

curl -u hemancuso/token:***** https://www.strongspace.com/api/v1/ssh_keys | prettyjson
{
    "ssh_keys": [
        {
            "name": "jmancuso@mactop.local", 
            "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIw......Az4GLQHoVcyw== jmancuso@mactop.local", 
            "id": 1
        }, 
        {
            "name": "jmancuso@blog.expandrive.com", 
            "key": "ssh-dss AAAAB3NzaC...ovUGhwtD41cHgxEzBeVvjkcN4= root@db1.expandrive.com", 
            "id": 2
        }
    ]
}

Add SSH key

POST /api/v1/ssh_keys
      :key
      :name [optional - key nickname]

Example:

curl -u hemancuso/token:***** -F 'key=ssh-dss AAAAB3NzaC1kc3MAAACBAL....HgxEzBeVvjkcN4= jmancuso@blog.expandrive.com' https://www.strongspace.com/api/v1/ssh_keys
{"status": "ok"}

If the key already exits, it returns an error code and the body:

{"status":"duplicate key"}

Delete SSH key

DELETE /api/v1/ssh_keys/:id

Example:

 curl -X DELETE -u hemancuso/token:*****  https://www.strongspace.com/api/v1/ssh_keys/2
 {"status": "ok"}

If the key doesn’t exist or user doesn’t have access:

{"status": "permission denied"}

Strongspace API Authentication

Jeff Mancuso December 7th, 2010    

This is the first public facing API we’ve developed and we spent considerable effort examining other successful APIs for inspiration. We wanted an intuitive RESTful API that always returned JSON and didn’t have a bunch of crufty stuff surrounding every request. APIs which require a bunch of custom headers on every request or have uncommon authentication schemes present a significant barrier to entry to the average programmer unless a robust client library already exists in their favorite language.

For authentication, we really like Github’s model. All authentication happens via HTTP basic over HTTPS and can take two forms. First, you can authenticate your regular username and password. Or, you can use an API token as your password and add “/token” to your username, just like Github. Unlike Github, if you change your password for Strongspace, your API token does not change. Also all Strongspace API requests must be performed via HTTPS.

To retrieve your API token:

GET /api/v1/api_token
     :reset = "true" [optional - generates a new API token]

Examples:

curl -u username:password https://www.strongspace.com/api/v1/api_token
curl -u username:password https://www.strongspace.com/api/v1/api_token?reset=true

returns the JSON:

{"api_token":"your_api_token"}

Strongspace API and command-line utility

Jeff Mancuso December 6th, 2010    

We’ve been working hard for the past couple weeks putting together a REST API for Strongspace and I’m going to write a series of posts this week documenting and showing how to use it. The easiest way to get going is to try out our Gem which includes a command-line utility named ‘strongspace’. To install the gem fire up a terminal and type

gem install strongspace

This installs the Strongspace library and makes accessible a strongspace command that you can call

$ strongspace help prints a list of available commands

=== General Commands

help                                               # show this usage
version                                            # show the gem version


keys                                               # show your user's public keys
keys:add [<path to keyfile>]                       # add a public key
keys:remove <id>                                   # remove a key by id
keys:clear                                         # remove all keys


spaces                                             # show your user's spaces
spaces:create <space_name> [type]                  # add a new space. type => (normal,public,backup)
spaces:destroy <space_name> [type]                 # remove a space by and destroy its data
spaces:snapshots <space_name>                      # show a space's snapshots
spaces:create_snapshot <space_name@snapshot_name>  # take a space of a space.
spaces:destroy_snapshot <space_name@snapshot_name> # remove a snapshot from a space

Much more coming soon, stay tuned.

ExpanDrive and the Mac App Store

Jeff Mancuso October 21st, 2010    

Yesterday Apple announced that the App Store was coming to the Mac. Exciting news for app developers, but much more exciting for the 3.89 million new Mac owners every quarter trying to discover, install and keep software up to date. Not unsurprisingly, there is a laundry list of restrictions and requirements for apps trying to make it into the App Store. That list, while not yet formally published, has been leaked. It looks as if section 2.18 will keep apps that rely on kernel extensions, like ExpanDrive, which relies on MacFUSE, out of the App Store or require developers to create watered down App Store Only forks of their product.

Section 2.18:

Apps that install kexts will be rejected

We hope this means “Apps that install kernel extensions globally into /System will be rejected” (which we currently do) and not “Apps that load non-Apple kernel extensions will be rejected” If this is an issue about packaging, then namespacing a kernel extension to an app and keeping it inside the bundle is a reasonable request and and something we’ll likely do anyways. It would be a real disappointment if Apple starts to lock down the Mac as it continues to progress towards iOS/OS X unity. Perhaps this is much ado about nothing and it’ll merely require us not to install anything globally, but it’s hard to imagine that will be the case.