Skip to content

Commit

Permalink
feat: impl moonraker version recovery
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Bassett <[email protected]>
  • Loading branch information
cadriel committed Apr 5, 2021
1 parent 4da9c67 commit 39efb0d
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 59 deletions.
4 changes: 2 additions & 2 deletions src/components/settings/VersionInformationDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ export default class VersionInformationDialog extends Vue {
// For type client, just show the release notes if we can.
get commitHistory () {
return this.$store.getters['version/getCommitHistory'](this.component.type)
return this.$store.getters['version/getCommitHistory'](this.component.key)
}
get baseUrl () {
if ('owner' in this.component) {
return `https://github.com/${this.component.owner}/${this.component.type}`
return `https://github.com/${this.component.owner}/${this.component.key}`
}
return ''
}
Expand Down
61 changes: 43 additions & 18 deletions src/components/settings/VersionSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,26 @@

<template v-for="(component, i) in components">
<app-setting
:key="`component-${component.type}-${component.name}`"
:key="`component-${component.key}-${component.name}`"
:title="packageTitle(component)"
>
<template v-slot:sub-title>
<span v-if="component.type !== 'system'">{{ component.version }}</span>
<span v-if="'remote_version' in component && hasUpdate(component.type)">
<span v-if="component.key !== 'system'">{{ component.version }}</span>
<span v-if="'remote_version' in component && hasUpdate(component.key)">
-> {{ component.remote_version }}
</span>
<span v-if="component.type === 'system' && component.package_count > 0">
<span v-if="component.key === 'system' && component.package_count > 0">
{{ component.package_count }} packages
</span>
</template>

<v-tooltip left>
<v-tooltip
left
v-if="hasUpdate(component.key) && !inError(component)"
>
<template v-slot:activator="{ attrs, on }">
<app-btn
v-if="hasUpdate(component.type)"
v-if="hasUpdate(component.key) && !inError(component)"
@click="handleInformationDialog(component)"
v-on="on"
v-bind="attrs"
Expand All @@ -56,17 +59,18 @@
</v-tooltip>

<version-status
:has-update="hasUpdate(component.type)"
:has-update="hasUpdate(component.key)"
:disabled="isRefreshing || printerPrinting"
:loading="isRefreshing"
:dirty="('is_dirty' in component) ? component.is_dirty : false"
:valid="('is_valid' in component) ? component.is_valid : true"
@on-update="updateComponent(component.type)">
@on-update="handleUpdateComponent(component.key)"
@on-recover="handleRecoverComponent(component)">
</version-status>

</app-setting>

<v-divider :key="`component-${component.type}-${component.name}-_divider`" v-if="i < components.length - 1 && components.length > 0"></v-divider>
<v-divider :key="`component-${component.key}-${component.name}-_divider`" v-if="i < components.length - 1 && components.length > 0"></v-divider>
</template>

</v-card>
Expand Down Expand Up @@ -113,26 +117,33 @@ export default class VersionSettings extends Mixins(StateMixin) {
}
packageTitle (component: HashVersion | OSPackage | ArtifactVersion) {
if (component.type === 'system') {
if (component.key === 'system') {
return 'os packages'
}
return component.type
return component.key
}
hasUpdate (component: string) {
return this.$store.getters['version/hasUpdate'](component)
}
inError (component: HashVersion | OSPackage | ArtifactVersion) {
const dirty = ('is_dirty' in component) ? component.is_dirty : false
const valid = ('is_valid' in component) ? component.is_valid : true
return (dirty || !valid)
}
packageUrl (component: HashVersion | OSPackage | ArtifactVersion) {
if (component.type === 'klipper') return 'https://github.com/KevinOConnor/klipper/commits/master'
if (component.type === 'moonraker') return 'https://github.com/Arksine/moonraker/commits/master'
if (component.type === 'fluidd' && 'name' in component && component.name === 'fluidd') return 'https://github.com/cadriel/fluidd/releases'
if (component.key === 'klipper') return 'https://github.com/KevinOConnor/klipper/commits/master'
if (component.key === 'moonraker') return 'https://github.com/Arksine/moonraker/commits/master'
if (component.key === 'fluidd' && 'name' in component && component.name === 'fluidd') return 'https://github.com/cadriel/fluidd/releases'
}
updateComponent (type: string) {
// Will attempt to update the requirec component based on its type.
handleUpdateComponent (key: string) {
this.$store.dispatch('version/onUpdateStatus', { busy: true })
switch (type) {
switch (key) {
case 'klipper':
SocketActions.machineUpdateKlipper()
break
Expand All @@ -143,20 +154,34 @@ export default class VersionSettings extends Mixins(StateMixin) {
SocketActions.machineUpdateSystem()
break
default: // assume a client update
SocketActions.machineUpdateClient(type)
SocketActions.machineUpdateClient(key)
break
}
// Close the drawer
this.$emit('click')
}
// Will attempt to recover a component based on its type and current status.
handleRecoverComponent (component: HashVersion | OSPackage | ArtifactVersion) {
this.$store.dispatch('version/onUpdateStatus', { busy: true })
const dirty = ('is_dirty' in component) ? component.is_dirty : false
const valid = ('is_valid' in component) ? component.is_valid : true
// console.log('attempting recovery...', component.type)
if (dirty) {
SocketActions.machineUpdateRecover(component.key, false)
}
if (!valid) {
SocketActions.machineUpdateRecover(component.key, true)
}
}
forceCheck () {
SocketActions.machineUpdateStatus(true)
}
getBaseUrl (component: HashVersion | ArtifactVersion) {
if ('owner' in component) {
return `https://github.com/${component.owner}/${component.type}`
return `https://github.com/${component.owner}/${component.key}`
}
return ''
}
Expand Down
19 changes: 15 additions & 4 deletions src/components/settings/VersionStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
outlined
:color="(disabled) ? 'grey darken-2' : 'success'"
>{{ $t('app.version.label.up_to_date') }}</v-chip>
<v-tooltip left>
<v-tooltip left v-if="dirty && valid">
<template v-slot:activator="{ on, attrs }">
<v-chip
v-if="dirty && valid"
v-bind="attrs"
v-on="on"
small
Expand All @@ -22,10 +21,9 @@
<span>{{ $t('app.version.tooltip.dirty') }}</span>
</v-tooltip>

<v-tooltip left>
<v-tooltip left v-if="!valid">
<template v-slot:activator="{ on, attrs }">
<v-chip
v-if="!valid"
v-bind="attrs"
v-on="on"
small
Expand All @@ -43,9 +41,22 @@
small
text
color="primary"
class="ml-1"
@click="$emit('on-update')">
{{ $t('app.version.btn.update') }}
</app-btn>

<app-btn
v-if="dirty || !valid"
small
text
color="error"
class="ml-1"
@click="$emit('on-recover')"
>
Recover
</app-btn>

</div>
</template>

Expand Down
16 changes: 15 additions & 1 deletion src/socketActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ export const SocketActions = {
)
},

async machineUpdateRecover (name: string, hard = false) {
let dispatch = 'version/onUpdatedClient'
if (name === 'moonraker') dispatch = 'version/onUpdatedMoonraker'
if (name === 'klipper') dispatch = 'version/onUpdatedKlipper'
baseEmit(
'machine.update.recover', {
dispatch,
params: { name, hard }
}
)
},

async machineUpdateMoonraker () {
baseEmit(
'machine.update.moonraker', {
Expand All @@ -77,9 +89,11 @@ export const SocketActions = {
},

async machineUpdateClient (name: string) {
let dispatch = 'version/onUpdatedClient'
if (name === 'fluidd') dispatch = 'version/onUpdatedFluidd'
baseEmit(
'machine.update.client', {
dispatch: 'version/onUpdatedClient',
dispatch,
params: { name }
}
)
Expand Down
8 changes: 7 additions & 1 deletion src/store/version/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const actions: ActionTree<VersionState, RootState> = {
async onUpdatedMoonraker ({ commit }, payload) {
consola.debug('Finished updating moonraker', payload)
SocketActions.machineUpdateStatus()
// We do this because moonraker is expected to restart.
commit('socket/setSocketDisconnecting', true, { root: true })
},

Expand All @@ -57,7 +58,12 @@ export const actions: ActionTree<VersionState, RootState> = {
},

async onUpdatedClient (_, payload) {
consola.debug('Finished updating client, reloading', payload)
consola.debug('Finished updating a client', payload)
SocketActions.machineUpdateStatus()
},

async onUpdatedFluidd (_, payload) {
consola.debug('Finished updating fluidd, reloading', payload)
window.location.reload()
},

Expand Down
37 changes: 19 additions & 18 deletions src/store/version/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,30 @@ import _Vue from 'vue'

export const getters: GetterTree<VersionState, RootState> = {
/**
* Returns the list of available components
* Returns an array list of available components
*/
getVisibleComponents: (state) => {
const c: Array<HashVersion | ArtifactVersion | OSPackage> = []
for (const key in state.components) {
const o = state.components[key]
c.push(o)
}
const o = Object.keys(state.version_info)
.map(k => {
const r = state.version_info[k]
r.key = k
return r
})

c.sort((a, b) => {
const name1 = a.type.toLowerCase()
const name2 = b.type.toLowerCase()
o.sort((a, b) => {
const name1 = a.key.toLowerCase()
const name2 = b.key.toLowerCase()
return (name1 < name2) ? -1 : (name1 > name2) ? 1 : 0
})
return c
return o
},

/**
* Returns an object indicating if any component (but system) has an update.
*/
hasUpdates: (state, getters) => {
let r = false
for (const key in state.components) {
for (const key in state.version_info) {
if (
!r ||
key !== 'system'
Expand All @@ -46,8 +47,8 @@ export const getters: GetterTree<VersionState, RootState> = {
* Returns a boolean indicating if a given component has an update.
*/
hasUpdate: (state) => (component: string): boolean => {
if (state.components[component] && isOfType<ArtifactVersion>(state.components[component], 'name')) {
const o = state.components[component] as ArtifactVersion
if (state.version_info[component] && isOfType<ArtifactVersion>(state.version_info[component], 'name')) {
const o = state.version_info[component] as ArtifactVersion
const version = valid(o.version)
const remoteVersion = valid(o.remote_version)
if (version && remoteVersion) {
Expand All @@ -56,12 +57,12 @@ export const getters: GetterTree<VersionState, RootState> = {
return false
}

if (state.components[component] && isOfType<OSPackage>(state.components[component], 'package_count')) {
const o = state.components[component] as OSPackage
if (state.version_info[component] && isOfType<OSPackage>(state.version_info[component], 'package_count')) {
const o = state.version_info[component] as OSPackage
return (o.package_count > 0)
}

const o = state.components[component] as HashVersion
const o = state.version_info[component] as HashVersion
return (o.current_hash !== o.remote_hash)
},

Expand All @@ -74,8 +75,8 @@ export const getters: GetterTree<VersionState, RootState> = {
*/
getCommitHistory: (state) => (component: string) => {
// This is only relevant for certain types.
if (state.components[component] && isOfType<HashVersion>(state.components[component], 'git_messages')) {
const c = state.components[component] as HashVersion
if (state.version_info[component] && isOfType<HashVersion>(state.version_info[component], 'git_messages')) {
const c = state.version_info[component] as HashVersion
const result = [...c.commits_behind]
.reduce((result: any, a) => {
const d = _Vue.$dayjs(+a.date * 1000).hour(6).minute(0).second(0).unix() * 1000
Expand Down
2 changes: 1 addition & 1 deletion src/store/version/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const defaultState = (): VersionState => {
github_rate_limit: 0,
github_requests_remaining: 0,
responses: [],
components: {},
version_info: {},
fluidd: {
version: '',
hash: ''
Expand Down
21 changes: 11 additions & 10 deletions src/store/version/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@ export const mutations: MutationTree<VersionState> = {
},

setUpdateStatus (state, payload) {
if ('busy' in payload) state.busy = payload.busy
if ('github_limit_reset_time' in payload) state.github_limit_reset_time = payload.github_limit_reset_time
if ('github_rate_limit' in payload) state.github_rate_limit = payload.github_rate_limit
if ('github_requests_remaining' in payload) state.github_requests_remaining = payload.github_requests_remaining
if (payload) {
if ('busy' in payload) state.busy = payload.busy
if ('github_limit_reset_time' in payload) state.github_limit_reset_time = payload.github_limit_reset_time
if ('github_rate_limit' in payload) state.github_rate_limit = payload.github_rate_limit
if ('github_requests_remaining' in payload) state.github_requests_remaining = payload.github_requests_remaining

const versionInfo = payload.version_info || undefined
if (versionInfo) {
for (const k in versionInfo) {
const type = k
Vue.set(state.components, k, { type, ...payload.version_info[k] })
}
const o = Object.assign(
{},
state.version_info,
payload.version_info
)
Vue.set(state, 'version_info', o)
}
},

Expand Down
Loading

0 comments on commit 39efb0d

Please sign in to comment.