Add sync command

## Problem

Syncing S3 buckets is long, it's hard to know how long it will take to sync a bucket, or what fails when it fails, what succeeds otherwise. Also, S3 sometimes has some crazy moments and errors on all requests. 
Which means this command should be pretty resilient to errors (it is).


## Solution

Reading a list of S3 keys from a file, we can track how far in the process we are and when it should be done. Saving the result to other files, we can track which key succeeded in syncing, which key failed to sync.

The work of syncing can also be distributed over many workers, since we can slice an S3 keys listing over many subfiles.

Reading and syncing at most `n` keys at a time means that the long process of syncing all the keys never use more than`O(n)` memory, which prevents running OOMs and swapping and pains.

## Implementation

Command `sync` reads the keys from a file and sync them from a __source__ bucket to a __destination__ bucket. Because S3 often errors, we retry errors on keys using a [triangular][1]* backoff, if they gave _retryable_ errors:

* Network errors
* S3 errors such as _SlowDown_, _Timeout_, _ServiceUnavailable_ and such.

By default, we retry 10 times. This means if 50% of S3 calls give retryable errors, the probability of missing out on an error that could have succeeded is 0.5**10 ~ 0.000975, or 9.75 times out of 10'000. Retrying 10 times will results in a short enough backoff to be worth it, wasting at most [55s][2] on a key that will never succeed to sync.

While 50% error rate seems big, I've observed (with previous version of this tool) spurious error periods from S3 that seem to resolve naturally after retrying a bit. I haven't observed such periods lasting more than 30s.

The sync command provides pluggable method for how the sync is to be done:

- PutCopy
- FetchPut intra AWS
- FetchPut, AWS -> GCS

Right now the only implementation is for PutCopy. The buckets can possibly be created with different AWS credentials, in which case PutCopy is impossible.

Test coverage is:

```bash
$ go test . -cover
ok  	github.com/Shopify/brigade/cmd/sync	5.482s	coverage: 87.8% of statements
```

Missing from the coverage are abort conditions and non-s3 errors. The non-s3 errors are usually network errors that are handled the same way as retryable errors: this class of error is tested.

It looks like this:

```insert pretty gif here```

r: @fbogsany, @camilo, @bouk, @boourns   
cc: @Shopify/webscale

`*` triangular backoff: I didn't actually know that was the name of the serie, wikipedia told me.
[1]: https://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF
[2]: http://www.wolframalpha.com/input/?i=sum%281+to+10%29
Another option is to use the zero value of the Options fields as the default and override it as it's used. For example, if you don't set `MaxRetry` then you can set it to a default in `syncOrRetry()`:

```go
const DefaultMaxRetry = 10

func (s *syncTask) syncOrRetry(src, dst *s3.Bucket, key s3.Key) (int, error) {
    // Default max retries here.
    maxretry := s.opt.MaxRetry
    if maxretry == 0 {
        maxretry = DefaultMaxRetry
    }

    // Do the rest of your function here.
    ...
}
```

Although, I don't think you necessarily need to have an options struct. I think it makes more sense to have the fields directly on SyncTask and separate out its instantiation and start functions:

```go
type SyncTask struct {
    MaxRetries int
    ...
}

func NewSyncTask(...) *SyncTask {
    return &SyncTask{
        MaxRetry: 10,
        ...
    }
}

func (t *SyncTask) Start() error {
    ...
}
```

Then you can instantiate a `SyncTask` with default settings using `NewSyncTask()` and change any defaults before you start it using `SyncTask.Start()`.