clearlinux / distribution

Placeholder repository to allow filing of general bugs/issues/etc against the Clear Linux OS for Intel Architecture linux distribution
521 stars 29 forks source link

Unable to import clear-31440-aws.img to AWS or upload my own custom AMI #1428

Open briskycat opened 4 years ago

briskycat commented 4 years ago

On the https://clearlinux.org/downloads page there is a link to an AWS image of Clear Linux. There are no explicit instructions nearby on what to do with the file, so I downloaded, unpacked it, and discovered that it was a raw disk image. So I tried importing it as a raw image to AWS following the official instructions but in the end I got this result:

{

    "ImportImageTasks": [
        {
            "Status": "deleted", 
            "Description": "Clear Linux VM", 
            "Platform": "Linux", 
            "Architecture": "x86_64", 
            "SnapshotDetails": [
                {
                    "Status": "completed", 
                    "UserBucket": {
                        "S3Bucket": "***", 
                        "S3Key": "Blank/clear-31440-aws.img"
                    }, 
                    "DiskImageSize": 536870912.0, 
                    "Description": "Clear Linux", 
                    "Format": "RAW"
                }
            ], 
            "StatusMessage": "ClientError: Unknown OS / Missing OS files.", 
            "ImportTaskId": "import-ami-0f67d85f5ecb92317"
        }
    ]
}

The import didn't work.

I also tried creating a VirtualBox VM based on this disk image with the intent of exporting it as an OVA and importing that OVA to AWS but the VM only booted the kernel which then failed to mount the root FS (I even tried to tinker with the root command line parameter and tried out many different chipsets/controllers - nothing worked). Screenshot 2019-10-31 at 13 17 45 Exporting a regular Clear Linux VM as an OVA and importing it to AWS does not work either because in that case AWS complains that the VM uses UEFI which AWS does not support.

{
    "ImportImageTasks": [
        {
            "Status": "deleting", 
            "Description": "Clear Linux VM", 
            "Platform": "Linux", 
            "Architecture": "x86_64", 
            "SnapshotDetails": [
                {
                    "Status": "completed", 
                    "UserBucket": {
                        "S3Bucket": "***", 
                        "S3Key": "Blank/ClearLinux.ova"
                    }, 
                    "DiskImageSize": 2323621888.0, 
                    "Format": "VMDK"
                }
            ], 
            "StatusMessage": "ClientError: EFI partition detected. UEFI booting is not supported in EC2.", 
            "ImportTaskId": "import-ami-0d508bbce0f67d352"
        }
    ]
}

Installing Clear Linux without UEFI using a regular server iso image, on the other hand, is impossible.

I am able to use the official AMI from AWS Marketplace, but that's not what I need. So how do I upload my own Clear Linux AMI to AWS?

ahkok commented 4 years ago

@tpleavitt I think we can approach this from a documentation perspective - we should likely have this use case documented - there are definitely some gotchas about importing images into AWS.

@mbelluzzo can possibly help with some of the technical barriers here

tpleavitt commented 4 years ago

created documentation issue: https://github.com/clearlinux/clear-linux-documentation/issues/890

mbelluzzo commented 4 years ago

@briskycat if you just want to run Clear on AWS we do offer it straight from AWS Marketplace. From AWS Console you can just search "Clear Linux" and it should be the first result.

The image we submit to amazon to be offered via their Marketplace is exactly the image we offer under clearlinux.org/downloads, however, the version in the Marketplace will always be slightly older (around a week) than our latest release because of how the publishing process work on their end.

But once you have an instance running, a swupd update is enough to catch-up.

We also have validation that basically does an import of that image and sees if it can successfully but on AWS, and the results for the mentioned image came back okay from our end. Therefore, could you please share the exactly steps you went through the aws cli that led to this error?

briskycat commented 4 years ago

@mbelluzzo the steps were as follows:

  1. Created the vmimport IAM role: aws iam create-role --role-name vmimport --assume-role-policy-document "file:///project/trust-policy.json"

    $ cat trust-policy.json 
    {
    "Version": "2012-10-17",
    "Statement": [
      {
         "Effect": "Allow",
         "Principal": { "Service": "vmie.amazonaws.com" },
         "Action": "sts:AssumeRole",
         "Condition": {
            "StringEquals":{
               "sts:Externalid": "vmimport"
            }
         }
      }
    ]
    }

    aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document "file:///project/role-policy.json"

    $ cat role-policy.json 
    {
    "Version":"2012-10-17",
    "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:GetBucketLocation",
            "s3:GetObject",
            "s3:ListBucket" 
         ],
         "Resource":[
            "arn:aws:s3:::mybucket",
            "arn:aws:s3:::mybucket/*"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:GetBucketLocation",
            "s3:GetObject",
            "s3:ListBucket",
            "s3:PutObject",
            "s3:GetBucketAcl"
         ],
         "Resource":[
            "arn:aws:s3:::mybucket",
            "arn:aws:s3:::mybucket/*"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "ec2:ModifySnapshotAttribute",
            "ec2:CopySnapshot",
            "ec2:RegisterImage",
            "ec2:Describe*"
         ],
         "Resource":"*"
      }
    ]
    }
  2. Downloaded clear-31440-aws.img.xz, unpacked it using xz -d, then uploaded clear-31440-aws.img to mybucket using AWS console.

  3. Initiated a VM import process aws ec2 import-image --description "Clear Linux" --architecture "x86_64" --platform "Linux" --disk-containers "file:///project/containers.json"

    $ cat containers.json 
    [
    {
    "Description": "Clear Linux",
    "Format": "raw",
    "UserBucket": {
        "S3Bucket": "mybucket",
        "S3Key": "Blank/clear-31440-aws.img"
    }
    }]
  4. Monitored the status

    aws ec2 describe-import-image-tasks --import-task-ids import-ami-0f67d85f5ecb92317
    {
    "ImportImageTasks": [
        {
            "Status": "deleted", 
            "Description": "Clear Linux", 
            "Platform": "Linux", 
            "Architecture": "x86_64", 
            "SnapshotDetails": [
                {
                    "Status": "completed", 
                    "UserBucket": {
                        "S3Bucket": "mybucket", 
                        "S3Key": "Blank/clear-31440-aws.img"
                    }, 
                    "DiskImageSize": 536870912.0, 
                    "Description": "Clear Linux", 
                    "Format": "RAW"
                }
            ], 
            "StatusMessage": "ClientError: Unknown OS / Missing OS files.", 
            "ImportTaskId": "import-ami-0f67d85f5ecb92317"
        }
    ]
    }
gtkramer commented 4 years ago

We have a working process for uploading images into AWS. It's what allows us to publish an updated Clear Linux offering. Everything we do looks largely similar until @briskycat 's step 3. This is where our process diverges. Instead of @briskycat 's step 3, our process does roughly the following for the rest of the steps:

cat <<EOF> ${json_file}
{
  "Description": "${description} image",
  "Format": "raw",
  "UserBucket": {
    "S3Bucket": "${BUCKET}",
    "S3Key": "${IMAGE}"
  }
}
EOF

aws ec2 import-snapshot --description "${description} image" --disk-container file://${json_file}

# Some wait code here for snapshot import to be completed

snapshot_id=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${import_task_id} | grep SnapshotId | awk -F '"'  '{print $4}')

aws ec2 register-image \
  --name "$description" \
  --description "$description" \
  --architecture x86_64 \
  --virtualization-type hvm \
  --ena-support \
  --root-device-name "/dev/sda1" \
  --block-device-mappings "[
    {
        \"DeviceName\": \"/dev/sda1\",
        \"Ebs\": {
            \"SnapshotId\": \"$snapshot_id\"
        }
    }
]"

This last command produces an AMI ID. From here, an instance may be launched from the AMI ID. This follows the normal process of launching instances in AWS. It also seems to be coherent with how AMIs are constructed in AWS. Every AMI is backed with a snapshot. I'm guessing this could be the miss in the documentation? The images DevOps produces are correct.

mbelluzzo commented 4 years ago

That is good to know @gtkramer . Thanks for double checking this!

gtkramer commented 4 years ago

For folks who do this import on their own but also expect to get the same kind of networking experience OOB as they would with our AMI, we should add the following note to the documentation that these instance attributes must be manually added:

aws ec2 modify-instance-attribute --instance-id instance_id --sriov-net-support simple
aws ec2 modify-instance-attribute --instance-id instance_id --ena-support