feat: ✨ start / stop container fix #3
This commit is contained in:
parent
5988f8ad89
commit
d45299a983
@ -107,6 +107,7 @@ def get_containers(
|
|||||||
return [
|
return [
|
||||||
serialize_container(container)
|
serialize_container(container)
|
||||||
for container in client.containers.list(
|
for container in client.containers.list(
|
||||||
|
all=True,
|
||||||
filters={"label": ["engine=pilotwings"]}
|
filters={"label": ["engine=pilotwings"]}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -114,6 +115,7 @@ def get_containers(
|
|||||||
return [
|
return [
|
||||||
serialize_container(container)
|
serialize_container(container)
|
||||||
for container in client.containers.list(
|
for container in client.containers.list(
|
||||||
|
all=True,
|
||||||
filters={"label": ["engine=pilotwings", f"owner={credentials.username}"]},
|
filters={"label": ["engine=pilotwings", f"owner={credentials.username}"]},
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -187,6 +189,29 @@ def restart_container(
|
|||||||
) -> SerializedContainer:
|
) -> SerializedContainer:
|
||||||
container = select_container(container_name, credentials)
|
container = select_container(container_name, credentials)
|
||||||
container.restart()
|
container.restart()
|
||||||
|
container.reload()
|
||||||
|
return serialize_container(container)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/container/{container_name}/start")
|
||||||
|
def start_container(
|
||||||
|
container_name: str,
|
||||||
|
credentials: Annotated[HTTPBasicCredentials, Depends(security)],
|
||||||
|
) -> SerializedContainer:
|
||||||
|
container = select_container(container_name, credentials)
|
||||||
|
container.start()
|
||||||
|
container.reload()
|
||||||
|
return serialize_container(container)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/container/{container_name}/stop")
|
||||||
|
def stop_container(
|
||||||
|
container_name: str,
|
||||||
|
credentials: Annotated[HTTPBasicCredentials, Depends(security)],
|
||||||
|
) -> SerializedContainer:
|
||||||
|
container = select_container(container_name, credentials)
|
||||||
|
container.stop()
|
||||||
|
container.reload()
|
||||||
return serialize_container(container)
|
return serialize_container(container)
|
||||||
|
|
||||||
|
|
||||||
|
16
frontend/utils.ts
Normal file
16
frontend/utils.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export const get_status_icon = (
|
||||||
|
status: string,
|
||||||
|
): { name: string; type: string } => {
|
||||||
|
switch (status) {
|
||||||
|
case 'running':
|
||||||
|
return { name: 'play', type: 'success' }
|
||||||
|
case 'restarting':
|
||||||
|
return { name: 'refresh', type: 'danger' }
|
||||||
|
case 'paused':
|
||||||
|
return { name: 'pause', type: 'warning' }
|
||||||
|
case 'exited':
|
||||||
|
return { name: 'stop', type: 'danger' }
|
||||||
|
default:
|
||||||
|
return { name: 'question-circle', type: 'warning' }
|
||||||
|
}
|
||||||
|
}
|
@ -34,9 +34,27 @@
|
|||||||
>
|
>
|
||||||
{{ container?.status }}
|
{{ container?.status }}
|
||||||
</Icon>
|
</Icon>
|
||||||
<button class="button ml-2" @click="restart">
|
<button
|
||||||
|
v-if="container?.status == 'running'"
|
||||||
|
class="button ml-2"
|
||||||
|
@click="restart"
|
||||||
|
>
|
||||||
<Icon name="refresh">Restart</Icon>
|
<Icon name="refresh">Restart</Icon>
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="container?.status == 'running'"
|
||||||
|
class="button ml-2"
|
||||||
|
@click="stop"
|
||||||
|
>
|
||||||
|
<Icon name="stop">Stop</Icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="container?.status != 'running'"
|
||||||
|
class="button ml-2"
|
||||||
|
@click="start"
|
||||||
|
>
|
||||||
|
<Icon name="play">Start</Icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="block is-flex is-align-items-baseline">
|
<div class="block is-flex is-align-items-baseline">
|
||||||
<Icon name="image"><b>Logs:</b></Icon>
|
<Icon name="image"><b>Logs:</b></Icon>
|
||||||
@ -58,6 +76,7 @@ import axios, { AxiosError } from 'axios'
|
|||||||
import type { Container } from '../types'
|
import type { Container } from '../types'
|
||||||
import Icon from '../components/Icon.vue'
|
import Icon from '../components/Icon.vue'
|
||||||
import Loading from '../components/Loading.vue'
|
import Loading from '../components/Loading.vue'
|
||||||
|
import { get_status_icon } from '../utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Container',
|
name: 'Container',
|
||||||
@ -77,19 +96,7 @@ export default {
|
|||||||
return this.$route.params.name as string
|
return this.$route.params.name as string
|
||||||
},
|
},
|
||||||
status_icon(): { name: string; type: string } {
|
status_icon(): { name: string; type: string } {
|
||||||
if (!this.container) return { name: 'question-circle', type: 'warning' }
|
return get_status_icon(this.container?.status ?? 'unknown')
|
||||||
switch (this.container.status) {
|
|
||||||
case 'running':
|
|
||||||
return { name: 'play', type: 'success' }
|
|
||||||
case 'restarting':
|
|
||||||
return { name: 'refresh', type: 'danger' }
|
|
||||||
case 'paused':
|
|
||||||
return { name: 'pause', type: 'warning' }
|
|
||||||
case 'exited':
|
|
||||||
return { name: 'stop', type: 'danger' }
|
|
||||||
default:
|
|
||||||
return { name: 'question-circle', type: 'warning' }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -125,6 +132,12 @@ export default {
|
|||||||
async restart() {
|
async restart() {
|
||||||
this.request('post', `/api/container/${this.container_name}/restart`)
|
this.request('post', `/api/container/${this.container_name}/restart`)
|
||||||
},
|
},
|
||||||
|
async start() {
|
||||||
|
this.request('post', `/api/container/${this.container_name}/start`)
|
||||||
|
},
|
||||||
|
async stop() {
|
||||||
|
this.request('post', `/api/container/${this.container_name}/stop`)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -26,6 +26,7 @@ import axios, { AxiosError } from 'axios'
|
|||||||
import type { Container } from '../types'
|
import type { Container } from '../types'
|
||||||
import Icon from '../components/Icon.vue'
|
import Icon from '../components/Icon.vue'
|
||||||
import Loading from '../components/Loading.vue'
|
import Loading from '../components/Loading.vue'
|
||||||
|
import { get_status_icon } from '../utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
@ -54,18 +55,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
status_icon(container: Container): { name: string; type: string } {
|
status_icon(container: Container): { name: string; type: string } {
|
||||||
switch (container.status) {
|
return get_status_icon(container.status)
|
||||||
case 'running':
|
|
||||||
return { name: 'play', type: 'success' }
|
|
||||||
case 'restarting':
|
|
||||||
return { name: 'refresh', type: 'danger' }
|
|
||||||
case 'paused':
|
|
||||||
return { name: 'pause', type: 'warning' }
|
|
||||||
case 'exited':
|
|
||||||
return { name: 'stop', type: 'danger' }
|
|
||||||
default:
|
|
||||||
return { name: 'question-circle', type: 'warning' }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -676,9 +676,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/retry": {
|
"node_modules/@humanwhocodes/retry": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
|
||||||
"integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==",
|
"integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
Loading…
Reference in New Issue
Block a user