From e71fe86442da831ae70a43b7571962a1aca71df7 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Thu, 24 Aug 2023 15:04:48 -0700 Subject: [PATCH] store: fail faster if not running in EC2 If you are running `chamber` outside of EC2 without a region configured, the binary will take 5 seconds to fail because the default ec2 metadata API timeout is 5 seconds. Instead, take a few milliseconds to determine whether we are even running on EC2. We attempt to do this by checking the contents of different files on the disk, e.g. /sys/devices/virtual/dmi/id/board_asset_tag, and then if all of those fail, attempting to see if anything is listening on the metadata host. This can help prevent the 5 second failure timeout. --- go.mod | 1 + go.sum | 2 ++ store/shared.go | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ff95a8f0..34972e03 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/alessio/shellescape v1.4.1 github.com/aws/aws-sdk-go v1.44.312 + github.com/kevinburke/isec2 v0.1.0 github.com/magiconair/properties v1.8.7 github.com/segmentio/analytics-go/v3 v3.2.1 github.com/spf13/cobra v1.7.0 diff --git a/go.sum b/go.sum index cbbcf785..c7b1f4d4 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/kevinburke/isec2 v0.1.0 h1:BhEAlWqZR6lNL7o/C3W46mhIBpJHimYNYQtXtvwXk6o= +github.com/kevinburke/isec2 v0.1.0/go.mod h1:axcGKXslLWfmqxnN+O0NqA8oGKqkQ37MQArV2brBVpw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/store/shared.go b/store/shared.go index 39ce1651..ceec0c69 100644 --- a/store/shared.go +++ b/store/shared.go @@ -1,12 +1,15 @@ package store import ( + "context" "os" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/session" + "github.com/kevinburke/isec2" ) const ( @@ -47,10 +50,15 @@ func getSession(numRetries int) (*session.Session, *string, error) { // If region is still not set, attempt to determine it via ec2 metadata API if aws.StringValue(retSession.Config.Region) == "" { - session := session.New() - ec2metadataSvc := ec2metadata.New(session) - if regionOverride, err := ec2metadataSvc.Region(); err == nil { - region = aws.String(regionOverride) + ec2ctx, ec2cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) + runningEC2, ec2err := isec2.IsEC2(ec2ctx) + ec2cancel() + if ec2err == nil && runningEC2 { + session := session.New() + ec2metadataSvc := ec2metadata.New(session) + if regionOverride, err := ec2metadataSvc.Region(); err == nil { + region = aws.String(regionOverride) + } } }