Skip to content

Commit

Permalink
Add last_status_change to deployments object
Browse files Browse the repository at this point in the history
* indicates last time status.reason or status.value was updated
* status_updated_at column is set to updated_at for exisiting deployments. Unfortunately updated_at is nullable, so those with null updated_at (unclear if this is a real scenario) will have status_updated_at set to the current time

Co-authored-by: Joao Pereira <[email protected]>
Co-authored-by: Seth Boyles <[email protected]>
  • Loading branch information
joaopapereira and sethboyles committed Jul 16, 2024
1 parent 7494b94 commit c3ab524
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 14 deletions.
13 changes: 13 additions & 0 deletions app/models/runtime/deployment_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ def deploying_count
end
end

def before_update
super
set_status_updated_at
end

def deploying?
state == DEPLOYING_STATE
end
Expand All @@ -76,5 +81,13 @@ def cancelable?
DeploymentModel::CANCELING_STATE]
valid_states_for_cancel.include?(state)
end

private

def set_status_updated_at
return unless column_changed?(:status_reason) || column_changed?(:status_value)

self.status_updated_at = updated_at
end
end
end
3 changes: 2 additions & 1 deletion app/presenters/v3/deployment_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def to_hash
value: deployment.status_value,
reason: deployment.status_reason,
details: {
last_successful_healthcheck: deployment.last_healthy_at
last_successful_healthcheck: deployment.last_healthy_at,
last_status_change: deployment.status_updated_at
}
},
strategy: deployment.strategy,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Sequel.migration do
up do
alter_table(:deployments) do
add_column :status_updated_at, DateTime, default: Sequel::CURRENT_TIMESTAMP, null: false
end
run 'update deployments set status_updated_at = updated_at where updated_at is not null'
end

down do
alter_table(:deployments) do
drop_column :status_updated_at
end
end
end
3 changes: 2 additions & 1 deletion docs/v3/source/includes/resources/deployments/_object.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Name | Type | Description
**updated_at** | _[timestamp](#timestamps)_ | The time with zone when the object was last updated
**status.value** | _string_ | The current status of the deployment; valid values are `ACTIVE` (meaning in progress) and `FINALIZED` (meaning finished, either successfully or not)
**status.reason** | _string_ | The reason for the status of the deployment;<br>following list represents valid values:<br>1. If **status.value** is `ACTIVE`<br>- `DEPLOYING`<br>- `CANCELING`<br>2. If **status.value** is `FINALIZED`<br>- `DEPLOYED`<br>- `CANCELED`<br>- `SUPERSEDED` (another deployment created for app before completion)<br>
**status.details** | _object_ | The details for the status of the deployment shows a timestamp of the last successful healthcheck
**status.details.last_successful_healthcheck** | _[timestamp](#timestamps)_ | Timestamp of the last successful healthcheck
**status.details.last_status_change** | _[timestamp](#timestamps)_ | Timestamp of last change to status.value or status.reason
**strategy** | _string_ | Strategy used for the deployment; supported strategies are `rolling` only
**droplet.guid** | _string_ | The droplet guid that the deployment is transitioning the app to
**previous_droplet.guid** | _string_ | The app's [current droplet guid](#get-current-droplet-association-for-an-app) before the deployment was created
Expand Down
36 changes: 24 additions & 12 deletions spec/request/deployments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -136,7 +137,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -218,7 +220,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -336,7 +339,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -414,7 +418,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -494,7 +499,8 @@
'value' => VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYED_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -661,7 +667,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -721,7 +728,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -839,7 +847,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down Expand Up @@ -929,7 +938,8 @@
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'droplet' => {
Expand Down Expand Up @@ -1051,7 +1061,8 @@ def json_for_deployment(deployment, app_model, droplet, status_value, status_rea
value: status_value,
reason: status_reason,
details: {
last_successful_healthcheck: iso8601
last_successful_healthcheck: iso8601,
last_status_change: iso8601
}
},
strategy: 'rolling',
Expand Down Expand Up @@ -1345,7 +1356,8 @@ def json_for_deployment(deployment, app_model, droplet, status_value, status_rea
'value' => VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
'reason' => VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON,
'details' => {
'last_successful_healthcheck' => iso8601
'last_successful_healthcheck' => iso8601,
'last_status_change' => iso8601
}
},
'strategy' => 'rolling',
Expand Down
49 changes: 49 additions & 0 deletions spec/unit/models/runtime/deployment_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,54 @@ module VCAP::CloudController
expect(deployment.cancelable?).to be(false)
end
end

describe '#status_updated_at' do
let(:deployment) do
DeploymentModel.make(
app: app,
droplet: droplet,
deploying_web_process: deploying_web_process,
status_reason: DeploymentModel::DEPLOYING_STATUS_REASON,
status_value: DeploymentModel::ACTIVE_STATUS_VALUE
)
end

# Can't use Timecop with created_at since its set by the DB
let(:creation_time) { deployment.created_at }
let(:update_time) { deployment.created_at + 24.hours }

before do
Timecop.freeze(creation_time)
end

after do
Timecop.return
end

it 'is defaulted with the created_at time' do
expect(deployment.status_updated_at).to eq(deployment.created_at)
end

it 'updates when status_reason has changed' do
deployment.status_reason = DeploymentModel::CANCELING_STATUS_REASON
Timecop.freeze(update_time)
deployment.save
expect(deployment.status_updated_at).to eq update_time
end

it 'updates when status_value has changed' do
deployment.status_value = DeploymentModel::FINALIZED_STATUS_VALUE
Timecop.freeze(update_time)
deployment.save
expect(deployment.status_updated_at).to eq update_time
end

it 'doesnt update when status_value or status_reason is unchanged' do
deployment.strategy = 'faux_strategy'
Timecop.freeze(update_time)
deployment.save
expect(deployment.status_updated_at).to eq creation_time
end
end
end
end
2 changes: 2 additions & 0 deletions spec/unit/presenters/v3/deployment_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module VCAP::CloudController::Presenters::V3
previous_droplet: previous_droplet,
deploying_web_process: process,
last_healthy_at: '2019-07-12 19:01:54',
status_updated_at: '2019-07-11 19:01:54',
state: deployment_state,
status_value: VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE,
status_reason: VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON
Expand All @@ -29,6 +30,7 @@ module VCAP::CloudController::Presenters::V3
expect(result[:status][:value]).to eq(VCAP::CloudController::DeploymentModel::ACTIVE_STATUS_VALUE)
expect(result[:status][:reason]).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATUS_REASON)
expect(result[:status][:details][:last_successful_healthcheck]).to eq('2019-07-12 19:01:54')
expect(result[:status][:details][:last_status_change]).to eq('2019-07-11 19:01:54')

expect(result[:strategy]).to eq('rolling')

Expand Down

0 comments on commit c3ab524

Please sign in to comment.