Skip to content

Commit

Permalink
Add partial VM stop/start support
Browse files Browse the repository at this point in the history
  • Loading branch information
sneal committed Aug 4, 2022
1 parent 3ce57ce commit 695ee43
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 9 deletions.
64 changes: 63 additions & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ func (c *Client) UpdateCloudConfig(config string) error {
return nil
}

//Cleanup will post to the cleanup endpoint of bosh, passing along the removeall flag passed in as a bool
// Cleanup will post to the cleanup endpoint of bosh, passing along the removeAll flag passed in as a bool
func (c *Client) Cleanup(removeAll bool) (Task, error) {
r := c.NewRequest("POST", "/cleanup")
var requestBody struct {
Expand Down Expand Up @@ -462,3 +462,65 @@ func (c *Client) Cleanup(removeAll bool) (Task, error) {
}
return task, err
}

func (c *Client) Restart(deployment, instance string) error {
return nil
}

func (c *Client) Stop(deployment, jobName, vmID string) error {
// /deployments/cf-f9cc327448912298c6ef/jobs/router/3fc7759a-c453-448c-97b6-844c85029f02?state=stopped
return c.doStop(jobName, vmID, fmt.Sprintf("/deployments/%s/jobs/%s/%s?state=stopped", deployment, jobName, vmID))
}

func (c *Client) StopNoConverge(deployment, jobName, vmID string) error {
// /deployments/cf-f9cc327448912298c6ef/instance_groups/router/3fc7759a-c453-448c-97b6-844c85029f02/actions/stop
return c.doStop(jobName, vmID, fmt.Sprintf("/deployments/%s/instance_groups/%s/%s/actions/stop", deployment, jobName, vmID))
}

func (c *Client) Start(deployment, instanceName string) error {
return nil
}

func (c *Client) doStop(jobName, vmID, stopPath string) error {
r := c.NewRequest("PUT", stopPath)
resp, err := c.DoRequest(r)

if err != nil {
return fmt.Errorf("error creating VM stop task: %w", err)
}
defer func() { _ = resp.Body.Close() }()

resBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("error reading VM stop task response: %w", err)
}

var task Task
err = json.Unmarshal(resBody, &task)
if err != nil {
return fmt.Errorf("error unmarshalling VM stop task response: %w", err)
}

// TODO: extract this retry somewhere
// TODO: 10m enough? Too much?
const maxTries = 600 // 10m
for i := 0; i <= maxTries; i++ {
if i == maxTries {
return fmt.Errorf("timed out getting VM stop task results after %d tries", maxRetries)
}

taskStatus, err := c.GetTask(task.ID)
if err != nil {
log.Printf("Error getting task %v, retrying...", err)
}
if taskStatus.State == "done" {
break
}
if taskStatus.State == "error" {
return fmt.Errorf("error occurred stopping instance %s/%s", jobName, vmID)
}
time.Sleep(time.Second)
}

return nil
}
54 changes: 54 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,59 @@ var _ = Describe("Api", func() {
})
})

Describe("Test stop instance", func() {
BeforeEach(func() {
setupMultiple([]MockRoute{
{"PUT", "/deployments/deployment-foo/jobs/job-foo/id-foo", "", server.URL + "/tasks/3"},
{"GET", "/tasks/3", task3, ""},
{"GET", "/tasks/3", task3, ""},
}, "basic")

config := &Config{
BOSHAddress: server.URL,
Username: "admin",
Password: "admin",
}

client, _ = NewClient(config)
})

AfterEach(func() {
teardown()
})

It("can stop an instance", func() {
err := client.Stop("deployment-foo", "job-foo", "id-foo")
Expect(err).Should(BeNil())
})
})

Describe("Test stop instance no converge", func() {
BeforeEach(func() {
setupMultiple([]MockRoute{
{"PUT", "/deployments/deployment-foo/instance_groups/job-foo/id-foo/actions/stop", "", server.URL + "/tasks/3"},
{"GET", "/tasks/3", task3, ""},
{"GET", "/tasks/3", task3, ""},
}, "basic")

config := &Config{
BOSHAddress: server.URL,
Username: "admin",
Password: "admin",
}

client, _ = NewClient(config)
})

AfterEach(func() {
teardown()
})

It("can stop an instance", func() {
err := client.StopNoConverge("deployment-foo", "job-foo", "id-foo")
Expect(err).Should(BeNil())
})
})

})
})
27 changes: 19 additions & 8 deletions bosh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ func setupMultiple(mockEndpoints []MockRoute, authType string) {
endpoint := mock.Endpoint
output := mock.Output
redirect := mock.Redirect
if redirect != "" {
r.Get(endpoint, func(r render.Render) {
r.Redirect(redirect)
})
}
if method == "GET" {
r.Get(endpoint, func() string {
return output
})
if redirect != "" {
r.Get(endpoint, func(r render.Render) {
r.Redirect(redirect)
})
} else {
r.Get(endpoint, func() string {
return output
})
}
} else if method == "POST" {
r.Post(endpoint, func() string {
return output
Expand All @@ -56,6 +57,16 @@ func setupMultiple(mockEndpoints []MockRoute, authType string) {
r.Delete(endpoint, func() (int, string) {
return 204, output
})
} else if method == "PUT" {
if redirect != "" {
r.Put(endpoint, func(r render.Render) {
r.Redirect(redirect)
})
} else {
r.Put(endpoint, func() (int, string) {
return 200, output
})
}
}
}
if authType != "uaa" {
Expand Down
12 changes: 12 additions & 0 deletions payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,15 @@ const task = `{
}`

const vms = `{"vm_cid":"ec974048-3352-4ba4-669d-beab87b16bcb","disk_cid":null,"ips":["10.244.0.142"],"dns":[],"agent_id":"c5e7c705-459e-41c0-b640-db32d8dc6e71","job_name":"doppler_z1","index":0,"job_state":"running","state":"started","resource_pool":"medium_z1","vm_type":"default","vitals":{"cpu":{"sys":"9.1","user":"2.1","wait":"1.7"},"disk":{"ephemeral":{"inode_percent":"11","percent":"36"},"persistent":{"inode_percent":"11","percent":"36"},"system":{"inode_percent":"11","percent":"36"}},"load":["0.61","0.74","1.10"],"mem":{"kb":"2520960","percent":"41"},"swap":{"kb":"102200","percent":"10"}},"processes":[{"name":"doppler","state":"running","uptime":{"secs":11794845},"mem":{"kb":2252,"percent":16.5},"cpu":{"total":0.9}},{"name":"syslog_drain_binder","state":"running","uptime":{"secs":11794845},"mem":{"kb":2252,"percent":16.5},"cpu":{"total":0.9}},{"name":"metron_agent","state":"running","uptime":{"secs":11794845},"mem":{"kb":2252,"percent":16.5},"cpu":{"total":0.9}}],"resurrection_paused":false,"az":"z1","id":"4a9278c8-e93a-4d6a-b22c-13560208da9e","bootstrap":true,"ignore":false}`

const task3 = `{
"id": 3,
"state": "done",
"description": "stop instance",
"timestamp": 1659568450,
"started_at": 1659568410,
"result": "job-foo/id-foo",
"user": "bosh",
"deployment": "deployment-foo",
"context_id": ""
}`

0 comments on commit 695ee43

Please sign in to comment.