osbuildexecutor/aws.ec2: set hostname of executor via cloud-init

This way much more of the journal will be captured under the new
hostname.
This commit is contained in:
Sanne Raymaekers 2024-06-20 13:40:07 +02:00
parent 14052e25db
commit 2a621521a8
7 changed files with 29 additions and 15 deletions

View file

@ -515,7 +515,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
return err return err
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
executor = osbuildexecutor.NewAWSEC2Executor(impl.OSBuildExecutor.IAMProfile, impl.OSBuildExecutor.KeyName, impl.OSBuildExecutor.CloudWatchGroup, tmpDir) executor = osbuildexecutor.NewAWSEC2Executor(impl.OSBuildExecutor.IAMProfile, impl.OSBuildExecutor.KeyName, impl.OSBuildExecutor.CloudWatchGroup, job.Id().String(), tmpDir)
default: default:
osbuildJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, "No osbuild executor defined", nil) osbuildJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, "No osbuild executor defined", nil)
return err return err
@ -533,7 +533,6 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
ExportPaths: exportPaths, ExportPaths: exportPaths,
ExtraEnv: extraEnv, ExtraEnv: extraEnv,
Result: true, Result: true,
JobID: job.Id().String(),
} }
osbuildJobResult.OSBuildOutput, err = executor.RunOSBuild(jobArgs.Manifest, opts, os.Stderr) osbuildJobResult.OSBuildOutput, err = executor.RunOSBuild(jobArgs.Manifest, opts, os.Stderr)
// First handle the case when "running" osbuild failed // First handle the case when "running" osbuild failed

View file

@ -19,14 +19,15 @@ type SecureInstance struct {
} }
// SecureInstanceUserData returns the cloud-init user data for a secure instance. // SecureInstanceUserData returns the cloud-init user data for a secure instance.
func SecureInstanceUserData(CloudWatchGroup string) string { func SecureInstanceUserData(cloudWatchGroup, hostname string) string {
additionalFiles := "" additionalFiles := ""
if CloudWatchGroup != "" { if cloudWatchGroup != "" {
additionalFiles += fmt.Sprintf(` - path: /tmp/cloud_init_vars additionalFiles += fmt.Sprintf(` - path: /tmp/cloud_init_vars
content: | content: |
OSBUILD_EXECUTOR_CLOUDWATCH_GROUP='%s' OSBUILD_EXECUTOR_CLOUDWATCH_GROUP='%s'
`, CloudWatchGroup) OSBUILD_EXECUTOR_HOSTNAME='%s'
`, cloudWatchGroup, hostname)
} }
return fmt.Sprintf(`#cloud-config return fmt.Sprintf(`#cloud-config
@ -38,7 +39,7 @@ write_files:
// Runs an instance with a security group that only allows traffic to // Runs an instance with a security group that only allows traffic to
// the host. Will replace resources if they already exists. // the host. Will replace resources if they already exists.
func (a *AWS) RunSecureInstance(iamProfile, keyName, CloudWatchGroup string) (*SecureInstance, error) { func (a *AWS) RunSecureInstance(iamProfile, keyName, cloudWatchGroup, hostname string) (*SecureInstance, error) {
identity, err := a.ec2metadata.GetInstanceIdentityDocument() identity, err := a.ec2metadata.GetInstanceIdentityDocument()
if err != nil { if err != nil {
logrus.Errorf("Error getting the identity document, %s", err) logrus.Errorf("Error getting the identity document, %s", err)
@ -79,7 +80,7 @@ func (a *AWS) RunSecureInstance(iamProfile, keyName, CloudWatchGroup string) (*S
return nil, err return nil, err
} }
ltID, err := a.createOrReplaceLT(identity.InstanceID, imageID, sgID, instanceType, iamProfile, keyName, CloudWatchGroup) ltID, err := a.createOrReplaceLT(identity.InstanceID, imageID, sgID, instanceType, iamProfile, keyName, cloudWatchGroup, hostname)
if ltID != "" { if ltID != "" {
secureInstance.LTID = ltID secureInstance.LTID = ltID
} }
@ -280,7 +281,7 @@ func isLaunchTemplateNotFoundError(err error) bool {
} }
func (a *AWS) createOrReplaceLT(hostInstanceID, imageID, sgID, instanceType, iamProfile, keyName, CloudWatchGroup string) (string, error) { func (a *AWS) createOrReplaceLT(hostInstanceID, imageID, sgID, instanceType, iamProfile, keyName, cloudWatchGroup, hostname string) (string, error) {
ltName := fmt.Sprintf("launch-template-for-%s-runner-instance", hostInstanceID) ltName := fmt.Sprintf("launch-template-for-%s-runner-instance", hostInstanceID)
descrLTOutput, err := a.ec2.DescribeLaunchTemplates(&ec2.DescribeLaunchTemplatesInput{ descrLTOutput, err := a.ec2.DescribeLaunchTemplates(&ec2.DescribeLaunchTemplatesInput{
LaunchTemplateNames: []*string{ LaunchTemplateNames: []*string{
@ -333,7 +334,7 @@ func (a *AWS) createOrReplaceLT(hostInstanceID, imageID, sgID, instanceType, iam
SecurityGroupIds: []*string{ SecurityGroupIds: []*string{
aws.String(sgID), aws.String(sgID),
}, },
UserData: aws.String(base64.StdEncoding.EncodeToString([]byte(SecureInstanceUserData(CloudWatchGroup)))), UserData: aws.String(base64.StdEncoding.EncodeToString([]byte(SecureInstanceUserData(cloudWatchGroup, hostname)))),
}, },
TagSpecifications: []*ec2.TagSpecification{ TagSpecifications: []*ec2.TagSpecification{
&ec2.TagSpecification{ &ec2.TagSpecification{

View file

@ -8,6 +8,7 @@ import (
func TestSecureInstanceUserData(t *testing.T) { func TestSecureInstanceUserData(t *testing.T) {
type testCase struct { type testCase struct {
CloudWatchGroup string CloudWatchGroup string
Hostname string
ExpectedUserData string ExpectedUserData string
} }
@ -21,6 +22,7 @@ write_files:
}, },
{ {
CloudWatchGroup: "test-group", CloudWatchGroup: "test-group",
Hostname: "test-hostname",
ExpectedUserData: `#cloud-config ExpectedUserData: `#cloud-config
write_files: write_files:
- path: /tmp/worker-run-executor-service - path: /tmp/worker-run-executor-service
@ -28,13 +30,14 @@ write_files:
- path: /tmp/cloud_init_vars - path: /tmp/cloud_init_vars
content: | content: |
OSBUILD_EXECUTOR_CLOUDWATCH_GROUP='test-group' OSBUILD_EXECUTOR_CLOUDWATCH_GROUP='test-group'
OSBUILD_EXECUTOR_HOSTNAME='test-hostname'
`, `,
}, },
} }
for idx, tc := range testCases { for idx, tc := range testCases {
t.Run(fmt.Sprintf("Test case %d", idx), func(t *testing.T) { t.Run(fmt.Sprintf("Test case %d", idx), func(t *testing.T) {
userData := SecureInstanceUserData(tc.CloudWatchGroup) userData := SecureInstanceUserData(tc.CloudWatchGroup, tc.Hostname)
if userData != tc.ExpectedUserData { if userData != tc.ExpectedUserData {
t.Errorf("Expected: %s, got: %s", tc.ExpectedUserData, userData) t.Errorf("Expected: %s, got: %s", tc.ExpectedUserData, userData)
} }

View file

@ -14,9 +14,6 @@ type OsbuildOpts struct {
Checkpoints []string Checkpoints []string
ExtraEnv []string ExtraEnv []string
Result bool Result bool
// not strict a osbuild opt
JobID string
} }
type Executor interface { type Executor interface {

View file

@ -25,6 +25,7 @@ type awsEC2Executor struct {
iamProfile string iamProfile string
keyName string keyName string
cloudWatchGroup string cloudWatchGroup string
hostname string
tmpDir string tmpDir string
} }
@ -268,7 +269,7 @@ func (ec2e *awsEC2Executor) RunOSBuild(manifest []byte, opts *OsbuildOpts, error
return nil, fmt.Errorf("Failed to get default aws client in %s region: %w", region, err) return nil, fmt.Errorf("Failed to get default aws client in %s region: %w", region, err)
} }
si, err := aws.RunSecureInstance(ec2e.iamProfile, ec2e.keyName, ec2e.cloudWatchGroup) si, err := aws.RunSecureInstance(ec2e.iamProfile, ec2e.keyName, ec2e.cloudWatchGroup, ec2e.hostname)
if err != nil { if err != nil {
return nil, fmt.Errorf("Unable to start secure instance: %w", err) return nil, fmt.Errorf("Unable to start secure instance: %w", err)
} }
@ -317,11 +318,12 @@ func (ec2e *awsEC2Executor) RunOSBuild(manifest []byte, opts *OsbuildOpts, error
return osbuildResult, nil return osbuildResult, nil
} }
func NewAWSEC2Executor(iamProfile, keyName, cloudWatchGroup, tmpDir string) Executor { func NewAWSEC2Executor(iamProfile, keyName, cloudWatchGroup, hostname, tmpDir string) Executor {
return &awsEC2Executor{ return &awsEC2Executor{
iamProfile, iamProfile,
keyName, keyName,
cloudWatchGroup, cloudWatchGroup,
hostname,
tmpDir, tmpDir,
} }
} }

View file

@ -6,6 +6,7 @@ After=cloud-final.service
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart=/usr/local/libexec/worker-initialization-scripts/set_executor_hostname.sh
ExecStart=/usr/local/libexec/worker-initialization-scripts/worker_executor.sh ExecStart=/usr/local/libexec/worker-initialization-scripts/worker_executor.sh
[Install] [Install]

View file

@ -0,0 +1,11 @@
#!/bin/bash
set -euo pipefail
source /tmp/cloud_init_vars
if [[ -z "$OSBUILD_EXECUTOR_HOSTNAME" ]]; then
echo "OSBUILD_EXECUTOR_HOSTNAME not set, skipping."
exit 0
fi
echo "Setting system hostname to $OSBUILD_EXECUTOR_HOSTNAME."
hostnamectl set-hostname "$OSBUILD_EXECUTOR_HOSTNAME"