~snappy-dev/snappy/trunk-github

« back to all changes in this revision

Viewing changes to snappy/snap_remote_repo.go

  • Committer: Zygmunt Krynicki
  • Date: 2016-02-05 11:26:28 UTC
  • mfrom: (1131)
  • mto: This revision was merged to the branch mainline in revision 1137.
  • Revision ID: git-v1:2f4cd12f5eb1dde16f4e7b59561026d0d125f377
Merge branch 'master' of github.com:ubuntu-core/snappy into cmd-output-testing

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
        "bytes"
24
24
        "encoding/json"
25
25
        "fmt"
 
26
        "io"
 
27
        "io/ioutil"
26
28
        "net/http"
27
29
        "net/url"
28
30
        "os"
31
33
 
32
34
        "github.com/ubuntu-core/snappy/arch"
33
35
        "github.com/ubuntu-core/snappy/oauth"
 
36
        "github.com/ubuntu-core/snappy/progress"
34
37
        "github.com/ubuntu-core/snappy/release"
35
38
        "github.com/ubuntu-core/snappy/snap"
36
39
        "github.com/ubuntu-core/snappy/snap/remote"
188
191
        return fmt.Sprintf("Snap remote repository for %s", s.searchURI)
189
192
}
190
193
 
191
 
// Details returns details for the given snap in this repository
192
 
func (s *SnapUbuntuStoreRepository) Details(name string, origin string) (parts []Part, err error) {
193
 
        snapName := name
194
 
        if origin != "" {
195
 
                snapName = name + "." + origin
196
 
        }
 
194
// Snap returns the RemoteSnapPart for the given name or an error.
 
195
func (s *SnapUbuntuStoreRepository) Snap(snapName string) (*RemoteSnapPart, error) {
197
196
 
198
197
        url, err := s.detailsURI.Parse(snapName)
199
198
        if err != nil {
220
219
        case resp.StatusCode == 404:
221
220
                return nil, ErrPackageNotFound
222
221
        case resp.StatusCode != 200:
223
 
                return parts, fmt.Errorf("SnapUbuntuStoreRepository: unexpected http statusCode %v for %s", resp.StatusCode, snapName)
 
222
                return nil, fmt.Errorf("SnapUbuntuStoreRepository: unexpected HTTP status code %d while looking forsnap %q", resp.StatusCode, snapName)
224
223
        }
225
224
 
226
225
        // and decode json
230
229
                return nil, err
231
230
        }
232
231
 
233
 
        snap := NewRemoteSnapPart(detailsData)
234
 
        parts = append(parts, snap)
 
232
        return NewRemoteSnapPart(detailsData), nil
 
233
}
235
234
 
236
 
        return parts, nil
 
235
// Details returns details for the given snap in this repository
 
236
func (s *SnapUbuntuStoreRepository) Details(name string, origin string) (parts []Part, err error) {
 
237
        snapName := name
 
238
        if origin != "" {
 
239
                snapName = name + "." + origin
 
240
        }
 
241
        snap, err := s.Snap(snapName)
 
242
        if err != nil {
 
243
                return nil, err
 
244
        }
 
245
        return []Part{snap}, nil
237
246
}
238
247
 
239
248
// All (installable) parts from the store
383
392
func (s *SnapUbuntuStoreRepository) Installed() (parts []Part, err error) {
384
393
        return nil, err
385
394
}
 
395
 
 
396
// Download downloads the given snap and returns its filename.
 
397
// The file is saved in temporary storage, and should be removed
 
398
// after use to prevent the disk from running out of space.
 
399
func (s *SnapUbuntuStoreRepository) Download(remoteSnap *RemoteSnapPart, pbar progress.Meter) (path string, err error) {
 
400
        w, err := ioutil.TempFile("", remoteSnap.pkg.Name)
 
401
        if err != nil {
 
402
                return "", err
 
403
        }
 
404
        defer func() {
 
405
                if cerr := w.Close(); cerr != nil && err == nil {
 
406
                        err = cerr
 
407
                }
 
408
                if err != nil {
 
409
                        os.Remove(w.Name())
 
410
                        path = ""
 
411
                }
 
412
        }()
 
413
 
 
414
        // try anonymous download first and fallback to authenticated
 
415
        url := remoteSnap.pkg.AnonDownloadURL
 
416
        if url == "" {
 
417
                url = remoteSnap.pkg.DownloadURL
 
418
        }
 
419
        req, err := http.NewRequest("GET", url, nil)
 
420
        if err != nil {
 
421
                return "", err
 
422
        }
 
423
        setUbuntuStoreHeaders(req)
 
424
 
 
425
        if err := download(remoteSnap.Name(), w, req, pbar); err != nil {
 
426
                return "", err
 
427
        }
 
428
 
 
429
        return w.Name(), w.Sync()
 
430
}
 
431
 
 
432
// download writes an http.Request showing a progress.Meter
 
433
var download = func(name string, w io.Writer, req *http.Request, pbar progress.Meter) error {
 
434
        client := &http.Client{}
 
435
 
 
436
        resp, err := client.Do(req)
 
437
        if err != nil {
 
438
                return err
 
439
        }
 
440
        defer resp.Body.Close()
 
441
 
 
442
        if resp.StatusCode != 200 {
 
443
                return &ErrDownload{Code: resp.StatusCode, URL: req.URL}
 
444
        }
 
445
 
 
446
        if pbar != nil {
 
447
                pbar.Start(name, float64(resp.ContentLength))
 
448
                mw := io.MultiWriter(w, pbar)
 
449
                _, err = io.Copy(mw, resp.Body)
 
450
                pbar.Finished()
 
451
        } else {
 
452
                _, err = io.Copy(w, resp.Body)
 
453
        }
 
454
 
 
455
        return err
 
456
}