-
-
Notifications
You must be signed in to change notification settings - Fork 580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic port-test capabilities before trying to bring up router, fixes #126, fixes #393 #483
Conversation
74fa0cd
to
78f2c56
Compare
This should be ready for review. @rickmanelius it probably deserves manual testing from you to see if it accomplishes what we need at this point. |
Happy to assist with a manual review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preparation
git fetch --all
git checkout rfay/20170926_test_port_80
make clean && make darwin
- Confirmed
ddev version
outputsv0.9.1-17-g78f2c569
- Stop all ddev sites.
Review
- Validated that
ddev stop
andddev start
work correctly on a singular site. - Validated that
ddev list
shows the router in a stopped state. - Started macOS's Apache via
sudo apachectl start
and validated it is in control when visiting http://localhost - Attempted a
ddev start
, which started the containers and at the Network step, I received the following error message: "Failed to start rickmanelius: Unable to listen on required ports, Localhost port 80 is in use,
Troubleshooting suggestions at https://github.com/drud/ddev/blob/master/docs/users/troubleshooting.md" - Linking to "https://github.com/drud/ddev/blob/master/docs/users/troubleshooting.md" doesn't work until the PR is fixed. However, I was able to confirm the PR contains it here https://github.com/rfay/ddev/blob/78f2c569840da88170920c48a0d195bbd8b0c3cb/docs/users/troubleshooting.md.
- I confirmed the most obvious example
sudo apachectl stop
was provided. I ran the instructions and I was able to confirm thatddev start
worked. - I verified that there were other great suggestions for other scenarios.
- CONFIRMED
Suggestions
- At least on macOS, running lsof doesn't require sudo.
- I'm guilty of using OS X and macOS interchangeably, but macOS is the accurate term.
@rfay I still think it would be of value for @tannerjfco to complete a code review, but manual end-user testing was a +1 from me. |
docs/users/troubleshooting.md
Outdated
or `sudo launchctl stop homebrew.mxcl.nginx` | ||
* nginx (Ubuntu): `sudo service nginx stop` | ||
* apache (often named "httpd") (many environments): `sudo apachectl stop` or on Ubuntu `sudo service apache2 stop` | ||
* vpnkit (OSX): You likely have a docker container bound to port 80, do you have containers up for Kalabox or another docker-based development environment? If so, stop the other environment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put this "some suggestions" section at the top before the lsof stuff. Perhaps renaming it to "Common tools that use port 80" or similar. I feel like most people just want a fast solution, and if they see something like mamp/apache that they've previously used, would just jump right to that.
Also, a suggested addition:
- Kalabox: If you have previously used Kalabox try running
kbox poweroff
I went ahead and added a commit to fix all usages of OSX. Not actually legitimate to do here, but it seems pretty harmless. Didn't make sense to fix this PR without fixing other usages. I didn't change the sudo on lsof because it is required on Ubuntu and just seemed like it would muck things up to make the difference. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this, thanks @rfay! A couple comments and questions here.
pkg/plugins/platform/router.go
Outdated
@@ -76,8 +79,20 @@ func StartDdevRouter() error { | |||
_, err = f.WriteString(doc.String()) | |||
util.CheckErr(err) | |||
|
|||
// Stop router so we can test port. Of course, it may not be running. | |||
err = dockerutil.ComposeCmd([]string{dest}, "-p", RouterProjectName, "down") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't we check for our healthy router instead? If we already have our router running, we already have the ports we require, so why stop it and start over? It seems like stopping it could also allow for breaking already-running sites, should the new site encounter an error that results in the router not returning successfully
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related idea: We could probably generally check running docker containers for ports occupied and report back if a specific container has our port. It's a nice idea from viewpoint of giving user most specific path to resolution, but not sure if it's worth it overall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure we could create a FindContainerByName()
and look for "ddev-router" and that would be a faster & more stable check.
Between GetDockerContainers()
:
https://github.com/drud/ddev/blob/a0ee2e90c0aa388659d721b4b3f316727fba5506/pkg/dockerutil/dockerutils.go#L55-L60
and ContainerName()
we already have the primitives. just need to loop the containers and check the name and ensure they are running.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand all the comments here, the gist is "Let's not stop the router to test. If it's running, call it good and assume we have the ports." I'm good with that and can use the suggested techniques to do it. Slack link to full conversation: #483 (comment)
docs/users/troubleshooting.md
Outdated
## Webserver ports are already occupied by another webserver | ||
|
||
If you get a message from ddev about a port conflict on port 80 or 443, like this: | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
silly nit, but for best results w/ MkDocs' markdown parsing (what we're using on RTD), I suggest empty lines before and after formatting such as this. GitHub's markdown parsing is fantastic and doesn't seem to break much on this kind of thing anymore, but I've had to go back and fix little frustrations like this later in RTD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 278c462, thanks.
``` | ||
sudo apachectl stop | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(suggestion) Just a little more text here would help it flow: e.g. "There are many applications that could be using port 80. Here are some more common tools and how to stop them".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also fixed in 278c462
cmd/ddev/cmd/start.go
Outdated
@@ -33,7 +33,7 @@ provide a working environment for development.`, | |||
func appStart() { | |||
app, err := platform.GetActiveApp("") | |||
if err != nil { | |||
util.Failed("Failed to start: %s", err) | |||
util.Failed("Failed to GetActiveApp err: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this error carries a bit more meaning for us, but less meaning for users. we also lose the context of what command produced the failure. I'd prefer to keep the original error message. If we need better identification of GetActiveApp errors, maybe we could address that in the error messages it returns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 40cfd5b, good point.
pkg/plugins/platform/router.go
Outdated
@@ -96,6 +111,7 @@ func StartDdevRouter() error { | |||
|
|||
// PrintRouterStatus outputs router status and warning if not | |||
// running or healthy, as applicable. | |||
// An easy way to make these ports unavailable: sudo netcat -l -p 80 (brew install netcat) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment seems out of place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually intended here, but I added to it "In order to test this". The comment was to remind anybody how you'd test the port being occupied without a major effort of setting up apache or something.
pkg/plugins/platform/router.go
Outdated
} | ||
err = CheckRouterPorts() | ||
if err != nil { | ||
return fmt.Errorf("Unable to listen on required ports, %v,\nTroubleshooting suggestions at https://github.com/drud/ddev/blob/master/docs/users/troubleshooting.md", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please link to an anchor just for troubleshooting ports in this. Right now, the entire troubleshooting doc is great, but as it grows we don't we want to avoid sending people to a sea of information, particularly if we have already identified their problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The actual usage is like this in StartDdevRouter():
err = CheckRouterPorts()
if err != nil {
return fmt.Errorf("Unable to listen on required ports, %v,\nTroubleshooting suggestions at https://github.com/drud/ddev/blob/master/docs/users/troubleshooting.md", err)
}
I assume that's what you'd want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I may not have been clear enough. Sorry!
As you know, this PR introduces a new troubleshooting.md document. We're linking to it right here.
This works well for now, as the document is small, and finding information in it is very easy. However, this troubleshooting.md document is likely to grow over time. As such, it would be great to create anchors in it and link directly to those. That way if we add 3 more pages of information to the troubleshooting document over time, the user is still getting sent to an anchor that covers their specific issue. In this case, we'd want to link directly to the "Webserver ports are already occupied by another webserver" section of that file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added anchor in 4ccd462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works as intended but there are some small improvements to the code and messaging that could be made.
519cd1d
to
4af614a
Compare
Rebased to current master. |
4af614a
to
1408150
Compare
I think everybody's requests are addressed, most importantly, we don't stop the router just to see if we can start it again. |
pkg/plugins/platform/router.go
Outdated
if err != nil || container.State != "running" { | ||
err = CheckRouterPorts() | ||
if err != nil { | ||
return fmt.Errorf("Unable to listen on required ports, %v,\nTroubleshooting suggestions at https://github.com/drud/ddev/blob/master/docs/users/troubleshooting.md#unable-listen", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Troubleshooting link should be to our readthedocs site vs github.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Given that I believe a bulk of the requested changes were on @beeradb, I think once we get a 👍 from him we are good to go. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works as advertised and the code looks good. Thanks!
The Problem/Issue/Bug:
#126 explains: we need to test ports 80 and 443 before we let docker-compose try to bring up the router. If we find that somebody is already listening on them, we need to explain the problem to the user gracefully and provide resources to resolve the problem.
This also fixes #393 (Stopped site, double notifications of broken router)
How this PR Solves The Problem:
Manual Testing Instructions:
docker run -p 80:80 -p 443:443 --entrypoint=/bin/cat -it --rm busybox
You can also start netcat or apache or nginx or many other ways.ddev start
with or without, you should see correct behavior.To test the fix for #393
docker stop ddev-router
ddev list
andddev describe
to look for the issueThis now has:
Automated Testing Overview:
Added TestRouterPortsCheck() which occupies port 80 using a docker container and then tests to see if we can start the router.
Related Issue Link(s):
OP #126
Release/Deployment notes: