16328: Merge branch 'master' into 16328-keep-proxy-uses-config.yaml-to-find-keepstores
[arvados.git] / sdk / go / arvados / keep_service.go
index b29748a2247342a2497a4d4018e41da5174e471e..97a62fa7bb3933b89e83e428fc4da39de7453fcd 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
 package arvados
 
 import (
@@ -6,16 +10,27 @@ import (
        "net/http"
        "strconv"
        "strings"
+       "time"
 )
 
 // KeepService is an arvados#keepService record
 type KeepService struct {
-       UUID           string `json:"uuid"`
-       ServiceHost    string `json:"service_host"`
-       ServicePort    int    `json:"service_port"`
-       ServiceSSLFlag bool   `json:"service_ssl_flag"`
-       ServiceType    string `json:"service_type"`
-       ReadOnly       bool   `json:"read_only"`
+       UUID           string    `json:"uuid"`
+       ServiceHost    string    `json:"service_host"`
+       ServicePort    int       `json:"service_port"`
+       ServiceSSLFlag bool      `json:"service_ssl_flag"`
+       ServiceType    string    `json:"service_type"`
+       ReadOnly       bool      `json:"read_only"`
+       CreatedAt      time.Time `json:"created_at"`
+       ModifiedAt     time.Time `json:"modified_at"`
+}
+
+type KeepMount struct {
+       UUID           string          `json:"uuid"`
+       DeviceID       string          `json:"device_id"`
+       ReadOnly       bool            `json:"read_only"`
+       Replication    int             `json:"replication"`
+       StorageClasses map[string]bool `json:"storage_classes"`
 }
 
 // KeepServiceList is an arvados#keepServiceList record
@@ -73,10 +88,32 @@ func (s *KeepService) String() string {
        return s.UUID
 }
 
+func (s *KeepService) Mounts(c *Client) ([]KeepMount, error) {
+       url := s.url("mounts")
+       req, err := http.NewRequest("GET", url, nil)
+       if err != nil {
+               return nil, err
+       }
+       var mounts []KeepMount
+       err = c.DoAndDecode(&mounts, req)
+       if err != nil {
+               return nil, fmt.Errorf("GET %v: %v", url, err)
+       }
+       return mounts, nil
+}
+
+// Index returns an unsorted list of blocks at the given mount point.
+func (s *KeepService) IndexMount(c *Client, mountUUID string, prefix string) ([]KeepServiceIndexEntry, error) {
+       return s.index(c, s.url("mounts/"+mountUUID+"/blocks?prefix="+prefix))
+}
+
 // Index returns an unsorted list of blocks that can be retrieved from
 // this server.
 func (s *KeepService) Index(c *Client, prefix string) ([]KeepServiceIndexEntry, error) {
-       url := s.url("index/" + prefix)
+       return s.index(c, s.url("index/"+prefix))
+}
+
+func (s *KeepService) index(c *Client, url string) ([]KeepServiceIndexEntry, error) {
        req, err := http.NewRequest("GET", url, nil)
        if err != nil {
                return nil, fmt.Errorf("NewRequest(%v): %v", url, err)
@@ -85,7 +122,7 @@ func (s *KeepService) Index(c *Client, prefix string) ([]KeepServiceIndexEntry,
        if err != nil {
                return nil, fmt.Errorf("Do(%v): %v", url, err)
        } else if resp.StatusCode != 200 {
-               return nil, fmt.Errorf("%v: %v", url, resp.Status)
+               return nil, fmt.Errorf("%v: %d %v", url, resp.StatusCode, resp.Status)
        }
        defer resp.Body.Close()
 
@@ -93,6 +130,13 @@ func (s *KeepService) Index(c *Client, prefix string) ([]KeepServiceIndexEntry,
        scanner := bufio.NewScanner(resp.Body)
        sawEOF := false
        for scanner.Scan() {
+               if scanner.Err() != nil {
+                       // If we encounter a read error (timeout,
+                       // connection failure), stop now and return it
+                       // below, so it doesn't get masked by the
+                       // ensuing "badly formatted response" error.
+                       break
+               }
                if sawEOF {
                        return nil, fmt.Errorf("Index response contained non-terminal blank line")
                }