14745: Makes DeleteDanglingResourcesAfter an arvados.Duration
authorEric Biagiotti <ebiagiotti@veritasgenetcs.com>
Mon, 11 Feb 2019 19:59:15 +0000 (14:59 -0500)
committerEric Biagiotti <ebiagiotti@veritasgenetcs.com>
Mon, 11 Feb 2019 19:59:15 +0000 (14:59 -0500)
Arvados-DCO-1.1-Signed-off-by: Eric Biagiotti <eric.biagiotti@gmail.com>

lib/cloud/azure/azure.go
lib/cloud/azure/azure_test.go
sdk/go/arvados/duration.go

index 2a63d28f6575145508c5bba21392be4b852346d5..be7aa3cf46ed9cee928a78fd3cc7344a0bb4e63f 100644 (file)
@@ -32,18 +32,18 @@ import (
 )
 
 type AzureInstanceSetConfig struct {
-       SubscriptionID               string  "SubscriptionID"
-       ClientID                     string  "ClientID"
-       ClientSecret                 string  "ClientSecret"
-       TenantID                     string  "TenantID"
-       CloudEnvironment             string  "CloudEnvironment"
-       ResourceGroup                string  "ResourceGroup"
-       Location                     string  "Location"
-       Network                      string  "Network"
-       Subnet                       string  "Subnet"
-       StorageAccount               string  "StorageAccount"
-       BlobContainer                string  "BlobContainer"
-       DeleteDanglingResourcesAfter float64 "DeleteDanglingResourcesAfter"
+       SubscriptionID               string
+       ClientID                     string
+       ClientSecret                 string
+       TenantID                     string
+       CloudEnvironment             string
+       ResourceGroup                string
+       Location                     string
+       Network                      string
+       Subnet                       string
+       StorageAccount               string
+       BlobContainer                string
+       DeleteDanglingResourcesAfter arvados.Duration
 }
 
 type VirtualMachinesClientWrapper interface {
@@ -204,9 +204,19 @@ type AzureInstanceSet struct {
 
 func NewAzureInstanceSet(config map[string]interface{}, dispatcherID cloud.InstanceSetID, logger logrus.FieldLogger) (prv cloud.InstanceSet, err error) {
        azcfg := AzureInstanceSetConfig{}
-       if err = mapstructure.Decode(config, &azcfg); err != nil {
+
+       decoderConfig := mapstructure.DecoderConfig{
+               DecodeHook: arvados.DurationMapStructureDecodeHook(),
+               Result:     &azcfg}
+
+       decoder, err := mapstructure.NewDecoder(&decoderConfig)
+       if err != nil {
                return nil, err
        }
+       if err = decoder.Decode(config); err != nil {
+               return nil, err
+       }
+
        ap := AzureInstanceSet{logger: logger}
        err = ap.setup(azcfg, string(dispatcherID))
        if err != nil {
@@ -489,7 +499,7 @@ func (az *AzureInstanceSet) ManageNics() (map[string]network.Interface, error) {
                                if result.Value().Tags["created-at"] != nil {
                                        createdAt, err := time.Parse(time.RFC3339Nano, *result.Value().Tags["created-at"])
                                        if err == nil {
-                                               if timestamp.Sub(createdAt).Seconds() > az.azconfig.DeleteDanglingResourcesAfter {
+                                               if timestamp.Sub(createdAt).Seconds() > az.azconfig.DeleteDanglingResourcesAfter.Duration().Seconds() {
                                                        az.logger.Printf("Will delete %v because it is older than %v s", *result.Value().Name, az.azconfig.DeleteDanglingResourcesAfter)
                                                        az.deleteNIC <- *result.Value().Name
                                                }
@@ -537,7 +547,7 @@ func (az *AzureInstanceSet) ManageBlobs() {
                        if b.Properties.BlobType == storage.BlobTypePage &&
                                b.Properties.LeaseState == "available" &&
                                b.Properties.LeaseStatus == "unlocked" &&
-                               age.Seconds() > az.azconfig.DeleteDanglingResourcesAfter {
+                               age.Seconds() > az.azconfig.DeleteDanglingResourcesAfter.Duration().Seconds() {
 
                                az.logger.Printf("Blob %v is unlocked and not modified for %v seconds, will delete", b.Name, age.Seconds())
                                az.deleteBlob <- b
index dfd9b95e0feceb2d4a218f31ed0ed2b7d79cce98..e5e8056a251aeb5b0c75db35636a2fc194c2226d 100644 (file)
@@ -21,7 +21,7 @@
 // Subnet: zzzzz-subnet-private
 // StorageAccount: example
 // BlobContainer: vhds
-// DeleteDanglingResourcesAfter: 20
+// DeleteDanglingResourcesAfter: 20s
 
 package azure
 
index d2a19a024c1aaecb9150d998bc79e6f3281a7b1b..d7dff6ddc75fca7d00fcf2db25a55ab7c40facef 100644 (file)
@@ -7,6 +7,7 @@ package arvados
 import (
        "encoding/json"
        "fmt"
+       "reflect"
        "time"
 )
 
@@ -37,9 +38,22 @@ func (d Duration) Duration() time.Duration {
        return time.Duration(d)
 }
 
-// Value implements flag.Value
+// Set sets the current duration by parsing the string using time.ParseDuration
 func (d *Duration) Set(s string) error {
        dur, err := time.ParseDuration(s)
        *d = Duration(dur)
        return err
 }
+
+// DurationMapStructureDecodeHook can be used to create a decoder for arvados.duration when using mapstructure
+func DurationMapStructureDecodeHook() interface{} {
+       return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+               var duration Duration
+               if f.Kind() != reflect.String || t != reflect.TypeOf(duration) {
+                       return data, nil
+               }
+
+               duration.Set(data.(string))
+               return duration, nil
+       }
+}