Skip to content

Commit

Permalink
Ignore timeout error when waiting for gcp operation
Browse files Browse the repository at this point in the history
  • Loading branch information
var77 committed May 1, 2024
1 parent ad52b31 commit 20a0dd5
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 74 deletions.
1 change: 1 addition & 0 deletions lib/hosting/gcp_apis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def wait_for_operation(zone, operation)
response = connection.post(path: "/compute/v1/projects/#{@project}/zones/#{zone}/operations/#{operation}/wait", expects: [200])
body = JSON.parse(response.body)
break unless body["status"] != "DONE"
rescue Excon::Error::Timeout
end
end

Expand Down
5 changes: 5 additions & 0 deletions prog/lantern/lantern_resource_nexus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def self.assemble(project_id:, location:, name:, target_vm_size:, target_storage
superuser_password = parent.superuser_password
repl_user = parent.repl_user
repl_password = parent.repl_password
lantern_version = parent.representative_server.lantern_version
extras_version = parent.representative_server.extras_version
minor_version = parent.representative_server.minor_version
target_storage_size_gib = parent.representative_server.target_storage_size_gib

end

lantern_resource = LanternResource.create(
Expand Down
46 changes: 46 additions & 0 deletions routes/api/project/lantern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,51 @@ class CloverApi
count: result[:count]
}
end

r.post true do
Authorization.authorize(@current_user.id, "Postgres:create", @project.id)
parsed_size = Validation.validate_lantern_size(r.params["size"])
Validation.validate_name(r.params["name"])
Validation.validate_org_id(r.params["org_id"])
restore_target = nil

if r.params["parent_id"].nil?
Validation.validate_version(r.params["lantern_version"], "lantern_version")
Validation.validate_version(r.params["extras_version"], "extras_version")
Validation.validate_version(r.params["minor_version"], "minor_version")
else
restore_target = r.params["restore_target"].nil? ? Time.new : Time.new(r.params["restore_target"])
end

domain = r.params["domain"]

if domain.nil? && r.params["subdomain"]
domain = "#{r.params["subdomain"]}.#{Config.lantern_top_domain}"
end

st = Prog::Lantern::LanternResourceNexus.assemble(
project_id: @project.id,
location: r.params["location"],
name: r.params["name"],
org_id: r.params["org_id"].to_i,
target_vm_size: parsed_size.vm_size,
target_storage_size_gib: r.params["storage_size_gib"] || parsed_size.storage_size_gib,
lantern_version: r.params["lantern_version"],
extras_version: r.params["extras_version"],
minor_version: r.params["minor_version"],
domain: domain,
db_name: r.params["db_name"],
db_user: r.params["db_user"],
db_user_password: r.params["db_user_password"],
app_env: r.params["app_env"] || Config.rack_env,
repl_password: r.params["repl_password"],
enable_debug: r.params["enable_debug"],
superuser_password: r.params["postgres_password"],
parent_id: r.params["parent_id"],
restore_target: restore_target
)
pg = LanternResource[st.id]
serialize(pg, :detailed)
end
end
end
38 changes: 0 additions & 38 deletions routes/api/project/location/lantern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,43 +159,5 @@ class CloverApi
count: result[:count]
}
end

r.post true do
Authorization.authorize(@current_user.id, "Postgres:create", @project.id)
parsed_size = Validation.validate_lantern_size(r.params["size"])
Validation.validate_name(r.params["name"])
Validation.validate_org_id(r.params["org_id"])
Validation.validate_version(r.params["lantern_version"], "lantern_version")
Validation.validate_version(r.params["extras_version"], "extras_version")
Validation.validate_version(r.params["minor_version"], "minor_version")

domain = r.params["domain"]

if domain.nil? && r.params["subdomain"]
domain = "#{r.params["subdomain"]}.#{Config.lantern_top_domain}"
end

st = Prog::Lantern::LanternResourceNexus.assemble(
project_id: @project.id,
location: @location,
name: r.params["name"],
org_id: r.params["org_id"].to_i,
target_vm_size: parsed_size.vm_size,
target_storage_size_gib: r.params["storage_size_gib"] || parsed_size.storage_size_gib,
lantern_version: r.params["lantern_version"],
extras_version: r.params["extras_version"],
minor_version: r.params["minor_version"],
domain: domain,
db_name: r.params["db_name"],
db_user: r.params["db_user"],
db_user_password: r.params["db_user_password"],
app_env: r.params["app_env"],
repl_password: r.params["repl_password"],
enable_debug: r.params["enable_debug"],
superuser_password: r.params["postgres_password"]
)
pg = LanternResource[st.id]
serialize(pg, :detailed)
end
end
end
10 changes: 10 additions & 0 deletions spec/lib/hosting/gcp_apis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,16 @@
expect { api.wait_for_operation("us-central1-a", "test-op") }.not_to raise_error
end

it "waits for operation until done after timeout" 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_raise(Excon::Error::Timeout)
.to_return(status: 200, body: JSON.dump({"status" => "DONE"}), headers: {"Content-Type" => "application/json"})

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

it "waits for operation until done" 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")
Expand Down
110 changes: 110 additions & 0 deletions spec/routes/api/project/lantern_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@

let(:project) { user.create_project_with_default_policy("project-1", provider: "gcp") }

let(:pg) do
st = Prog::Lantern::LanternResourceNexus.assemble(
project_id: project.id,
location: "us-central1",
name: "instance-1",
target_vm_size: "n1-standard-2",
target_storage_size_gib: 100,
org_id: 0
)
LanternResource[st.id]
end

describe "unauthenticated" do
it "not list" do
get "/api/project/#{project.ubid}/lantern"
Expand Down Expand Up @@ -44,5 +56,103 @@
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)["items"].length).to eq(2)
end

describe "create" do
it "creates new lantern database" do
post "/api/project/#{project.ubid}/lantern", {size: "n1-standard-2", name: "instance-2", org_id: 0, location: "us-central1", storage_size_gib: 100, lantern_version: "0.2.2", extras_version: "0.1.4", minor_version: "1", domain: "test.db.lantern.dev", app_env: "test", repl_password: "test-repl-pass", enable_telemetry: true, postgres_password: "test-pg-pass"}

body = JSON.parse(last_response.body)
expect(last_response.status).to eq(200)

expect(body["name"]).to eq("instance-2")
expect(body["state"]).to eq("creating")
expect(body["instance_type"]).to eq("writer")
expect(body["location"]).to eq("us-central1")
expect(body["lantern_version"]).to eq("0.2.2")
expect(body["extras_version"]).to eq("0.1.4")
expect(body["minor_version"]).to eq("1")
expect(body["org_id"]).to eq(0)
expect(body["storage_size_gib"]).to eq(100)
expect(body["domain"]).to eq("test.db.lantern.dev")
expect(body["app_env"]).to eq("test")
expect(body["debug"]).to be(false)
expect(body["enable_telemetry"]).to be(true)
expect(body["repl_user"]).to eq("repl_user")
expect(body["repl_password"]).to eq("test-repl-pass")
expect(body["postgres_password"]).to eq("test-pg-pass")
end

it "creates new lantern database from backup" do
expect(LanternResource).to receive(:[]).and_call_original.twice
expect(LanternResource).to receive(:[]).with(pg.id).and_return(pg)
expect(LanternResource).to receive(:[]).and_call_original.at_least(:once)
expect(pg.timeline).to receive(:refresh_earliest_backup_completion_time).at_least(:once)
expect(pg.timeline).to receive(:earliest_restore_time).and_return(Time.new - 1000000).at_least(:once)
expect(pg.timeline).to receive(:latest_restore_time).and_return(Time.new).at_least(:once)
post "/api/project/#{project.ubid}/lantern", {size: "n1-standard-2", name: "instance-from-backup", org_id: 0, location: "us-central1", domain: "test.db.lantern.dev", parent_id: pg.id}

body = JSON.parse(last_response.body)

expect(last_response.status).to eq(200)

expect(body["name"]).to eq("instance-from-backup")
expect(body["state"]).to eq("creating")
expect(body["instance_type"]).to eq("writer")
expect(body["location"]).to eq("us-central1")
expect(body["lantern_version"]).to eq(pg.representative_server.lantern_version)
expect(body["extras_version"]).to eq(pg.representative_server.extras_version)
expect(body["minor_version"]).to eq(pg.representative_server.minor_version)
expect(body["org_id"]).to eq(0)
expect(body["storage_size_gib"]).to eq(pg.representative_server.target_storage_size_gib)
expect(body["domain"]).to eq("test.db.lantern.dev")
expect(body["app_env"]).to eq("test")
expect(body["debug"]).to be(false)
expect(body["enable_telemetry"]).to be(true)
expect(body["repl_user"]).to eq("repl_user")
expect(body["repl_password"]).to eq(pg.repl_password)
expect(body["postgres_password"]).to eq(pg.superuser_password)
end

it "creates new lantern database from backup with restore time" do
expect(LanternResource).to receive(:[]).and_call_original.twice
expect(LanternResource).to receive(:[]).with(pg.id).and_return(pg)
expect(LanternResource).to receive(:[]).and_call_original.at_least(:once)
expect(pg.timeline).to receive(:refresh_earliest_backup_completion_time).at_least(:once)
expect(pg.timeline).to receive(:earliest_restore_time).and_return(Time.new - 1000000).at_least(:once)
expect(pg.timeline).to receive(:latest_restore_time).and_return(Time.new).at_least(:once)
post "/api/project/#{project.ubid}/lantern", {size: "n1-standard-2", name: "instance-from-backup", org_id: 0, location: "us-central1", domain: "test.db.lantern.dev", parent_id: pg.id, restore_target: Time.now - 1000}

body = JSON.parse(last_response.body)

expect(last_response.status).to eq(200)

expect(body["name"]).to eq("instance-from-backup")
expect(body["state"]).to eq("creating")
expect(body["instance_type"]).to eq("writer")
expect(body["location"]).to eq("us-central1")
expect(body["lantern_version"]).to eq(pg.representative_server.lantern_version)
expect(body["extras_version"]).to eq(pg.representative_server.extras_version)
expect(body["minor_version"]).to eq(pg.representative_server.minor_version)
expect(body["org_id"]).to eq(0)
expect(body["storage_size_gib"]).to eq(pg.representative_server.target_storage_size_gib)
expect(body["domain"]).to eq("test.db.lantern.dev")
expect(body["app_env"]).to eq("test")
expect(body["debug"]).to be(false)
expect(body["enable_telemetry"]).to be(true)
expect(body["repl_user"]).to eq("repl_user")
expect(body["repl_password"]).to eq(pg.repl_password)
expect(body["postgres_password"]).to eq(pg.superuser_password)
end

it "creates new lantern database with subdomain" do
expect(Config).to receive(:lantern_top_domain).and_return("db.lantern.dev")
post "/api/project/#{project.ubid}/lantern", {size: "n1-standard-2", name: "instance-2", org_id: 0, location: "us-central1", storage_size_gib: 100, lantern_version: "0.2.2", extras_version: "0.1.4", minor_version: "1", subdomain: "test", app_env: "test", repl_password: "test-repl-pass", enable_telemetry: true, postgres_password: "test-pg-pass"}

body = JSON.parse(last_response.body)
expect(last_response.status).to eq(200)

expect(body["domain"]).to eq("test.db.lantern.dev")
end
end
end
end
36 changes: 0 additions & 36 deletions spec/routes/api/project/location/lantern_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,42 +141,6 @@
end
end

describe "create" do
it "creates new lantern database" do
post "/api/project/#{project.ubid}/location/#{pg.location}/lantern", {size: "n1-standard-2", name: "instance-2", org_id: 0, location: "us-central1", storage_size_gib: 100, lantern_version: "0.2.2", extras_version: "0.1.4", minor_version: "1", domain: "test.db.lantern.dev", app_env: "test", repl_password: "test-repl-pass", enable_telemetry: true, postgres_password: "test-pg-pass"}

body = JSON.parse(last_response.body)
expect(last_response.status).to eq(200)

expect(body["name"]).to eq("instance-2")
expect(body["state"]).to eq("creating")
expect(body["instance_type"]).to eq("writer")
expect(body["location"]).to eq("us-central1")
expect(body["lantern_version"]).to eq("0.2.2")
expect(body["extras_version"]).to eq("0.1.4")
expect(body["minor_version"]).to eq("1")
expect(body["org_id"]).to eq(0)
expect(body["storage_size_gib"]).to eq(100)
expect(body["domain"]).to eq("test.db.lantern.dev")
expect(body["app_env"]).to eq("test")
expect(body["debug"]).to be(false)
expect(body["enable_telemetry"]).to be(true)
expect(body["repl_user"]).to eq("repl_user")
expect(body["repl_password"]).to eq("test-repl-pass")
expect(body["postgres_password"]).to eq("test-pg-pass")
end

it "creates new lantern database with subdomain" do
expect(Config).to receive(:lantern_top_domain).and_return("db.lantern.dev")
post "/api/project/#{project.ubid}/location/#{pg.location}/lantern", {size: "n1-standard-2", name: "instance-2", org_id: 0, location: "us-central1", storage_size_gib: 100, lantern_version: "0.2.2", extras_version: "0.1.4", minor_version: "1", subdomain: "test", app_env: "test", repl_password: "test-repl-pass", enable_telemetry: true, postgres_password: "test-pg-pass"}

body = JSON.parse(last_response.body)
expect(last_response.status).to eq(200)

expect(body["domain"]).to eq("test.db.lantern.dev")
end
end

describe "#update-extension" do
it "updates lantern extension" do
post "/api/project/#{project.ubid}/location/#{pg.location}/lantern/instance-1/update-extension", {lantern_version: "0.2.4", extras_version: Config.lantern_extras_default_version}
Expand Down

0 comments on commit 20a0dd5

Please sign in to comment.