<commit_before>package common

import (
	"context"
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"log"
	"time"

	"encoding/json"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/packer/common/uuid"
	"github.com/hashicorp/packer/helper/multistep"
	"github.com/hashicorp/packer/packer"
)

type StepIamInstanceProfile struct {
	IamInstanceProfile                        string
	TemporaryIamInstanceProfilePolicyDocument *PolicyDocument
	createdInstanceProfileName                string
	createdRoleName                           string
	createdPolicyName                         string
	roleIsAttached                            bool
}

func (s *StepIamInstanceProfile) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
	iamsvc := state.Get("iam").(*iam.IAM)
	ui := state.Get("ui").(packer.Ui)

	state.Put("iamInstanceProfile", "")

	if len(s.IamInstanceProfile) > 0 {
		_, err := iamsvc.GetInstanceProfile(
			&iam.GetInstanceProfileInput{
				InstanceProfileName: aws.String(s.IamInstanceProfile),
			},
		)
		if err != nil {
			err := fmt.Errorf("Couldn't find specified instance profile: %s", err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}
		log.Printf("Using specified instance profile: %v", s.IamInstanceProfile)
		state.Put("iamInstanceProfile", s.IamInstanceProfile)
		return multistep.ActionContinue
	}

	if s.TemporaryIamInstanceProfilePolicyDocument != nil {
		// Create the profile
		profileName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())

		policy, err := json.Marshal(s.TemporaryIamInstanceProfilePolicyDocument)
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Creating temporary instance profile for this instance: %s", profileName))

		profileResp, err := iamsvc.CreateInstanceProfile(&iam.CreateInstanceProfileInput{
			InstanceProfileName: aws.String(profileName),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}
		s.createdInstanceProfileName = aws.StringValue(profileResp.InstanceProfile.InstanceProfileName)

		log.Printf("[DEBUG] Waiting for temporary instance profile: %s", s.createdInstanceProfileName)
		err = iamsvc.WaitUntilInstanceProfileExists(&iam.GetInstanceProfileInput{
			InstanceProfileName: aws.String(s.createdInstanceProfileName),
		})

		if err == nil {
			log.Printf("[DEBUG] Found instance profile %s", s.createdInstanceProfileName)
		} else {
			err := fmt.Errorf("Timed out waiting for instance profile %s: %s", s.createdInstanceProfileName, err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Creating temporary role for this instance: %s", profileName))

		roleResp, err := iamsvc.CreateRole(&iam.CreateRoleInput{
			RoleName:                 aws.String(profileName),
			Description:              aws.String("Temporary role for Packer"),
			AssumeRolePolicyDocument: aws.String("{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}]}"),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.createdRoleName = aws.StringValue(roleResp.Role.RoleName)

		log.Printf("[DEBUG] Waiting for temporary role: %s", s.createdInstanceProfileName)
		err = iamsvc.WaitUntilRoleExists(&iam.GetRoleInput{
			RoleName: aws.String(s.createdRoleName),
		})
		if err == nil {
			log.Printf("[DEBUG] Found temporary role %s", s.createdRoleName)
		} else {
			err := fmt.Errorf("Timed out waiting for temporary role %s: %s", s.createdRoleName, err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Attaching policy to the temporary role: %s", profileName))

		_, err = iamsvc.PutRolePolicy(&iam.PutRolePolicyInput{
			RoleName:       roleResp.Role.RoleName,
			PolicyName:     aws.String(profileName),
			PolicyDocument: aws.String(string(policy)),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.createdPolicyName = aws.StringValue(roleResp.Role.RoleName)

		_, err = iamsvc.AddRoleToInstanceProfile(&iam.AddRoleToInstanceProfileInput{
			RoleName:            roleResp.Role.RoleName,
			InstanceProfileName: profileResp.InstanceProfile.InstanceProfileName,
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.roleIsAttached = true
		state.Put("iamInstanceProfile", aws.StringValue(profileResp.InstanceProfile.InstanceProfileName))

		time.Sleep(5 * time.Second)
	}

	return multistep.ActionContinue
}

func (s *StepIamInstanceProfile) Cleanup(state multistep.StateBag) {
	iamsvc := state.Get("iam").(*iam.IAM)
	ui := state.Get("ui").(packer.Ui)
	var err error

	if s.roleIsAttached == true {
		ui.Say("Detaching temporary role from instance profile...")

		_, err := iamsvc.RemoveRoleFromInstanceProfile(&iam.RemoveRoleFromInstanceProfileInput{
			InstanceProfileName: aws.String(s.createdInstanceProfileName),
			RoleName:            aws.String(s.createdRoleName),
		})
		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the role manually: %s", err.Error(), s.createdRoleName))
		}
	}

	if s.createdPolicyName != "" {
		ui.Say("Removing policy from temporary role...")
		iamsvc.DeleteRolePolicy(&iam.DeleteRolePolicyInput{
			PolicyName: aws.String(s.createdPolicyName),
			RoleName:   aws.String(s.createdRoleName),
		})
	}
	if s.createdRoleName != "" {
		ui.Say("Deleting temporary role...")

		_, err = iamsvc.DeleteRole(&iam.DeleteRoleInput{RoleName: &s.createdRoleName})
		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the role manually: %s", err.Error(), s.createdRoleName))
		}
	}

	if s.createdInstanceProfileName != "" {
		ui.Say("Deleting temporary instance profile...")

		_, err = iamsvc.DeleteInstanceProfile(&iam.DeleteInstanceProfileInput{
			InstanceProfileName: &s.createdInstanceProfileName})

		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the instance profile manually: %s", err.Error(), s.createdInstanceProfileName))
		}
	}
}
<commit_msg>Remove 5 sec sleep after adding iam instance profile<commit_after>package common

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"

	"encoding/json"

	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/packer/common/uuid"
	"github.com/hashicorp/packer/helper/multistep"
	"github.com/hashicorp/packer/packer"
)

type StepIamInstanceProfile struct {
	IamInstanceProfile                        string
	TemporaryIamInstanceProfilePolicyDocument *PolicyDocument
	createdInstanceProfileName                string
	createdRoleName                           string
	createdPolicyName                         string
	roleIsAttached                            bool
}

func (s *StepIamInstanceProfile) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
	iamsvc := state.Get("iam").(*iam.IAM)
	ui := state.Get("ui").(packer.Ui)

	state.Put("iamInstanceProfile", "")

	if len(s.IamInstanceProfile) > 0 {
		_, err := iamsvc.GetInstanceProfile(
			&iam.GetInstanceProfileInput{
				InstanceProfileName: aws.String(s.IamInstanceProfile),
			},
		)
		if err != nil {
			err := fmt.Errorf("Couldn't find specified instance profile: %s", err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}
		log.Printf("Using specified instance profile: %v", s.IamInstanceProfile)
		state.Put("iamInstanceProfile", s.IamInstanceProfile)
		return multistep.ActionContinue
	}

	if s.TemporaryIamInstanceProfilePolicyDocument != nil {
		// Create the profile
		profileName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())

		policy, err := json.Marshal(s.TemporaryIamInstanceProfilePolicyDocument)
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Creating temporary instance profile for this instance: %s", profileName))

		profileResp, err := iamsvc.CreateInstanceProfile(&iam.CreateInstanceProfileInput{
			InstanceProfileName: aws.String(profileName),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}
		s.createdInstanceProfileName = aws.StringValue(profileResp.InstanceProfile.InstanceProfileName)

		log.Printf("[DEBUG] Waiting for temporary instance profile: %s", s.createdInstanceProfileName)
		err = iamsvc.WaitUntilInstanceProfileExists(&iam.GetInstanceProfileInput{
			InstanceProfileName: aws.String(s.createdInstanceProfileName),
		})

		if err == nil {
			log.Printf("[DEBUG] Found instance profile %s", s.createdInstanceProfileName)
		} else {
			err := fmt.Errorf("Timed out waiting for instance profile %s: %s", s.createdInstanceProfileName, err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Creating temporary role for this instance: %s", profileName))

		roleResp, err := iamsvc.CreateRole(&iam.CreateRoleInput{
			RoleName:                 aws.String(profileName),
			Description:              aws.String("Temporary role for Packer"),
			AssumeRolePolicyDocument: aws.String("{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\"Action\": \"sts:AssumeRole\"}]}"),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.createdRoleName = aws.StringValue(roleResp.Role.RoleName)

		log.Printf("[DEBUG] Waiting for temporary role: %s", s.createdInstanceProfileName)
		err = iamsvc.WaitUntilRoleExists(&iam.GetRoleInput{
			RoleName: aws.String(s.createdRoleName),
		})
		if err == nil {
			log.Printf("[DEBUG] Found temporary role %s", s.createdRoleName)
		} else {
			err := fmt.Errorf("Timed out waiting for temporary role %s: %s", s.createdRoleName, err)
			log.Printf("[DEBUG] %s", err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		ui.Say(fmt.Sprintf("Attaching policy to the temporary role: %s", profileName))

		_, err = iamsvc.PutRolePolicy(&iam.PutRolePolicyInput{
			RoleName:       roleResp.Role.RoleName,
			PolicyName:     aws.String(profileName),
			PolicyDocument: aws.String(string(policy)),
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.createdPolicyName = aws.StringValue(roleResp.Role.RoleName)

		_, err = iamsvc.AddRoleToInstanceProfile(&iam.AddRoleToInstanceProfileInput{
			RoleName:            roleResp.Role.RoleName,
			InstanceProfileName: profileResp.InstanceProfile.InstanceProfileName,
		})
		if err != nil {
			ui.Error(err.Error())
			state.Put("error", err)
			return multistep.ActionHalt
		}

		s.roleIsAttached = true
		state.Put("iamInstanceProfile", aws.StringValue(profileResp.InstanceProfile.InstanceProfileName))
	}

	return multistep.ActionContinue
}

func (s *StepIamInstanceProfile) Cleanup(state multistep.StateBag) {
	iamsvc := state.Get("iam").(*iam.IAM)
	ui := state.Get("ui").(packer.Ui)
	var err error

	if s.roleIsAttached == true {
		ui.Say("Detaching temporary role from instance profile...")

		_, err := iamsvc.RemoveRoleFromInstanceProfile(&iam.RemoveRoleFromInstanceProfileInput{
			InstanceProfileName: aws.String(s.createdInstanceProfileName),
			RoleName:            aws.String(s.createdRoleName),
		})
		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the role manually: %s", err.Error(), s.createdRoleName))
		}
	}

	if s.createdPolicyName != "" {
		ui.Say("Removing policy from temporary role...")
		iamsvc.DeleteRolePolicy(&iam.DeleteRolePolicyInput{
			PolicyName: aws.String(s.createdPolicyName),
			RoleName:   aws.String(s.createdRoleName),
		})
	}
	if s.createdRoleName != "" {
		ui.Say("Deleting temporary role...")

		_, err = iamsvc.DeleteRole(&iam.DeleteRoleInput{RoleName: &s.createdRoleName})
		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the role manually: %s", err.Error(), s.createdRoleName))
		}
	}

	if s.createdInstanceProfileName != "" {
		ui.Say("Deleting temporary instance profile...")

		_, err = iamsvc.DeleteInstanceProfile(&iam.DeleteInstanceProfileInput{
			InstanceProfileName: &s.createdInstanceProfileName})

		if err != nil {
			ui.Error(fmt.Sprintf(
				"Error %s. Please delete the instance profile manually: %s", err.Error(), s.createdInstanceProfileName))
		}
	}
}

{'fraction_non_alphanumeric': 0.13672182821118992, 'fraction_numerical': 0.0017336485421591804, 'mean_word_length': 3.9905623279591036, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5444943', 'n_tokens_mistral': 4485, 'n_tokens_neox': 4066, 'n_words': 773}