-
-
Notifications
You must be signed in to change notification settings - Fork 582
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1562, fixes #1464 (#1743) * Add a delete command to delete projects, fixes #1562 * Add ddev delete images
- Loading branch information
Showing
3 changed files
with
198 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/drud/ddev/pkg/dockerutil" | ||
"github.com/drud/ddev/pkg/util" | ||
"github.com/drud/ddev/pkg/version" | ||
docker "github.com/fsouza/go-dockerclient" | ||
"github.com/spf13/cobra" | ||
"os" | ||
"strings" | ||
) | ||
|
||
// DeleteImagesCmd implements the ddev delete images command | ||
var DeleteImagesCmd = &cobra.Command{ | ||
Use: "images", | ||
Short: "Delete docker images not currently in use", | ||
Example: `ddev delete images`, | ||
Args: cobra.NoArgs, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
// This is were stuff goes | ||
if !util.Confirm("Deleting unused ddev images. \nThis is a non-destructive operation, \nbut it may require that the images be downloaded again when you need them. \nOK to continue?") { | ||
os.Exit(1) | ||
} | ||
util.Success("Powering off ddev to avoid conflicts") | ||
powerOff() | ||
|
||
client := dockerutil.GetDockerClient() | ||
|
||
images, err := client.ListImages(docker.ListImagesOptions{ | ||
All: true, | ||
}) | ||
if err != nil { | ||
util.Failed("Failed to list images: %v", err) | ||
} | ||
webimg := version.GetWebImage() | ||
dbimg101 := version.GetDBImage("10.1") | ||
dbimg102 := version.GetDBImage("10.2") | ||
dbaimage := version.GetDBAImage() | ||
routerimage := version.RouterImage + ":" + version.RouterTag | ||
sshimage := version.SSHAuthImage + ":" + version.SSHAuthTag | ||
|
||
// Too much code inside this loop, but complicated by multiple db images | ||
// and discrete names of images | ||
for _, image := range images { | ||
for _, tag := range image.RepoTags { | ||
// If a webimage, but doesn't match our webimage, delete it | ||
if strings.HasPrefix(tag, version.WebImg) && !strings.HasPrefix(tag, webimg) { | ||
if err = removeImage(client, tag); err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
} | ||
// If a dbimage, but doesn't match our dbimages, delete it | ||
if strings.HasPrefix(tag, version.DBImg) && !strings.HasPrefix(tag, dbimg101) && !strings.HasPrefix(tag, dbimg102) { | ||
if err = removeImage(client, tag); err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
} | ||
// If a dbaimage, but doesn't match our dbaimage, delete it | ||
if strings.HasPrefix(tag, version.DBAImg) && !strings.HasPrefix(tag, dbaimage) { | ||
if err = removeImage(client, tag); err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
} | ||
// If a routerImage, but doesn't match our routerimage, delete it | ||
if strings.HasPrefix(tag, version.RouterImage) && !strings.HasPrefix(tag, routerimage) { | ||
if err = removeImage(client, tag); err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
} | ||
// If a sshAgentImage, but doesn't match our sshAgentImage, delete it | ||
if strings.HasPrefix(tag, version.SSHAuthImage) && !strings.HasPrefix(tag, sshimage) { | ||
if err = removeImage(client, tag); err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
DeleteCmd.AddCommand(DeleteImagesCmd) | ||
} | ||
|
||
func removeImage(client *docker.Client, tag string) error { | ||
util.Warning("Removing container: %s", tag) | ||
err := client.RemoveImage(tag) | ||
if err != nil { | ||
util.Failed("Failed to remove %s: %v", tag, err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"github.com/drud/ddev/pkg/ddevapp" | ||
"github.com/drud/ddev/pkg/util" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// noConfirm: If true, --yes, we won't stop and prompt before each deletion | ||
var noConfirm bool | ||
|
||
// if deleteAll is true, we'll delete all projects | ||
var deleteAll bool | ||
|
||
// DeleteCmd provides the delete command | ||
var DeleteCmd = &cobra.Command{ | ||
Use: "delete [projectname ...]", | ||
Short: "Remove all project information (including database) for an existing project", | ||
Long: `Removes all ddev project information (including database) for an existing project, but does not touch the project codebase or the codebase's .ddev folder.'.`, | ||
Example: `ddev delete | ||
ddev delete proj1 proj2 proj3 | ||
ddev delete --omit-snapshot proj1 | ||
ddev delete --omit-snapshot --yes proj1 proj2 | ||
ddev delete --all`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if noConfirm && deleteAll { | ||
util.Failed("Sorry, it's not possible to use flags --all and --yes together") | ||
} | ||
projects, err := getRequestedProjects(args, deleteAll) | ||
if err != nil { | ||
util.Failed("Failed to get project(s): %v", err) | ||
} | ||
|
||
// Iterate through the list of projects built above, removing each one. | ||
for _, project := range projects { | ||
if !noConfirm { | ||
prompt := "OK to delete this project and its database?\n %s in %s\nThe code and its .ddev directory will not be touched.\n" | ||
if !omitSnapshot { | ||
prompt = prompt + "A database snapshot will be made before the database is deleted.\n" | ||
} | ||
if !util.Confirm(fmt.Sprintf(prompt+"OK to delete %s?", project.Name, project.AppRoot, project.Name)) { | ||
continue | ||
} | ||
} | ||
// Explanation of what's going on (including where the project is) | ||
// Stop it. | ||
// Delete database | ||
// Delete any other associated volumes | ||
|
||
// We do the snapshot UNLESS omit-snapshot is set; the project may have to be | ||
// started to do the snapshot. | ||
if project.SiteStatus() != ddevapp.SiteRunning && !omitSnapshot { | ||
util.Warning("project must be started to do the snapshot") | ||
err = project.Start() | ||
if err != nil { | ||
util.Failed("Failed to start project %s: %v", project.Name, err) | ||
} | ||
} | ||
if err := project.Stop(true, !omitSnapshot); err != nil { | ||
util.Failed("Failed to remove project %s: \n%v", project.GetName(), err) | ||
} | ||
|
||
util.Success("Project %s has been deleted.", project.GetName()) | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
DeleteCmd.Flags().Bool("clean-containers", true, "Clean up all ddev docker containers which are not required by this version of ddev") | ||
DeleteCmd.Flags().BoolVarP(&omitSnapshot, "omit-snapshot", "O", false, "Omit/skip database snapshot") | ||
DeleteCmd.Flags().BoolVarP(&noConfirm, "yes", "y", false, "Yes - skip confirmation prompt") | ||
DeleteCmd.Flags().BoolVarP(&deleteAll, "all", "a", false, "Delete all projects") | ||
|
||
RootCmd.AddCommand(DeleteCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters