mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-12 17:46:20 +08:00
fix: Optimize container compose deletion logic
This commit is contained in:
parent
5c5904216b
commit
29952f48ca
5 changed files with 44 additions and 5 deletions
|
@ -260,6 +260,7 @@ type ComposeOperation struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
|
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
|
||||||
WithFile bool `json:"withFile"`
|
WithFile bool `json:"withFile"`
|
||||||
|
Force bool `josn:"force"`
|
||||||
}
|
}
|
||||||
type ComposeUpdate struct {
|
type ComposeUpdate struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
|
|
|
@ -227,12 +227,9 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
||||||
if cmd.CheckIllegal(req.Path, req.Operation) {
|
if cmd.CheckIllegal(req.Path, req.Operation) {
|
||||||
return buserr.New("ErrCmdIllegal")
|
return buserr.New("ErrCmdIllegal")
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(req.Path); err != nil {
|
|
||||||
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
|
||||||
}
|
|
||||||
if req.Operation == "delete" {
|
if req.Operation == "delete" {
|
||||||
if stdout, err := compose.Operate(req.Path, "down"); err != nil {
|
if err := removeContainerForCompose(req.Name, req.Path); err != nil && !req.Force {
|
||||||
return errors.New(string(stdout))
|
return err
|
||||||
}
|
}
|
||||||
if req.WithFile {
|
if req.WithFile {
|
||||||
_ = os.RemoveAll(path.Dir(req.Path))
|
_ = os.RemoveAll(path.Dir(req.Path))
|
||||||
|
@ -240,6 +237,9 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
||||||
_ = composeRepo.DeleteRecord(repo.WithByName(req.Name))
|
_ = composeRepo.DeleteRecord(repo.WithByName(req.Name))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(req.Path); err != nil {
|
||||||
|
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
||||||
|
}
|
||||||
if req.Operation == "up" {
|
if req.Operation == "up" {
|
||||||
if stdout, err := compose.Up(req.Path); err != nil {
|
if stdout, err := compose.Up(req.Path); err != nil {
|
||||||
return errors.New(string(stdout))
|
return errors.New(string(stdout))
|
||||||
|
@ -308,6 +308,33 @@ func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeContainerForCompose(composeName, composePath string) error {
|
||||||
|
if _, err := os.Stat(composePath); err == nil {
|
||||||
|
if stdout, err := compose.Operate(composePath, "down"); err != nil {
|
||||||
|
return errors.New(stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var options container.ListOptions
|
||||||
|
options.All = true
|
||||||
|
options.Filters = filters.NewArgs()
|
||||||
|
options.Filters.Add("label", "com.docker.compose.project="+composeName)
|
||||||
|
client, err := docker.NewDockerClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
ctx := context.Background()
|
||||||
|
containers, err := client.ContainerList(ctx, options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, c := range containers {
|
||||||
|
_ = client.ContainerRemove(ctx, c.ID, container.RemoveOptions{RemoveVolumes: true, Force: true})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func recreateCompose(content, path string) error {
|
func recreateCompose(content, path string) error {
|
||||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0640)
|
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0640)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -309,6 +309,7 @@ export namespace Container {
|
||||||
operation: string;
|
operation: string;
|
||||||
path: string;
|
path: string;
|
||||||
withFile: boolean;
|
withFile: boolean;
|
||||||
|
force: boolean;
|
||||||
}
|
}
|
||||||
export interface ComposeUpdate {
|
export interface ComposeUpdate {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
{{ $t('container.deleteComposeHelper') }}
|
{{ $t('container.deleteComposeHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-checkbox v-model="force" :label="$t('website.forceDelete')" />
|
||||||
|
<span class="input-help">
|
||||||
|
{{ $t('website.forceDeleteHelper') }}
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<div class="font">
|
<div class="font">
|
||||||
<span>{{ $t('database.delete') }}</span>
|
<span>{{ $t('database.delete') }}</span>
|
||||||
|
@ -40,6 +46,7 @@ let loading = ref(false);
|
||||||
let deleteInfo = ref('');
|
let deleteInfo = ref('');
|
||||||
|
|
||||||
const deleteFile = ref();
|
const deleteFile = ref();
|
||||||
|
const force = ref();
|
||||||
const composeName = ref();
|
const composeName = ref();
|
||||||
const composePath = ref();
|
const composePath = ref();
|
||||||
|
|
||||||
|
@ -53,6 +60,7 @@ const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
||||||
const acceptParams = async (prop: DialogProps) => {
|
const acceptParams = async (prop: DialogProps) => {
|
||||||
deleteFile.value = false;
|
deleteFile.value = false;
|
||||||
|
force.value = false;
|
||||||
composeName.value = prop.name;
|
composeName.value = prop.name;
|
||||||
composePath.value = prop.path;
|
composePath.value = prop.path;
|
||||||
deleteInfo.value = '';
|
deleteInfo.value = '';
|
||||||
|
@ -66,6 +74,7 @@ const submit = async () => {
|
||||||
path: composePath.value,
|
path: composePath.value,
|
||||||
operation: 'delete',
|
operation: 'delete',
|
||||||
withFile: deleteFile.value,
|
withFile: deleteFile.value,
|
||||||
|
force: force.value,
|
||||||
};
|
};
|
||||||
await composeOperator(params)
|
await composeOperator(params)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -203,6 +203,7 @@ const onComposeOperate = async (operation: string, row: any) => {
|
||||||
path: row.path,
|
path: row.path,
|
||||||
operation: operation,
|
operation: operation,
|
||||||
withFile: false,
|
withFile: false,
|
||||||
|
force: false,
|
||||||
};
|
};
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await composeOperator(params)
|
await composeOperator(params)
|
||||||
|
|
Loading…
Add table
Reference in a new issue