Documentation
¶
Overview ¶
You can use the "packr clean" command to clean up this, and any other packr generated files.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var AuthCmd = &cobra.Command{ Use: "auth [command]", Short: "A collection of authentication commands", Example: `ddev auth ssh ddev auth pantheon`, Run: func(cmd *cobra.Command, args []string) { err := cmd.Usage() util.CheckErr(err) }, }
AuthCmd is the top-level "ddev auth" command
var AuthSSHCommand = &cobra.Command{ Use: "ssh", Short: "Add ssh key authentication to the ddev-ssh-auth container", Long: `Use this command to provide the password to your ssh key to the ddev-ssh-agent container, where it can be used by other containers. Normal usage is just "ddev auth ssh", or if your key is not in ~/.ssh, ddev auth ssh --keydir=/some/path/.ssh"`, Example: `ddev auth ssh`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { util.Failed("This command takes no arguments.") } uidStr, _, username := util.GetContainerUIDGid() if sshKeyPath == "" { homeDir, err := homedir.Dir() if err != nil { util.Failed("Unable to determine home directory: %v", err) } sshKeyPath = filepath.Join(homeDir, ".ssh") } if !filepath.IsAbs(sshKeyPath) { sshKeyPath, err = filepath.Abs(sshKeyPath) if err != nil { util.Failed("Failed to derive absolute path for ssh key path %s: %v", sshKeyPath, err) } } fi, err := os.Stat(sshKeyPath) if os.IsNotExist(err) { util.Failed("The ssh key directory %s was not found", sshKeyPath) } if err != nil { util.Failed("Failed to check status of ssh key directory %s: %v", sshKeyPath, err) } if !fi.IsDir() { util.Failed("The ssh key directory (%s) must be a directory", sshKeyPath) } app := ddevapp.DdevApp{} err = app.EnsureSSHAgentContainer() if err != nil { util.Failed("Failed to start ddev-ssh-agent container: %v", err) } sshKeyPath = dockerutil.MassageWindowsHostMountpoint(sshKeyPath) dockerCmd := []string{"run", "-it", "--rm", "--volumes-from=" + ddevapp.SSHAuthName, "--user=" + uidStr, "--mount=type=bind,src=" + sshKeyPath + ",dst=/home/" + username + "/.ssh", version.SSHAuthImage + ":" + version.SSHAuthTag + "-built", "ssh-add"} err = exec.RunInteractiveCommand("docker", dockerCmd) if err != nil { util.Failed("Docker command 'docker %v' failed: %v", dockerCmd, err) } }, }
AuthSSHCommand implements the "ddev auth ssh" command
var ComposerCmd = &cobra.Command{ Use: "composer [command]", Short: "Executes a composer command within the web container", Long: `Executes a composer command at the project root in the web container. Generally, any composer command can be forwarded to the container context by prepending the command with 'ddev'.`, Example: `ddev composer install ddev composer require <package> ddev composer outdated --minor-only ddev composer create drupal/recommended-project`, Run: func(cmd *cobra.Command, args []string) { app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed(err.Error()) } if app.SiteStatus() != ddevapp.SiteRunning { if err = app.Start(); err != nil { util.Failed("Failed to start %s: %v", app.Name, err) } } stdout, stderr, err := app.Composer(args) if err != nil { util.Failed("composer %v failed, %v. stderr=%v", args, err, stderr) } _, _ = fmt.Fprint(os.Stderr, stderr) _, _ = fmt.Fprint(os.Stdout, stdout) }, }
var ComposerCreateCmd = &cobra.Command{ Use: "create [args] [flags]", FParseErrWhitelist: cobra.FParseErrWhitelist{ UnknownFlags: true, }, Short: "Executes 'composer create-project' within the web container with the arguments and flags provided", Long: `Directs basic invocations of 'composer create-project' within the context of the web container. Projects will be installed to a temporary directory and moved to the project root directory after installation. Any existing files in the project root will be deleted when creating a project.`, Example: `ddev composer create drupal/recommended-project ddev composer create "typo3/cms-base-distribution:^10" ddev composer create drupal/recommended-project --no-install ddev composer create --repository=https://repo.magento.com/ magento/project-community-edition`, Run: func(cmd *cobra.Command, args []string) { osargs := []string{} if len(os.Args) > 3 { osargs = os.Args[3:] } app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed(err.Error()) } if app.SiteStatus() != ddevapp.SiteRunning { err = app.Start() if err != nil { util.Failed("Failed to start app %s to run create-project: %v", app.Name, err) } } util.Warning("Warning: ALL EXISTING CONTENT of the project root (%s) will be deleted", app.AppRoot) if !util.Confirm("Would you like to continue?") { util.Failed("create-project cancelled") } util.Warning("Removing any existing files in project root") objs, err := fileutil.ListFilesInDir(app.AppRoot) if err != nil { util.Failed("Failed to create project: %v", err) } for _, o := range objs { if o == ".ddev" { continue } if err = os.RemoveAll(filepath.Join(app.AppRoot, o)); err != nil { util.Failed("Failed to create project: %v", err) } } tmpDir := fmt.Sprintf(".tmp_ddev_composer_create_%s", util.RandString(6)) containerInstallPath := path.Join("/var/www/html", tmpDir) hostInstallPath := filepath.Join(app.AppRoot, tmpDir) composerCmd := []string{ "composer", "create-project", } composerCmd = append(composerCmd, osargs...) composerCmd = append(composerCmd, containerInstallPath) composerCmdString := strings.TrimSpace(strings.Join(composerCmd, " ")) output.UserOut.Printf("Executing composer command: %s\n", composerCmdString) stdout, stderr, err := app.Exec(&ddevapp.ExecOpts{ Service: "web", Cmd: composerCmdString, Dir: "/var/www/html", Tty: isatty.IsTerminal(os.Stdin.Fd()), }) if err != nil { util.Failed("Failed to create project:%v, stderr=%v", err, stderr) } if len(stdout) > 0 { fmt.Println(strings.TrimSpace(stdout)) } output.UserOut.Printf("Moving installation to project root") if runtime.GOOS == "windows" && !(app.NFSMountEnabled || app.NFSMountEnabledGlobal) { err = filepath.Walk(hostInstallPath, func(path string, info os.FileInfo, err error) error { if path == hostInstallPath { return nil } elements := strings.Split(path, tmpDir) newPath := filepath.Join(elements...) if info.IsDir() { if err := os.MkdirAll(newPath, info.Mode()); err != nil { return fmt.Errorf("unable to move %s to %s: %v", path, newPath, err) } return nil } if err := os.Rename(path, newPath); err != nil { return fmt.Errorf("unable to move %s to %s: %v", path, newPath, err) } return nil }) } else { _, _, err = app.Exec(&ddevapp.ExecOpts{ Service: "web", Cmd: fmt.Sprintf("shopt -s dotglob && mv %s/* /var/www/html && rmdir %s", containerInstallPath, containerInstallPath), Dir: "/var/www/html", }) } if err != nil { util.Failed("Failed to create project: %v", err) } if runtime.GOOS == "windows" && !nodeps.IsDockerToolbox() { fileutil.ReplaceSimulatedLinks(app.AppRoot) } err = app.Start() if err != nil { util.Failed("Failed to start project after composer create: %v", err) } }, }
var ComposerCreateProjectCmd = &cobra.Command{ Use: "create-project", Run: func(cmd *cobra.Command, args []string) { util.Failed(`'ddev composer create-project' is unsupported. Please use 'ddev composer create' for basic project creation or 'ddev ssh' into the web container and execute 'composer create-project' directly.`) }, }
var ConfigCommand *cobra.Command = &cobra.Command{ Use: "config [provider or 'global']", Short: "Create or modify a ddev project configuration in the current directory", Example: `"ddev config" or "ddev config --docroot=web --project-type=drupal8"`, Args: cobra.ExactArgs(0), Run: handleConfigRun, }
ConfigCommand represents the `ddev config` command
var DdevExecCmd = &cobra.Command{ Use: "exec <command>", Aliases: []string{"."}, Short: "Execute a shell command in the container for a service. Uses the web service by default.", Long: `Execute a shell command in the container for a service. Uses the web service by default. To run your command in the container for another service, run "ddev exec --service <service> <cmd>"`, Example: "ddev exec ls /var/www/html\nddev exec --service db\nddev exec -s db\nddev exec -s solr (assuming an add-on service named 'solr')", Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { err := cmd.Usage() util.CheckErr(err) os.Exit(1) } app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed("Failed to exec command: %v", err) } if strings.Contains(app.SiteStatus(), ddevapp.SiteStopped) { util.Failed("Project is not currently running. Try 'ddev start'.") } if strings.Contains(app.SiteStatus(), ddevapp.SitePaused) { util.Failed("Project is paused. Run 'ddev start' to start it.") } app.DockerEnv() out, _, err := app.Exec(&ddevapp.ExecOpts{ Service: serviceType, Dir: execDirArg, Cmd: strings.Join(args, " "), Tty: true, }) if err != nil { util.Failed("Failed to execute command %s: %v", strings.Join(args, " "), err) } output.UserOut.Print(out) }, }
DdevExecCmd allows users to execute arbitrary sh commands within a container.
var DdevLiveAuthCommand = &cobra.Command{ Use: "ddev-live [token]", Short: "Provide a machine token for the global ddev-live auth", Long: "Configure token for ddev-live authentication. See https://dash.ddev.com/settings/integration to retrieve your token.", Example: `ddev auth ddev-live [token] ddev auth ddev-live --default-org=some-ddevlive-org [token]`, Run: func(cmd *cobra.Command, args []string) { if len(args) != 1 { util.Failed("You must provide a DDEV API Token, e.g. 'ddev auth ddev-live [token]'. See https://dash.ddev.com/settings/integration to retrieve your your token.") } uid, _, _ := util.GetContainerUIDGid() c := fmt.Sprintf(`ddev-live auth --token="%s"`, args[0]) if cmd.Flag("default-org").Changed { c = fmt.Sprintf(`ddev-live auth --default-org="%s" --token="%s"`, cmd.Flag("default-org").Value.String(), args[0]) } _, out, err := dockerutil.RunSimpleContainer(version.GetWebImage(), "", []string{"bash", "-c", c}, nil, []string{"HOME=/tmp", "DDEV_LIVE_NO_ANALYTICS=" + os.Getenv("DDEV_LIVE_NO_ANALYTICS")}, []string{"ddev-global-cache:/mnt/ddev-global-cache"}, uid, true) if err == nil { util.Success("Authentication successful!\nYou may now use the 'ddev config ddev-live' command when configuring projects.") } else { util.Failed("Failed to authenticate: %v (%v) command=%v", err, out, c) } }, }
DdevLiveAuthCommand is the `ddev auth ddev-live` command
var DdevLogsCmd = &cobra.Command{ Use: "logs", Short: "Get the logs from your running services.", Long: `Uses 'docker logs' to display stdout from the running services.`, Example: `ddev logs ddev logs -f ddev logs -s db`, Run: func(cmd *cobra.Command, args []string) { app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed("Failed to retrieve logs: %v", err) } if strings.Contains(app.SiteStatus(), ddevapp.SiteStopped) { util.Failed("Project is not currently running. Try 'ddev start'.") } err = app.Logs(serviceType, follow, timestamp, tail) if err != nil { util.Failed("Failed to retrieve logs for %s: %v", app.GetName(), err) } }, }
DdevLogsCmd contains the "ddev logs" command
var DdevPauseCommand = &cobra.Command{ Use: "pause [projectname ...]", Short: "uses 'docker stop' to pause/stop the containers belonging to a project.", Long: `Uses "docker-compose stop" to pause/stop the containers belonging to a project. This leaves the containers instantiated instead of removing them like ddev stop does. You can run 'ddev pause' from a project directory to stop the containers of that project, or you can stop running projects in any directory by running 'ddev pause projectname [projectname ...]' or pause all with 'ddev pause --all'`, Aliases: []string{"sc", "stop-containers"}, Run: func(cmd *cobra.Command, args []string) { projects, err := getRequestedProjects(args, pauseAllProjects) if err != nil { util.Failed("Unable to get project(s): %v", err) } for _, project := range projects { if err := ddevapp.CheckForMissingProjectFiles(project); err != nil { util.Failed("Failed to pause/stop-containers %s: %v", project.GetName(), err) } if err := project.Pause(); err != nil { util.Failed("Failed to pause/stop-containers %s: %v", project.GetName(), err) } util.Success("Project %s has been paused.", project.GetName()) } }, }
DdevPauseCommand represents the stop command
var DdevRestoreSnapshotCommand = &cobra.Command{ Use: "restore-snapshot [snapshot_name]", Short: "Restore a project's database to the provided snapshot version.", Long: `Uses mariabackup command to restore a project database to a particular snapshot from the .ddev/db_snapshots folder. Example: "ddev restore-snapshot d8git_20180717203845"`, Run: func(cmd *cobra.Command, args []string) { if len(args) != 1 { util.Warning("Please provide the name of the snapshot you want to restore." + "\nThe available snapshots are in .ddev/db_snapshots.") _ = cmd.Usage() os.Exit(1) } snapshotName := args[0] app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed("Failed to find active project: %v", err) } if err := app.RestoreSnapshot(snapshotName); err != nil { util.Failed("Failed to restore snapshot %s for project %s: %v", snapshotName, app.GetName(), err) } }, }
DdevRestoreSnapshotCommand provides the ability to revert to a database snapshot
var DdevSSHCmd = &cobra.Command{ Use: "ssh [projectname]", Short: "Starts a shell session in the container for a service. Uses web service by default.", Long: `Starts a shell session in the container for a service. Uses web service by default. To start a shell session for another service, run "ddev ssh --service <service>`, Example: `ddev ssh ddev ssh -s sb ddev ssh <projectname> ddev ssh -d /var/www/html`, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { projects, err := getRequestedProjects(args, false) if err != nil { util.Failed("Failed to ddev ssh: %v", err) } app := projects[0] if strings.Contains(app.SiteStatus(), ddevapp.SiteStopped) { util.Failed("Project is not currently running. Try 'ddev start'.") } if strings.Contains(app.SiteStatus(), ddevapp.SitePaused) { util.Failed("Project is stopped. Run 'ddev start' to start the environment.") } app.DockerEnv() shell := "bash" if !nodeps.ArrayContainsString([]string{"web", "db", "dba", "solr"}, serviceType) { shell = "sh" } _ = app.ExecWithTty(&ddevapp.ExecOpts{ Service: serviceType, Cmd: shell + " -l", Dir: sshDirArg, }) }, }
DdevSSHCmd represents the ssh command.
var DdevSequelproCmd = &cobra.Command{ Use: "sequelpro", Short: "Connect sequelpro to a project database", Long: `A helper command for using sequelpro (macOS database browser) with a running DDEV-Local project's database'.`, Example: `ddev sequelpro`, Run: func(cmd *cobra.Command, args []string) { if len(args) != 0 { output.UserOut.Fatalf("invalid arguments to sequelpro command: %v", args) } out, err := handleSequelProCommand(SequelproLoc) if err != nil { output.UserOut.Fatalf("Could not run sequelpro command: %s", err) } util.Success(out) }, }
DdevSequelproCmd represents the sequelpro command
Use: "share [project]", Short: "Share project on the internet via ngrok.", Long: `Use "ddev share" or add on extra ngrok commands, like "ddev share --subdomain some-subdomain". Although a few ngrok commands are supported directly, any ngrok flag can be added in the ngrok_args section of .ddev/config.yaml. You will want to create an account on ngrok.com and use the "ngrok authtoken" command to set up ngrok.`, Example: `ddev share ddev share --subdomain some-subdomain ddev share --use-http ddev share myproject`, Run: func(cmd *cobra.Command, args []string) { if len(args) > 1 { util.Failed("Too many arguments provided. Please use 'ddev share' or 'ddev share [projectname]'") } apps, err := getRequestedProjects(args, false) if err != nil { util.Failed("Failed to describe project(s): %v", err) } app := apps[0] if app.SiteStatus() != ddevapp.SiteRunning { util.Failed("Project is not yet running. Use 'ddev start' first.") } ngrokLoc, err := exec.LookPath("ngrok") if ngrokLoc == "" || err != nil { util.Failed("ngrok not found in path, please install it, see https://ngrok.com/download") } urls := []string{app.GetWebContainerDirectHTTPSURL(), app.GetWebContainerDirectHTTPURL()} useHTTP, err := cmd.Flags().GetBool("use-http") if err != nil { util.Failed("failed to get use-http flag: %v", err) } if useHTTP { urls = []string{app.GetWebContainerDirectHTTPURL()} } var ngrokErr error for _, url := range urls { ngrokArgs := []string{"http"} ngrokArgs = append(ngrokArgs, url) if app.NgrokArgs != "" { ngrokArgs = append(ngrokArgs, strings.Split(app.NgrokArgs, " ")...) } if cmd.Flags().Changed("subdomain") { sub, err := cmd.Flags().GetString("subdomain") if err != nil { util.Failed("unable to get --subdomain flag: %v", err) } ngrokArgs = append(ngrokArgs, "-subdomain="+sub) } if strings.Contains(url, "http://") { util.Warning("Using local http URL, your data may be exposed on the internet. Create a free ngrok account instead...") time.Sleep(time.Second * 3) } util.Success("Running %s %s", ngrokLoc, strings.Join(ngrokArgs, " ")) ngrokCmd := exec.Command(ngrokLoc, ngrokArgs...) ngrokCmd.Stdout = os.Stdout ngrokCmd.Stderr = os.Stderr ngrokErr = ngrokCmd.Run() if ngrokErr == nil { break } exitErr, ok := ngrokErr.(*exec.ExitError) if !ok { util.Error("ngrok exited: %v", ngrokErr) break } exitCode := exitErr.ExitCode() if exitCode != 1 { util.Error("ngrok exited: %v", exitErr) break } } os.Exit(0) }, }
DdevShareCommand contains the "ddev share" command
var DdevSnapshotCommand = &cobra.Command{ Use: "snapshot [projectname projectname...]", Short: "Create a database snapshot for one or more projects.", Long: `Uses mariabackup or xtrabackup command to create a database snapshot in the .ddev/db_snapshots folder. These are compatible with server backups using the same tools and can be restored with "ddev restore-snapshot".`, Example: `ddev snapshot ddev snapshot --name some_descriptive_name ddev snapshot --all`, Run: func(cmd *cobra.Command, args []string) { apps, err := getRequestedProjects(args, snapshotAll) if err != nil { util.Failed("Unable to get project(s) %v: %v", args, err) } for _, app := range apps { if snapshotNameOutput, err := app.Snapshot(snapshotName); err != nil { util.Failed("Failed to snapshot %s: %v", app.GetName(), err) } else { util.Success("Created snapshot %s", snapshotNameOutput) } } }, }
DdevSnapshotCommand provides the snapshot command
var DdevStopCmd = &cobra.Command{ Use: "stop [projectname ...]", Aliases: []string{"rm", "remove"}, Short: "Stop and remove the containers of a project. Does not lose or harm anything unless you add --remove-data.", Long: `Stop and remove the containers of a project. You can run 'ddev stop' from a project directory to stop/remove that project, or you can stop/remove projects in any directory by running 'ddev stop projectname [projectname ...]' or 'ddev stop -a'. By default, stop is a non-destructive operation and will leave database contents intact. It never touches your code or files directories. To remove database contents and global listing, use "ddev delete" or "ddev stop --remove-data". To snapshot the database on stop, use "ddev stop --snapshot"; A snapshot is automatically created on "ddev stop --remove-data" unless you use "ddev stop --remove-data --omit-snapshot". `, Example: `ddev stop ddev stop proj1 proj2 proj3 ddev stop --all ddev stop --all --stop-ssh-agent ddev stop --remove-data`, Run: func(cmd *cobra.Command, args []string) { if createSnapshot && omitSnapshot { util.Failed("Illegal option combination: --snapshot and --omit-snapshot:") } projects, err := getRequestedProjects(args, stopAll) if err != nil { util.Failed("Failed to get project(s): %v", err) } for _, project := range projects { if project.SiteStatus() == ddevapp.SiteStopped { util.Success("Project %s is already stopped.", project.GetName()) } doSnapshot := (createSnapshot || removeData) && !omitSnapshot if err := project.Stop(removeData, doSnapshot); err != nil { util.Failed("Failed to stop project %s: \n%v", project.GetName(), err) } if unlist { project.RemoveGlobalProjectInfo() } util.Success("Project %s has been stopped.", project.GetName()) } if stopSSHAgent { if err := ddevapp.RemoveSSHAgentContainer(); err != nil { util.Error("Failed to remove ddev-ssh-agent: %v", err) } } }, }
DdevStopCmd represents the remove command
var DebugCmd = &cobra.Command{ Use: "debug [command]", Short: "A collection of debugging commands", Run: func(cmd *cobra.Command, args []string) { err := cmd.Usage() util.CheckErr(err) }, }
DebugCmd is the top-level "ddev debug" command
var DebugComposeConfigCmd = &cobra.Command{ Use: "compose-config [project]", Short: "Prints the docker-compose configuration of the current project", Run: func(cmd *cobra.Command, args []string) { projectName := "" if len(args) > 1 { util.Failed("This command only takes one optional argument: project name") } if len(args) == 1 { projectName = args[0] } app, err := ddevapp.GetActiveApp(projectName) if err != nil { util.Failed("Failed to get compose-config: %v", err) } app.DockerEnv() if err = app.WriteDockerComposeYAML(); err != nil { util.Failed("Failed to get compose-config: %v", err) } out, err := fileutil.ReadFileIntoString(app.DockerComposeFullRenderedYAMLPath()) if err != nil { util.Failed("unable to read rendered file %s: %v", app.DockerComposeFullRenderedYAMLPath(), err) } output.UserOut.Print(strings.TrimSpace(out)) }, }
DebugComposeConfigCmd implements the ddev debug compose-config command
var DebugConfigYamlCmd = &cobra.Command{ Use: "configyaml [project]", Short: "Prints the project config.*.yaml usage", Example: "ddev debug configyaml, ddev debug configyaml <projectname>", Run: func(cmd *cobra.Command, args []string) { projectName := "" if len(args) > 1 { util.Failed("This command only takes one optional argument: project-name") } if len(args) == 1 { projectName = args[0] } app, err := ddevapp.GetActiveApp(projectName) if err != nil { util.Failed("Failed to get active project: %v", err) } configFiles, err := app.ReadConfig(true) if err != nil { util.Error("failed reading config for project %s: %v", app.Name, err) } output.UserOut.Printf("These config files were loaded for project %s: %v", app.Name, configFiles) fields := reflect.TypeOf(*app) values := reflect.ValueOf(*app) num := fields.NumField() for i := 0; i < num; i++ { field := fields.Field(i) v := values.Field(i) yaml := field.Tag.Get("yaml") key := strings.Split(yaml, ",") if v.CanInterface() && key[0] != "-" && !isZero(v) { output.UserOut.Printf("%s: %v", key[0], v) } } }, }
DebugConfigYamlCmd implements the ddev debug configyaml command
var DebugNFSMountCmd = &cobra.Command{ Use: "nfsmount", Short: "Checks to see if nfs mounting works for current project", Example: "ddev debug nfsmount", Run: func(cmd *cobra.Command, args []string) { testVolume := "testnfsmount" containerName := "testnfscontainer" if len(args) != 0 { util.Failed("This command takes no additional arguments") } app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed("Failed to debug nfsmount: %v", err) } oldContainer, err := dockerutil.FindContainerByName(containerName) if err == nil && oldContainer != nil { err = dockerutil.RemoveContainer(oldContainer.ID, 20) if err != nil { util.Failed("Failed to remove existing test container %s: %v", containerName, err) } } dockerutil.RemoveVolume(testVolume) hostDockerInternal, err := dockerutil.GetHostDockerInternalIP() if err != nil { util.Failed("failed to GetHostDockerInternalIP(): %v", err) } if hostDockerInternal == "" { hostDockerInternal = "host.docker.internal" } shareDir := app.AppRoot if runtime.GOOS == "darwin" && fileutil.IsDirectory(filepath.Join("/System/Volumes/Data", app.AppRoot)) { shareDir = filepath.Join("/System/Volumes/Data", app.AppRoot) } volume, err := dockerutil.CreateVolume(testVolume, "local", map[string]string{"type": "nfs", "o": fmt.Sprintf("addr=%s,hard,nolock,rw", hostDockerInternal), "device": ":" + dockerutil.MassageWindowsNFSMount(shareDir)}) defer dockerutil.RemoveVolume(testVolume) if err != nil { util.Failed("Failed to create volume %s: %v", testVolume, err) } _ = volume uidStr, _, _ := util.GetContainerUIDGid() _, out, err := dockerutil.RunSimpleContainer(version.GetWebImage(), containerName, []string{"sh", "-c", "findmnt -T /nfsmount && ls -d /nfsmount/.ddev"}, []string{}, []string{}, []string{"testnfsmount" + ":/nfsmount"}, uidStr, true) if err != nil { util.Warning("NFS does not seem to be set up yet, see debugging instructions at https://ddev.readthedocs.io/en/stable/users/performance/#debugging-ddev-start-failures-with-nfs_mount_enabled-true") util.Failed("Details: error=%v\noutput=%v", err, out) } output.UserOut.Printf(strings.TrimSpace(out)) util.Success("") util.Success("Successfully accessed NFS mount of %s", app.AppRoot) switch { case app.NFSMountEnabledGlobal: util.Success("nfs_mount_enabled is set globally") case app.NFSMountEnabled: util.Success("nfs_mount_enabled is true in this project (%s), but is not set globally", app.Name) default: util.Warning("nfs_mount_enabled is not set either globally or in this project. \nUse `ddev config global --nfs-mount-enabled` to enable it.") } }, }
DebugNFSMountCmd implements the ddev debug nfsmount 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 -Oy 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) } 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 } } 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) } } }, }
DeleteCmd provides the delete 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) { 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) } sort.Slice(images, func(i, j int) bool { if images[i].RepoTags == nil || images[j].RepoTags == nil { return false } return images[i].RepoTags[0] > images[j].RepoTags[0] }) webimg := version.GetWebImage() dbaimage := version.GetDBAImage() routerimage := version.RouterImage + ":" + version.RouterTag sshimage := version.SSHAuthImage + ":" + version.SSHAuthTag nameAry := strings.Split(version.GetDBImage(nodeps.MariaDB), ":") keepDBImageTag := "notagfound" if len(nameAry) > 1 { keepDBImageTag = nameAry[1] } for _, image := range images { for _, tag := range image.RepoTags { if strings.HasPrefix(tag, version.WebImg) && !strings.HasPrefix(tag, webimg) && !strings.HasPrefix(tag, webimg+"-built") { if err = dockerutil.RemoveImage(tag); err != nil { util.Warning("Failed to remove %s: %v", tag, err) } } if strings.HasPrefix(tag, "drud/ddev-dbserver") && !strings.HasSuffix(tag, keepDBImageTag) && !strings.HasSuffix(tag, keepDBImageTag+"-built") { if err = dockerutil.RemoveImage(tag); err != nil { util.Warning("Unable to remove %s: %v", tag, err) } } if strings.HasPrefix(tag, version.DBAImg) && !strings.HasPrefix(tag, dbaimage) { if err = dockerutil.RemoveImage(tag); err != nil { util.Warning("Failed to remove %s: %v", tag, err) } } if strings.HasPrefix(tag, version.RouterImage) && !strings.HasPrefix(tag, routerimage) { if err = dockerutil.RemoveImage(tag); err != nil { util.Warning("Failed to remove %s: %v", tag, err) } } if strings.HasPrefix(tag, version.SSHAuthImage) && !strings.HasPrefix(tag, sshimage) && !strings.HasPrefix(tag, sshimage+"-built") { if err = dockerutil.RemoveImage(tag); err != nil { util.Warning("Failed to remove %s: %v", tag, err) } } } } util.Success("Any non-current images discovered were deleted.") }, }
DeleteImagesCmd implements the ddev delete images command
var DescribeCommand = &cobra.Command{ Use: "describe [projectname]", Short: "Get a detailed description of a running ddev project.", Long: `Get a detailed description of a running ddev project. Describe provides basic information about a ddev project, including its name, location, url, and status. It also provides details for MySQL connections, and connection information for additional services like MailHog and phpMyAdmin. You can run 'ddev describe' from a project directory to describe that project, or you can specify a project to describe by running 'ddev describe <projectname>.`, Example: "ddev describe\nddev describe <projectname>", Run: func(cmd *cobra.Command, args []string) { if len(args) > 1 { util.Failed("Too many arguments provided. Please use 'ddev describe' or 'ddev describe [projectname]'") } projects, err := getRequestedProjects(args, false) if err != nil { util.Failed("Failed to describe project(s): %v", err) } project := projects[0] if err := ddevapp.CheckForMissingProjectFiles(project); err != nil { util.Failed("Failed to describe %s: %v", project.Name, err) } desc, err := project.Describe() if err != nil { util.Failed("Failed to describe project %s: %v", project.Name, err) } renderedDesc, err := renderAppDescribe(desc) util.CheckErr(err) output.UserOut.WithField("raw", desc).Print(renderedDesc) }, }
DescribeCommand represents the `ddev config` command
var ExportDBCmd = &cobra.Command{ Use: "export-db [project]", Short: "Dump a database to a file or to stdout", Long: `Dump a database to a file or to stdout`, Example: `ddev export-db --file=/tmp/db.sql.gz' ddev export-db -f /tmp/db.sql.gz ddev export-db --gzip=false --file /tmp/db.sql ddev export-db > /tmp/db.sql.gz ddev export-db --gzip=false > /tmp/db.sql ddev export-db myproject --gzip=false --file=/tmp/myproject.sql ddev export-db someproject --gzip=false --file=/tmp/someproject.sql `, Args: cobra.RangeArgs(0, 1), PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Run: func(cmd *cobra.Command, args []string) { projects, err := getRequestedProjects(args, false) if err != nil { util.Failed("Unable to get project(s): %v", err) } app := projects[0] if app.SiteStatus() != ddevapp.SiteRunning { util.Failed("ddev can't export-db until the project is started, please use ddev start.") } err = app.ExportDB(outFileName, gzipOption, exportTargetDB) if err != nil { util.Failed("Failed to export database for %s: %v", app.GetName(), err) } }, }
ExportDBCmd is the `ddev export-db` command.
var HostNameCmd = &cobra.Command{ Use: "hostname [hostname] [ip]", Example: "ddev hostname somesite.ddev.local 127.0.0.1", Short: "Manage your hostfile entries.", Long: `Manage your hostfile entries. Managing host names has security and usability implications and requires elevated privileges. You may be asked for a password to allow ddev to modify your hosts file. If you are connected to the internet and using the domain ddev.site this is generally not necessary, becauses the hosts file never gets manipulated.`, Run: func(cmd *cobra.Command, args []string) { hosts, err := goodhosts.NewHosts() if err != nil { rawResult := make(map[string]interface{}) detail := fmt.Sprintf("Could not open hosts file for reading: %v", err) rawResult["error"] = "READERROR" rawResult["full_error"] = detail output.UserOut.WithField("raw", rawResult).Fatal(detail) return } if err := hosts.Flush(); err != nil { rawResult := make(map[string]interface{}) detail := fmt.Sprintf("Please use sudo or execute with administrative privileges: %v", err) rawResult["error"] = "WRITEERROR" rawResult["full_error"] = detail output.UserOut.WithField("raw", rawResult).Fatal(detail) return } if removeInactive { if len(args) > 0 { output.UserOut.Fatal("Invalid arguments supplied. 'ddev hostname --remove-all' accepts no arguments.") } util.Warning("Attempting to remove inactive hostnames which use TLD %s", nodeps.DdevDefaultTLD) removeInactiveHostnames(hosts) return } if len(args) != 2 { output.UserOut.Fatal("Invalid arguments supplied. Please use 'ddev hostname [hostname] [ip]'") } hostname, ip := args[0], args[1] if removeHostName { removeHostname(hosts, ip, hostname) return } addHostname(hosts, ip, hostname) }, }
HostNameCmd represents the hostname command
var ImportDBCmd = &cobra.Command{ Use: "import-db [project]", Args: cobra.RangeArgs(0, 1), Short: "Import a sql file into the project.", Long: `Import a sql file into the project. The database dump file can be provided as a SQL dump in a .sql, .sql.gz, .mysql, .mysql.gz, .zip, .tgz, or .tar.gz format. For the zip and tar formats, the path to a .sql file within the archive can be provided if it is not located at the top level of the archive. An optional target database can also be provided; the default is the default database named "db". Also note the related "ddev mysql" command`, Example: `ddev import-db ddev import-db --src=.tarballs/junk.sql ddev import-db --src=.tarballs/junk.sql.gz ddev import-db --target-db=newdb --src=.tarballs/junk.sql.gz ddev import-db <db.sql ddev import-db someproject <db.sql gzip -dc db.sql.gz | ddev import-db`, PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Run: func(cmd *cobra.Command, args []string) { projects, err := getRequestedProjects(args, false) if err != nil { util.Failed("Unable to get project(s): %v", err) } app := projects[0] if app.SiteStatus() != ddevapp.SiteRunning { err = app.Start() if err != nil { util.Failed("Failed to start app %s to import-db: %v", app.Name, err) } } err = app.ImportDB(dbSource, dbExtPath, progressOption, noDrop, targetDB) if err != nil { util.Failed("Failed to import database %s for %s: %v", targetDB, app.GetName(), err) } util.Success("Successfully imported database '%s' for %v", targetDB, app.GetName()) if noDrop { util.Success("Existing database '%s' was NOT dropped before importing", targetDB) } else { util.Success("Existing database '%s' was dropped before importing", targetDB) } }, }
ImportDBCmd represents the `ddev import-db` command.
var ImportFileCmd = &cobra.Command{ Use: "import-files", Example: `ddev import-files --src=/path/to/files.tar.gz`, Short: "Pull the uploaded files directory of an existing project to the default public upload directory of your project.", Long: `Pull the uploaded files directory of an existing project to the default public upload directory of your project. The files can be provided as a directory path or an archive in .tar, .tar.gz, .tgz, or .zip format. For the .zip and tar formats, the path to a directory within the archive can be provided if it is not located at the top-level of the archive. If the destination directory exists, it will be replaced with the assets being imported. The destination directory can be configured in your project's config.yaml under the upload_dir key. If no custom upload directory is defined, the app type's default upload directory will be used.`, PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { app, err := ddevapp.GetActiveApp("") if err != nil { util.Failed("Failed to import files: %v", err) } var showExtPathPrompt bool if sourcePath == "" { if extPath == "" { showExtPathPrompt = true } promptForFileSource(&sourcePath) } importPath, isArchive, err := appimport.ValidateAsset(sourcePath, "files") if err != nil { util.Failed("Failed to import files for %s: %v", app.GetName(), err) } if isArchive && showExtPathPrompt { promptForExtPath(&extPath) } if err = app.ImportFiles(importPath, extPath); err != nil { util.Failed("Failed to import files for %s: %v", app.GetName(), err) } util.Success("Successfully imported files for %v", app.GetName()) }, }
ImportFileCmd represents the `ddev import-db` command.
var ListCmd = &cobra.Command{ Use: "list", Short: "List projects", Long: `List projects. Shows all projects by default, shows active projects only with --active-only`, Example: `ddev list ddev list --active-only ddev list -A`, Run: func(cmd *cobra.Command, args []string) { for { apps, err := ddevapp.GetProjects(activeOnly) if err != nil { util.Failed("failed getting GetProjects: %v", err) } appDescs := make([]map[string]interface{}, 0) if len(apps) < 1 { output.UserOut.WithField("raw", appDescs).Println("No ddev projects were found.") } else { table := ddevapp.CreateAppTable() for _, app := range apps { desc, err := app.Describe() if err != nil { util.Error("Failed to describe project %s: %v", app.GetName(), err) } appDescs = append(appDescs, desc) ddevapp.RenderAppRow(table, desc) } output.UserOut.WithField("raw", appDescs).Print(table.String() + "\n" + ddevapp.RenderRouterStatus()) } if !continuous { break } time.Sleep(time.Duration(continuousSleepTime) * time.Second) } }, }
ListCmd represents the list command
var PantheonAuthCommand = &cobra.Command{ Use: "pantheon [token]", Short: "Provide a machine token for the global pantheon auth", Long: "Configure global machine token for pantheon authentication. See https://pantheon.io/docs/machine-tokens/ for instructions on creating a token.", Example: `ddev auth pantheon`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { util.Failed("You must provide a Pantheon machine token, e.g. 'ddev auth pantheon [token]'. See https://pantheon.io/docs/machine-tokens/ for instructions on creating a token.") } if len(args) != 1 { util.Failed("Too many arguments detected. Please provide only your Pantheon Machine token., e.g. 'ddev auth pantheon [token]'. See https://pantheon.io/docs/machine-tokens/ for instructions on creating a token.") } uid, _, _ := util.GetContainerUIDGid() _, out, err := dockerutil.RunSimpleContainer(version.GetWebImage(), "", []string{"terminus", "auth:login", "--machine-token=" + args[0]}, nil, []string{"HOME=/tmp"}, []string{"ddev-global-cache:/mnt/ddev-global-cache"}, uid, true) if err == nil { util.Success("Authentication successful!\nYou may now use the 'ddev config pantheon' command when configuring projects.") } else { util.Failed("Failed to authenticate: %v (%v)", err, out) } }, }
PantheonAuthCommand is the `ddev auth pantheon` command
var PoweroffCommand = &cobra.Command{ Use: "poweroff", Short: "Completely stop all projects and containers", Long: `ddev poweroff stops all projects and containers, equivalent to ddev stop -a --stop-ssh-agent`, Example: `ddev poweroff`, Args: cobra.NoArgs, Aliases: []string{"powerdown"}, Run: func(cmd *cobra.Command, args []string) { powerOff() }, }
PoweroffCommand contains the "ddev share" command
var PullCmd = &cobra.Command{ Use: "pull", Short: "Pull files and database using a configured provider plugin.", Long: `Pull files and database using a configured provider plugin. Running pull will connect to the configured provider and download + import the latest backups.`, Example: `ddev pull`, Args: cobra.ExactArgs(0), PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Run: func(cmd *cobra.Command, args []string) { appPull(skipConfirmationArg) }, }
PullCmd represents the `ddev pull` command.
var RestartCmd = &cobra.Command{ Use: "restart [projects]", Short: "Restart a project or several projects.", Long: `Stops named projects and then starts them back up again.`, Example: `ddev restart ddev restart <project1> <project2> ddev restart --all`, PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Run: func(cmd *cobra.Command, args []string) { projects, err := getRequestedProjects(args, restartAll) if err != nil { util.Failed("Failed to get project(s): %v", err) } for _, app := range projects { output.UserOut.Printf("Restarting project %s...", app.GetName()) err = app.Stop(false, false) if err != nil { util.Failed("Failed to restart %s: %v", app.GetName(), err) } err = app.Start() if err != nil { util.Failed("Failed to restart %s: %v", app.GetName(), err) } util.Success("Restarted %s", app.GetName()) httpURLs, urlList, _ := app.GetAllURLs() if globalconfig.GetCAROOT() == "" { urlList = httpURLs } util.Success("Your project can be reached at %s", strings.Join(urlList, " ")) } }, }
RestartCmd rebuilds an apps settings
var RootCmd = &cobra.Command{ Use: "ddev", Short: "DDEV-Local local development environment", Long: `Create and maintain a local web development environment. Docs: https://ddev.readthedocs.io Support: https://ddev.readthedocs.io/en/stable/#support`, Version: version.DdevVersion, PersistentPreRun: func(cmd *cobra.Command, args []string) { ignores := []string{"version", "config", "hostname", "help", "auth", "import-files"} command := strings.Join(os.Args[1:], " ") output.LogSetUp() for _, k := range ignores { if strings.Contains(command, k) { return } } err := dockerutil.CheckDockerVersion(version.DockerVersionConstraint) if err != nil { if err.Error() == "no docker" { if os.Args[1] != "version" { util.Failed("Could not connect to docker. Please ensure Docker is installed and running.") } } else { util.Failed("The docker version currently installed does not meet ddev's requirements: %v", err) } } err = dockerutil.CheckDockerCompose(version.DockerComposeVersionConstraint) if err != nil { if err.Error() == "no docker-compose" { util.Failed("docker-compose does not appear to be installed.") } else { util.Failed("The docker-compose version currently installed does not meet ddev's requirements: %v", err) } } updateFile := filepath.Join(globalconfig.GetGlobalDdevDir(), ".update") timeToCheckForUpdates, err := updatecheck.IsUpdateNeeded(updateFile, updateInterval) if err != nil { util.Warning("Could not perform update check: %v", err) } if timeToCheckForUpdates && globalconfig.IsInternetActive() { err = updatecheck.ResetUpdateTime(updateFile) if err != nil { util.Warning("Failed to update updatecheck file %s", updateFile) return } updateNeeded, updateURL, err := updatecheck.AvailableUpdates("drud", "ddev", version.DdevVersion) if err != nil { util.Warning("Could not check for updates. This is most often caused by a networking issue.") log.Debug(err) return } if updateNeeded { util.Warning("\n\nA new update is available! please visit %s to download the update.\nFor upgrade help see %s", updateURL, updateDocURL) } } }, PersistentPostRun: func(cmd *cobra.Command, args []string) { ignores := map[string]bool{"list": true, "version": true, "help": true, "auth": true, "hostname": true} if _, ok := ignores[cmd.CalledAs()]; ok { return } instrumentationNotSetUpWarning() cmdCopy := cmd var fullCommand = make([]string, 0) fullCommand = append(fullCommand, util.GetFirstWord(cmdCopy.Use)) for cmdCopy.HasParent() { fullCommand = append(fullCommand, util.GetFirstWord(cmdCopy.Parent().Use)) cmdCopy = cmdCopy.Parent() } for i := 0; i < len(fullCommand)/2; i++ { j := len(fullCommand) - i - 1 fullCommand[i], fullCommand[j] = fullCommand[j], fullCommand[i] } event := "" if len(fullCommand) > 1 { event = fullCommand[1] } if globalconfig.DdevGlobalConfig.InstrumentationOptIn && version.SegmentKey != "" && globalconfig.IsInternetActive() && len(fullCommand) > 1 { ddevapp.SetInstrumentationBaseTags() ddevapp.SendInstrumentationEvents(event) } }, }
RootCmd represents the base command when called without any subcommands
var SequelproLoc = "/Applications/Sequel Pro.app"
SequelproLoc is where we expect to find the sequel pro.app It's global so it can be mocked in testing.
var StartCmd = &cobra.Command{ Use: "start [projectname ...]", Aliases: []string{"add"}, Short: "Start a ddev project.", Long: `Start initializes and configures the web server and database containers to provide a local development environment. You can run 'ddev start' from a project directory to start that project, or you can start stopped projects in any directory by running 'ddev start projectname [projectname ...]'`, Example: `ddev start ddev start <project1> <project2> ddev start --all`, PreRun: func(cmd *cobra.Command, args []string) { dockerutil.EnsureDdevNetwork() }, Run: func(cmd *cobra.Command, args []string) { err := checkDdevVersionAndOptInInstrumentation() if err != nil { util.Failed(err.Error()) } projects, err := getRequestedProjects(args, startAll) if err != nil { util.Failed("Failed to get project(s): %v", err) } for _, project := range projects { if err := ddevapp.CheckForMissingProjectFiles(project); err != nil { util.Failed("Failed to start %s: %v", project.GetName(), err) } output.UserOut.Printf("Starting %s...", project.GetName()) if err := project.Start(); err != nil { util.Failed("Failed to start %s: %v", project.GetName(), err) continue } util.Success("Successfully started %s", project.GetName()) httpURLs, urlList, _ := project.GetAllURLs() if globalconfig.GetCAROOT() == "" { urlList = httpURLs } util.Success("Project can be reached at %s", strings.Join(urlList, " ")) } }, }
StartCmd provides the ddev start command
Functions ¶
Types ¶
This section is empty.
Source Files
¶
- a.go
- auth-ddev-live.go
- auth-pantheon.go
- auth-ssh.go
- auth.go
- cmd-packr.go
- cmd_version.go
- commands.go
- composer-create.go
- composer.go
- config-global.go
- config.go
- config_ddev-live.go
- config_pantheon.go
- debug-compose-config.go
- debug-config-yaml.go
- debug-nfsmount.go
- debug.go
- delete-images.go
- delete.go
- describe.go
- exec.go
- export-db.go
- hostname.go
- import-db.go
- import-files.go
- list.go
- logs.go
- pause.go
- poweroff.go
- pull.go
- restart.go
- restore_snapshot.go
- root.go
- sequelpro.go
- share.go
- snapshot.go
- ssh.go
- start.go
- stop.go
- utils.go