Skip to content

Commit

Permalink
Init repository
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasbeiler committed Dec 4, 2024
0 parents commit b36f6e6
Show file tree
Hide file tree
Showing 16 changed files with 585 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Terraform

on:
schedule:
- cron: '0 * * * *' # Every hour.

# on: workflow_dispatch

jobs:
terraform:
runs-on: ubuntu-latest

env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform Init
run: terraform init

- name: Terraform Apply
run: terraform apply -auto-approve
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#### SOURCE: https://github.com/github/gitignore/blob/main/Terraform.gitignore
# Local .vagrant directories
.vagrant

# Local .terraform directories
.terraform

# .tfstate files
*.tfstate
*.tfstate.*
*tfstate*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc

# Misc
.env
samples/
.terraform.lock.hcl
*key
chave*
responders/
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Disclaimer

This project is a work in progress and will continue to evolve toward greater robustness, simplicity, and modularity.

I am **NOT** affiliated with the GrapheneOS Foundation; I am simply a user who is deeply interested in Reproducible Builds, especially for an operating system that is already in use on my Google Pixel 8 Pro and will play an even larger role in my life in the future with the rumored Google Pixel Laptop.

This project:
- Builds GrapheneOS on AWS EC2 Spot instances;
- Unpacks images, archives and other special/unusual file types;
- ... and also removes/strips signatures to prevent them from messing with the comparison.
- Compares the resulting build with the official release;
- Publishes the diffoscope output showing all the differences between files from the official builds and my builds.

A new build is triggered as soon as a release reaches the alpha channel, usually indicating its imminent stable release within a few hours.

The kernel and applications are compiled from scratch to ensure full reproducibility — no prebuilts are used (except for Vanadium, but I'll build it soon). Vendor blobs are fetched directly from Google via `adevtool`, rather than from the GrapheneOS repositories.

Currently, this work is limited to the Google Pixel 8 Pro, the device I own. However, feel free to fork this project for other devices.

### Results
The diffoscope reports are available at:
- `https://gos-repro-reports-2.s3.us-east-1.amazonaws.com/${PIXEL_CODENAME}-${BUILD_NUMBER}.html`.
- For example: https://gos-repro-reports-2.s3.us-east-1.amazonaws.com/husky-2024120400.html

The SHA512 hashes of the official releases I compared my builds against are avaible at:
- `https://gos-repro-reports-2.s3.us-east-1.amazonaws.com/${PIXEL_CODENAME}-${BUILD_NUMBER}.checksum`.
- For example: https://gos-repro-reports-2.s3.us-east-1.amazonaws.com/husky-2024120400.checksum

### Pending work
- [ ] Build Vanadium too (I'm not reproducing it yet);
- [ ] Decide whether to continue using `7z x` or switch to mounting filesystem images;
- [ ] Deal with APEX files that are not zip files, they need to be unpacked in some special way;
- [ ] Use the official AOSP `lpunpack` tool instead of using that Python reimplementation;
- [ ] Write GitHub Actions to trigger the infrastructure when a new GrapheneOS release reaches their alpha channel;
- [ ] Deal with pvmfw.img's large diffs (does it need to be unpacked somehow? how?!).
8 changes: 8 additions & 0 deletions infra/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This bucket needs to already exist beforehand.
terraform {
backend "s3" {
bucket = "gosbuild-terraform-state"
key = "tfstate"
region = "us-east-1"
}
}
10 changes: 10 additions & 0 deletions infra/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
data "aws_ami" "ubuntu" {
most_recent = true

filter {
name = "name"
values = ["debian-12-amd64-*"]
}

owners = ["136693071363"] # Debian
}
49 changes: 49 additions & 0 deletions infra/ec2.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
resource "aws_instance" "machine" {
ami = data.aws_ami.ubuntu.image_id
instance_type = local.instance_type
key_name = local.key_name
user_data = local.user_data

iam_instance_profile = aws_iam_instance_profile.instance_profile.id

ebs_block_device {
device_name = data.aws_ami.ubuntu.root_device_name
volume_size = local.volume_size_gb
}

connection {
type = "ssh"
user = "admin"
private_key = tls_private_key.private_key.private_key_pem
host = self.public_dns
}

provisioner "file" {
source = "../scripts"
destination = "scripts/"
}

provisioner "remote-exec" {
inline = [
"mkdir -p scripts/",
]
}

instance_market_options {
market_type = "spot"
spot_options {
max_price = local.spot_price
}
}
}

resource "aws_key_pair" "generated_key" {
key_name = local.key_name
public_key = tls_private_key.private_key.public_key_openssh
}


resource "tls_private_key" "private_key" {
algorithm = "RSA"
rsa_bits = 4096
}
49 changes: 49 additions & 0 deletions infra/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
resource "aws_iam_role" "iam_role" {
name = "ec2_s3_interaction"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_instance_profile" "instance_profile" {
name = aws_iam_role.iam_role.id
role = aws_iam_role.iam_role.id
}

resource "aws_iam_role_policy" "iam_role_policy" {
name = aws_iam_role.iam_role.id
role = aws_iam_role.iam_role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::${aws_s3_bucket.gos_repro_reports.id}"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::${aws_s3_bucket.gos_repro_reports.id}/*"]
}
]
}
EOF
}
8 changes: 8 additions & 0 deletions infra/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
locals {
user_data = base64encode(file("startup_script.sh"))
spot_price = "0.76"
instance_type = "c3.8xlarge"
# instance_type = "r4.2xlarge"
volume_size_gb = 384
key_name = "ec2_ssh_key"
}
4 changes: 4 additions & 0 deletions infra/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "private_key" {
value = tls_private_key.private_key.private_key_pem
sensitive = true
}
3 changes: 3 additions & 0 deletions infra/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
provider "aws" {
region = "us-east-1"
}
56 changes: 56 additions & 0 deletions infra/s3.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
resource "aws_s3_bucket" "gos_repro_reports" {
bucket = "gos-repro-reports-2"
provider = aws
force_destroy = false

}

resource "aws_s3_bucket_ownership_controls" "gos_repro_reports" {
bucket = aws_s3_bucket.gos_repro_reports.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}

resource "aws_s3_bucket_public_access_block" "gos_repro_reports" {
bucket = aws_s3_bucket.gos_repro_reports.id

block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}

resource "aws_s3_bucket_acl" "gos_repro_reports" {
depends_on = [
aws_s3_bucket_ownership_controls.gos_repro_reports,
aws_s3_bucket_public_access_block.gos_repro_reports,
]

bucket = aws_s3_bucket.gos_repro_reports.id
acl = "public-read"
}

data "aws_iam_policy_document" "gos_repro_reports" {
policy_id = "s3_bucket_gos_repro_reports"

statement {
actions = [
"s3:GetObject"
]
effect = "Allow"
resources = [
"${aws_s3_bucket.gos_repro_reports.arn}/*"
]
principals {
type = "*"
identifiers = ["*"]
}
sid = "1"
}
}

resource "aws_s3_bucket_policy" "gos_repro_reports" {
bucket = aws_s3_bucket.gos_repro_reports.id
policy = data.aws_iam_policy_document.gos_repro_reports.json
}
44 changes: 44 additions & 0 deletions infra/startup_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
set -eo pipefail

OUR_NONROOT_USER="strcat" # Trying to match official build
TIMEZONE_TO_SET="America/New_York" # Trying to match official build, because I've looked at some diffs showing EST as timezone somewhere.
BUILD_SCRIPT_PATH="build_gos.sh"
COMPARE_SCRIPT_PATH="compare_gos.sh"

useradd -m -G users,sudo -s /bin/bash ${OUR_NONROOT_USER}
timedatectl set-timezone ${TIMEZONE_TO_SET}
ln -sf /usr/share/zoneinfo/${TIMEZONE_TO_SET} /etc/localtime
echo "${OUR_NONROOT_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/90-cloud-init-users

# Install general AOSP build dependencies and diffoscope stuff
apt update
apt install -y git-core git-lfs curl gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig yarnpkg rsync libncurses5 libncurses5-dev diffutils hostname libssl-dev android-sdk-libsparse-utils
apt install -y diffoscope p7zip e2fsprogs python3-pip golang binwalk

# Install repo
curl -sL --url "https://storage.googleapis.com/git-repo-downloads/repo" --output "/usr/local/bin/repo"
chmod a+rx /usr/local/bin/repo
rm -rf /usr/lib/python3/dist-packages/diffoscope*
pip install diffoscope --break-system-packages

# Download avbtool and unpack_bootimg from AOSP sources
curl -sL --fail https://android.googlesource.com/platform/external/avb/+/master/avbtool.py?format=TEXT | base64 -d | tee /usr/local/bin/avbtool && chmod a+x /usr/local/bin/avbtool
curl -sL --fail https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/main/unpack_bootimg.py?format=TEXT | base64 -d | tee /usr/local/bin/unpack_bootimg && chmod a+x /usr/local/bin/unpack_bootimg
curl -sL --fail https://github.com/unix3dgforce/lpunpack/raw/refs/heads/master/lpunpack.py | tee /usr/local/bin/lpunpack_py && chmod a+x /usr/local/bin/lpunpack_py # TODO: Use the official one from AOSP instead!
# shutdown_afterwards() {
# shutdown -h now
# }
# trap shutdown_afterwards EXIT # Ensure machine goes away on exit.

# Prepare swapfile
# fallocate -l 12G /swapfile
# chmod 600 /swapfile
# mkswap /swapfile
# swapon /swapfile

# Run scripts as user
cp /home/admin/scripts/${BUILD_SCRIPT_PATH} /home/admin/scripts/${COMPARE_SCRIPT_PATH} /usr/local/bin/
chmod a+x /usr/local/bin/${BUILD_SCRIPT_PATH} /usr/local/bin/${COMPARE_SCRIPT_PATH}
su ${OUR_NONROOT_USER} -c ${BUILD_SCRIPT_PATH}
su ${OUR_NONROOT_USER} -c ${COMPARE_SCRIPT_PATH}
8 changes: 8 additions & 0 deletions infra/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
4 changes: 4 additions & 0 deletions infra/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "KEY_NAME" {
default = "ec2_ssh_key"
type = string
}
Loading

0 comments on commit b36f6e6

Please sign in to comment.