Skip to content

Commit

Permalink
Add support for custom cached images for Lantern
Browse files Browse the repository at this point in the history
  • Loading branch information
var77 committed May 11, 2024
1 parent 49a092c commit 8ea6fe4
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 26 deletions.
28 changes: 17 additions & 11 deletions config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,6 @@ def self.e2e_test?
optional :ubicloud_images_blob_storage_secret_key, string, clear: true
optional :ubicloud_images_blob_storage_certs, string

# Lantern
override :lantern_top_domain, "db.lantern.dev", string
override :lantern_dns_email, "varik@lantern.dev", string
override :lantern_default_version, "0.2.5", string
override :lantern_extras_default_version, "0.1.5", string
override :lantern_minor_default_version, "2", string
override :lantern_backup_bucket, "walg-dev-backups"
override :e2e_test, "0"
override :backup_retention_days, 7, int
optional :lantern_backend_database_url, string

# GCP
override :gcp_project_id, "lantern-development", string
override :gcp_compute_service_account, "339254316100-compute@developer.gserviceaccount.com", string
Expand All @@ -154,6 +143,23 @@ def self.e2e_test?
optional :prom_password, string
override :gcr_image, "gcr.io/ringed-griffin-394922/lantern-bitnami"

# Lantern
override :lantern_top_domain, "db.lantern.dev", string
override :lantern_dns_email, "varik@lantern.dev", string
override :lantern_default_version, "0.2.7", string
override :lantern_extras_default_version, "0.1.5", string
override :lantern_minor_default_version, "1", string
override :lantern_backup_bucket, "walg-dev-backups"
override :e2e_test, "0"
override :backup_retention_days, 7, int
optional :lantern_backend_database_url, string

# To use default ubuntu image pass these env vars to overwrite
# LANTERN_GCP_IMAGE=projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20240319
# LANTERN_GCP_IMAGE_CACHED=false
override :lantern_gcp_image, "projects/#{gcp_project_id}/global/images/ubuntu-lantern-#{lantern_default_version.tr(".", "-")}-extras-#{lantern_extras_default_version.tr(".", "-")}-minor-#{lantern_minor_default_version}", string
override :lantern_gcp_image_cached, true, bool

# Cloudflare
optional :cf_token, string
optional :cf_zone_id, string
Expand Down
23 changes: 21 additions & 2 deletions lib/hosting/gcp_apis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def wait_for_operation(zone, operation)
connection = Excon.new(@host[:connection_string], headers: @host[:headers])

loop do
response = connection.post(path: "/compute/v1/projects/#{@project}/zones/#{zone}/operations/#{operation}/wait", expects: [200])
response = connection.post(path: "/compute/v1/projects/#{@project}/#{(zone == "global") ? "" : "zones/"}#{zone}/operations/#{operation}/wait", expects: [200])
body = JSON.parse(response.body)
break unless body["status"] != "DONE"
rescue Excon::Error::Timeout
Expand Down Expand Up @@ -72,7 +72,7 @@ def create_vm(name, zone, image, ssh_key, user, machine_type, disk_size_gb, labe
initializeParams: {
diskSizeGb: disk_size_gb,
diskType: "projects/#{@project}/zones/#{zone}/diskTypes/pd-ssd",
sourceImage: "projects/ubuntu-os-cloud/global/images/#{image}"
sourceImage: image
},
mode: "READ_WRITE",
type: "PERSISTENT"
Expand Down Expand Up @@ -330,4 +330,23 @@ def allow_bucket_usage_by_prefix(service_account_email, bucket_name, prefix)

Hosting::GcpApis.check_errors(response)
end

def create_image(name:, vm_name:, zone:, description: "", family: "lantern-ubuntu")
connection = Excon.new(@host[:connection_string], headers: @host[:headers])
body = {
kind: "compute#image",
description: description,
name: name,
family: family,
sourceDisk: "projects/#{@project}/zones/#{zone}/disks/#{vm_name}",
storageLocations: [
"us"
]
}

response = connection.post(path: "/compute/beta/projects/#{@project}/global/images", body: JSON.dump(body), expects: 200)
Hosting::GcpApis.check_errors(response)
data = JSON.parse(response.body)
wait_for_operation("global", data["id"])
end
end
5 changes: 0 additions & 5 deletions lib/option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ def self.lantern_locations_for_provider(provider)
Option::Locations.select { _1.provider.name == provider }
end

BootImage = Struct.new(:name, :display_name)
BootImages = [
["ubuntu-2204-jammy-v20240319", "Ubuntu Jammy 22.04 LTS (GCP)"]
].map { |args| BootImage.new(*args) }.freeze

VmSize = Struct.new(:name, :family, :vcpu, :memory, :storage_size_gib) do
alias_method :display_name, :name
end
Expand Down
47 changes: 47 additions & 0 deletions misc/misc_operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,51 @@ def self.add_lantern_doctor_to_all
end
}
end

def self.create_image(name, description, image_tag, vm: nil)
gcp_api = Hosting::GcpApis.new
container_image = "#{Config.gcr_image}:#{image_tag}"

if vm.nil?
vm = Prog::GcpVm::Nexus.assemble_with_sshable("lantern", Project.first.id, name: "imagecreation-machine", storage_size_gib: 10)

# wait vm available
loop do
break if Strand[vm.id].label == "wait"
sleep 10
end

vm = GcpVm[vm.id]
puts "VM Created"
end

key_data = vm.sshable.keys.map(&:private_key)
Util.rootish_ssh(vm.sshable.host, "lantern", key_data, <<SH)
set -euo pipefail
sudo apt update && sudo apt-get -y install software-properties-common make ruby-bundler
curl -fsSL https://get.docker.com > /tmp/get-docker.sh
chmod +x /tmp/get-docker.sh
/tmp/get-docker.sh
rm -rf /tmp/get-docker.sh
sudo sed -i 's/ulimit -Hn/ulimit -n/' /etc/init.d/docker
sudo service docker restart
echo #{Config.gcp_creds_gcr_b64} | base64 -d | sudo docker login -u _json_key --password-stdin https://gcr.io
sudo docker pull #{container_image}
sudo docker logout
history -cw
SH
puts "Dependencies installed"

vm.incr_stop_vm
# wait vm stopped
loop do
break if GcpVm[vm.id].display_state == "stopped"
sleep 10
end

puts "VM stopped creating image"
gcp_api.create_image(name: name, vm_name: vm.name, zone: "#{vm.location}-a", description: description)
puts "Image created"
vm.incr_destroy
end
end
1 change: 1 addition & 0 deletions model/lantern/lantern_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def configure_hash

JSON.generate({
enable_coredumps: true,
skip_deps: Config.lantern_gcp_image_cached,
org_id: resource.org_id,
instance_id: resource.name,
instance_type: instance_type,
Expand Down
2 changes: 1 addition & 1 deletion prog/gcp_vm/nexus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Prog::GcpVm::Nexus < Prog::Base
semaphore :destroy, :start_vm, :stop_vm, :update_storage, :update_size

def self.assemble(public_key, project_id, name: nil, size: "n1-standard-2",
unix_user: "lantern", location: "us-central1", boot_image: "ubuntu-2204-jammy-v20240319",
unix_user: "lantern", location: "us-central1", boot_image: Config.lantern_gcp_image,
storage_size_gib: nil, arch: "x64", labels: {})

unless (project = Project[project_id])
Expand Down
2 changes: 1 addition & 1 deletion prog/lantern/lantern_server_nexus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def self.assemble(
location: resource.location,
size: target_vm_size,
storage_size_gib: target_storage_size_gib,
boot_image: "ubuntu-2204-jammy-v20240319",
boot_image: Config.lantern_gcp_image,
labels: {"parent" => resource.name}
)

Expand Down
11 changes: 7 additions & 4 deletions rhizome/lantern/bin/configure
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,18 @@ def setup_initial_compose_file
end
end

install_dependencies
puts "dependencies installed"
if $configure_hash[:skip_deps].nil?
install_dependencies
puts "dependencies installed"
configure_gcr($configure_hash["gcp_creds_gcr_b64"], $configure_hash["container_image"])
puts "GCR repo ready"
end

setup_fs
puts "filesystem ready"
setup_env
puts ".env setted up"
setup_initial_compose_file
puts "docker-compose.yaml ready"
configure_gcr($configure_hash["gcp_creds_gcr_b64"], $configure_hash["container_image"])
puts "GCR repo ready"
run_database($configure_hash["container_image"])
puts "database ready"
22 changes: 22 additions & 0 deletions spec/lib/hosting/gcp_apis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@
end

describe "#wait_for_operation" do
it "waits for global operation to be done at first attempt" do
stub_request(:post, "https://oauth2.googleapis.com/token").to_return(status: 200, body: JSON.dump({}), headers: {"Content-Type" => "application/json"})
stub_request(:post, "https://compute.googleapis.com/compute/v1/projects/test-project/global/operations/test-op/wait").to_return(status: 200, body: JSON.dump({"status" => "DONE"}), headers: {"Content-Type" => "application/json"})

api = described_class.new
expect { api.wait_for_operation("global", "test-op") }.not_to raise_error
end

it "waits for operation to be done at first attempt" do
stub_request(:post, "https://oauth2.googleapis.com/token").to_return(status: 200, body: JSON.dump({}), headers: {"Content-Type" => "application/json"})
stub_request(:post, "https://compute.googleapis.com/compute/v1/projects/test-project/zones/us-central1-a/operations/test-op/wait").to_return(status: 200, body: JSON.dump({"status" => "DONE"}), headers: {"Content-Type" => "application/json"})
Expand Down Expand Up @@ -316,5 +324,19 @@
expect { api.wait_for_operation("us-central1-a", "test-op") }.not_to raise_error
end
end

describe "#create_image" do
it "cerates image" do
stub_request(:post, "https://oauth2.googleapis.com/token").to_return(status: 200, body: JSON.dump({}), headers: {"Content-Type" => "application/json"})
stub_request(:post, "https://compute.googleapis.com/compute/beta/projects/test-project/global/images")
.with(
body: "{\"kind\":\"compute#image\",\"description\":\"test-desc\",\"name\":\"test-name\",\"family\":\"lantern-ubuntu\",\"sourceDisk\":\"projects/test-project/zones/us-central1-a/disks/inst-name\",\"storageLocations\":[\"us\"]}"
)
.to_return(status: 200, body: JSON.dump({"id" => "test-op"}), headers: {})
stub_request(:post, "https://compute.googleapis.com/compute/v1/projects/test-project/global/operations/test-op/wait").to_return(status: 200, body: JSON.dump({"status" => "DONE"}), headers: {"Content-Type" => "application/json"})
api = described_class.new
expect { api.create_image(name: "test-name", vm_name: "inst-name", zone: "us-central1-a", description: "test-desc") }.not_to raise_error
end
end
end
end
5 changes: 5 additions & 0 deletions spec/model/lantern/lantern_server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
db_user_password: "pwd123",
superuser_password: "pwd1234",
restore_target: nil)
expect(Config).to receive(:lantern_gcp_image_cached).and_return(false).at_least(:once)
expect(Config).to receive(:prom_password).and_return("pwd123").at_least(:once)
expect(Config).to receive(:gcp_creds_gcr_b64).and_return("test-creds").at_least(:once)
expect(Config).to receive(:gcp_creds_logging_b64).and_return("test-creds").at_least(:once)
Expand All @@ -254,6 +255,7 @@
walg_conf = timeline.generate_walg_config
expected_conf = JSON.generate({
enable_coredumps: true,
skip_deps: false,
org_id: resource.org_id,
instance_id: resource.name,
instance_type: lantern_server.standby? ? "reader" : "writer",
Expand Down Expand Up @@ -313,6 +315,7 @@
walg_conf = timeline.generate_walg_config
expected_conf = JSON.generate({
enable_coredumps: true,
skip_deps: true,
org_id: resource.org_id,
instance_id: resource.name,
instance_type: lantern_server.standby? ? "reader" : "writer",
Expand Down Expand Up @@ -370,6 +373,7 @@
walg_conf = timeline.generate_walg_config
expected_conf = JSON.generate({
enable_coredumps: true,
skip_deps: true,
org_id: resource.org_id,
instance_id: resource.name,
instance_type: lantern_server.standby? ? "reader" : "writer",
Expand Down Expand Up @@ -428,6 +432,7 @@
walg_conf = timeline.generate_walg_config
expected_conf = JSON.generate({
enable_coredumps: true,
skip_deps: true,
org_id: resource.org_id,
instance_id: resource.name,
instance_type: lantern_server.standby? ? "reader" : "writer",
Expand Down
4 changes: 2 additions & 2 deletions spec/prog/gcp_vm/nexus_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

let(:st) { Strand.new }
let(:gcp_vm) {
vm = GcpVm.new_with_id(family: "standard", cores: 1, name: "dummy-vm", arch: "x64", location: "us-central1", storage_size_gib: 50)
vm = GcpVm.new_with_id(family: "standard", cores: 1, name: "dummy-vm", arch: "x64", location: "us-central1", storage_size_gib: 50, boot_image: Config.lantern_gcp_image)
vm
}
let(:prj) { Project.create_with_id(name: "default", provider: "gcp").tap { _1.associate_with_project(_1) } }
Expand Down Expand Up @@ -71,7 +71,7 @@
gcp_api = instance_double(Hosting::GcpApis)
expect(Hosting::GcpApis).to receive(:new).and_return(gcp_api)
frame = {"labels" => {"parent" => "test-label"}}
expect(gcp_api).to receive(:create_vm).with("dummy-vm", "us-central1-a", nil, nil, nil, "standard-1", 50, labels: frame["labels"])
expect(gcp_api).to receive(:create_vm).with("dummy-vm", "us-central1-a", gcp_vm.boot_image, nil, nil, "standard-1", 50, labels: frame["labels"])
expect(nx).to receive(:frame).and_return(frame)
expect(nx.strand).to receive(:stack).and_return([frame]).at_least(:once)
expect(nx.strand).to receive(:modified!).with(:stack).at_least(:once)
Expand Down

0 comments on commit 8ea6fe4

Please sign in to comment.