Skip to content
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

Quick start guide does not work #1517

Closed
rszibele opened this issue Jun 6, 2018 · 20 comments
Closed

Quick start guide does not work #1517

rszibele opened this issue Jun 6, 2018 · 20 comments

Comments

@rszibele
Copy link

rszibele commented Jun 6, 2018

Following the quick start guide at https://www.yesodweb.com/page/quickstart I can't seem to get yesod-sqlite to work. Everything builds fine but it seems that the executable exits early, thereby only displaying the page with "The application isn't built".

e.g:

richard@linux-aovt:~/Documents/szibele> stack exec -- yesod devel
Yesod devel server. Enter 'quit' or hit Ctrl-C to quit.
Application can be accessed at:

http://localhost:3000
https://localhost:3443
If you wish to test https capabilities, you should set the following variable:
export APPROOT=https://localhost:3443

ExitSuccess
Type help for available commands. Press enter to force a rebuild.
Starting devel application
Devel application launched: http://localhost:3000

What makes me suspicious is the ExitSuccess line.

My setup:

operating system: OpenSUSE Leap 15

richard@linux-aovt:~> uname
Linux

richard@linux-aovt:~> uname -a
Linux linux-aovt 4.17.0-1.gbcb3422-vanilla #1 SMP PREEMPT Mon Jun 4 08:26:32 UTC 2018 (bcb3422) x86_64 x86_64 x86_64 GNU/Linux

richard@linux-aovt:~> stack --version
Version 1.7.1, Git revision 681c800873816c022739ca7ed14755e85a579565 (5807 commits) x86_64 hpack-0.28.2

richard@linux-aovt:~> stack ghc -- --version
Writing implicit global project config file to: /home/richard/.stack/global-project/stack.yaml
Note: You can change the snapshot via the resolver field there.
Using latest snapshot resolver: lts-11.12
The Glorious Glasgow Haskell Compilation System, version 8.2.2

richard@linux-aovt:~/Documents/szibele> stack list-dependencies
DEPRECATED: Use ls dependencies instead. Will be removed in next major version.
Cabal 2.0.1.1
StateVar 1.1.1.0
adjunctions 4.4
aeson 1.2.4.0
aeson-compat 0.3.7.1
ansi-terminal 0.8.0.4
ansi-wl-pprint 0.6.8.2
appar 0.1.4
array 0.5.2.0
asn1-encoding 0.9.5
asn1-parse 0.9.4
asn1-types 0.3.2
async 2.1.1.1
attoparsec 0.13.2.2
attoparsec-iso8601 1.0.0.0
authenticate 1.3.4
auto-update 0.1.4
base 4.10.1.0
base-compat 0.9.3
base-orphans 0.7
base16-bytestring 0.1.1.6
base64-bytestring 1.0.0.1
basement 0.0.7
basic-prelude 0.7.0
bifunctors 5.5.2
binary 0.8.5.1
blaze-builder 0.4.1.0
blaze-html 0.9.0.1
blaze-markup 0.8.2.1
bsb-http-chunked 0.0.0.2
byteable 0.1.1
byteorder 1.0.4
bytestring 0.10.8.2
bytestring-builder 0.10.8.1.0
cabal-doctest 1.0.6
case-insensitive 1.2.0.11
cereal 0.5.5.0
chunked-data 0.3.1
cipher-aes 0.2.11
classy-prelude 1.4.0
classy-prelude-conduit 1.4.0
classy-prelude-yesod 1.4.0
clientsession 0.9.1.2
colour 2.3.4
comonad 5.0.3
conduit 1.3.0.2
conduit-extra 1.3.0
connection 0.2.8
containers 0.5.10.2
contravariant 1.4.1
cookie 0.4.4
cpphs 1.20.8
cprng-aes 0.6.1
crypto-api 0.13.3
crypto-cipher-types 0.0.9
crypto-random 0.0.9
cryptonite 0.25
cryptonite-conduit 0.2.2
css-text 0.1.3.0
data-default 0.7.1.1
data-default-class 0.1.2.0
data-default-instances-containers 0.0.1
data-default-instances-dlist 0.0.1
data-default-instances-old-locale 0.0.1
deepseq 1.4.3.0
deepseq-generics 0.2.0.0
directory 1.3.0.2
distributive 0.5.3
dlist 0.8.0.4
dlist-instances 0.1.1.1
easy-file 0.2.2
email-validate 2.3.2.5
entropy 0.3.8
exceptions 0.8.3
fail 4.9.0.0
fast-logger 2.4.11
file-embed 0.0.10.1
filepath 1.4.1.2
foreign-store 0.2
foundation 0.0.20
free 5.0.2
ghc-boot-th 8.2.2
ghc-prim 0.5.1.1
hashable 1.2.7.0
haskell-src-exts 1.20.2
haskell-src-meta 0.8.0.2
hjsmin 0.2.0.2
hourglass 0.2.11
http-api-data 0.3.7.2
http-client 0.5.12.1
http-client-tls 0.3.5.3
http-conduit 2.3.1
http-date 0.0.7
http-types 0.12.1
http2 1.6.3
integer-gmp 1.0.1.0
integer-logarithms 1.0.2.1
iproute 1.7.5
kan-extensions 5.1
keys 3.12
language-javascript 0.6.0.11
lifted-base 0.2.3.12
memory 0.14.16
microlens 0.4.8.3
microlens-th 0.4.1.3
mime-mail 0.4.14
mime-types 0.1.0.7
monad-control 1.0.2.3
monad-logger 0.3.28.5
monad-loops 0.4.3
mono-traversable 1.0.8.1
mono-traversable-instances 0.1.0.0
mtl 2.2.2
mutable-containers 0.3.4
network 2.6.3.5
network-uri 2.6.1.0
nonce 1.0.7
old-locale 1.0.0.7
old-time 1.1.0.3
optparse-applicative 0.14.2.0
parsec 3.1.13.0
path-pieces 0.2.1
pem 0.2.4
persistent 2.8.2
persistent-sqlite 2.8.1.2
persistent-template 2.5.4
pointed 5.0.1
polyparse 1.12
pretty 1.1.3.3
primitive 0.6.3.0
process 1.6.1.0
profunctors 5.2.2
psqueues 0.2.7.0
random 1.1
resource-pool 0.2.3.2
resourcet 1.2.1
rts 1.0
safe 0.3.17
say 0.1.0.0
scientific 0.3.6.2
securemem 0.1.10
semigroupoids 5.2.2
semigroups 0.18.4
setenv 0.1.1.3
shakespeare 2.0.15
silently 1.2.5
simple-sendfile 0.2.27
skein 1.0.9.4
socks 0.5.6
split 0.2.3.3
stm 2.4.5.0
stm-chans 3.0.0.4
streaming-commons 0.1.19
stringsearch 0.3.6.6
syb 0.7
szibele 0.0.0
tagged 0.8.5
tagsoup 0.14.6
tagstream-conduit 0.5.5.3
template-haskell 2.12.0.0
text 1.2.3.0
th-abstraction 0.2.6.0
th-expand-syns 0.4.4.0
th-lift 0.7.10
th-lift-instances 0.1.11
th-orphans 0.13.5
th-reify-many 0.1.8
time 1.8.0.2
time-locale-compat 0.1.1.4
tls 1.4.1
transformers 0.5.2.0
transformers-base 0.4.4
transformers-compat 0.5.1.4
typed-process 0.2.2.0
unix 2.7.2.2
unix-compat 0.5.0.1
unix-time 0.3.8
unliftio 0.2.7.0
unliftio-core 0.1.1.0
unordered-containers 0.2.9.0
uri-bytestring 0.3.2.0
utf8-string 1.0.1.1
uuid-types 1.0.3
vault 0.3.1.1
vector 0.12.0.1
vector-algorithms 0.7.0.1
vector-instances 3.4
void 0.7.2
wai 3.2.1.2
wai-app-static 3.1.6.2
wai-extra 3.0.22.0
wai-logger 2.3.2
warp 3.2.22
word8 0.1.3
x509 1.7.3
x509-store 1.6.6
x509-system 1.6.6
x509-validation 1.6.10
xml-conduit 1.8.0
xml-types 0.3.6
xss-sanitize 0.3.5.7
yaml 0.8.30
yesod 1.6.0
yesod-auth 1.6.3
yesod-core 1.6.5
yesod-form 1.6.1
yesod-newsfeed 1.6.1.0
yesod-persistent 1.6.0
yesod-static 1.6.0
zlib 0.6.2

richard@linux-aovt:~> yesod version
yesod-bin version: 1.6.0.3
@psibi
Copy link
Member

psibi commented Jun 6, 2018

Just to be sure, can you try the following after issuing the command stack exec --yesod devel:

  • Wait untill it shows ExitSuccess
  • See if your Yesod app appears at http://localhost:3000
  • If it doesn't appear, press Enter in console. That will issue a rebuild. Wait till it get's completed and check again in the browser.

Let me know if that helps/doesn't help.

@rszibele
Copy link
Author

rszibele commented Jun 6, 2018

Thanks for the quick response, psibi. Following your instructions, ExitSuccess no longer appears after a rebuild by pressing Enter in the console so I assume it should be running now. However, it still displays The application isn't built.

What I've also tried in the meanwhile:

  • deleted ~/.stack
  • deleted ~/.ghc
  • ran stack upgrade
  • followed the instructions on the quick guide to set up my project

I unfortunately still get the same issue.

@rszibele
Copy link
Author

rszibele commented Jun 6, 2018

I tried and did exactly the same thing in a virtual machine on Ubuntu 18.04 and it works. I'll be investigating why it doesn't work on OpenSUSE Leap 15.

@rszibele
Copy link
Author

rszibele commented Jun 7, 2018

Ok, this is strange. It only listens on ipv6 even though in the configuration (settings.yml) it should listen on any ipv4 address: _env:HOST:*4.

richard@linux-aovt:~> ss -ltn
State       Recv-Q Send-Q                                Local Address:Port                                               Peer Address:Port              
LISTEN      0      5                                         127.0.0.1:631                                                     0.0.0.0:*                  
LISTEN      0      100                                       127.0.0.1:25                                                      0.0.0.0:*                  
LISTEN      0      50                                                *:1716                                                          *:*                  
LISTEN      0      5                                             [::1]:631                                                        [::]:*                  
LISTEN      0      128          [2003:ec:ebde:500:307a:66cb:af80:d056]:3000                                                       [::]:*                  
LISTEN      0      100                                           [::1]:25                                                         [::]:*

Opening [2003:ec:ebde:500:307a:66cb:af80:d056]:3000 in Firefox shows the web page.

@psibi
Copy link
Member

psibi commented Jun 7, 2018

That's strange. I checked on my Ubuntu machine too and the template worked fine. Not really sure why this is happening with OpenSUSE.

@rszibele
Copy link
Author

rszibele commented Jun 7, 2018

According to http://hackage.haskell.org/package/warp-3.2.22/docs/Network-Wai-Handler-Warp.html#t:HostPreference *4 means any IPv4 or IPv6 hostname, IPv4 preferred, so I thought changing it to !4 which means any IPv4 hostname would solve it, but I still get the same result. I also tried 127.0.0.1 or localhost without success.

@rszibele
Copy link
Author

rszibele commented Jun 7, 2018

Found the issue, OpenSUSE doesn't bind the hostname to localhost on a fresh install which causes this issue.

@rszibele rszibele closed this as completed Jun 7, 2018
@rszibele
Copy link
Author

rszibele commented Jun 7, 2018

I'll have to reopen this as I've spoken with the lads over at freenode #SUSE and they say it's an issue with the framework as it shouldn't be a requirement that the hostname is bound to localhost. What I also find strange is that 127.0.0.1, localhost or !4 didn't work, it should, shouldn't it?

@rszibele rszibele reopened this Jun 7, 2018
@psibi
Copy link
Member

psibi commented Jun 7, 2018

What I also find strange is that 127.0.0.1, localhost or !4 didn't work, it should, shouldn't it?

!4 should have worked.
127.0.0.1 should have worked. But it seems to have assigned IPv6 to you. So that explains why that didn't work.
localhost - Now if it's not binded, it won't work.

@psibi
Copy link
Member

psibi commented Jun 7, 2018

BTW, Thanks for the great debugging!

@rszibele
Copy link
Author

rszibele commented Jun 8, 2018

localhost is bound to 127.0.0.1, but my computers hostname opensuse isn't bound to anything in /etc/hosts, sorry for not being clear. On Ubuntu the computers hostname is bound to a local address, but not on OpenSUSE.

@psibi
Copy link
Member

psibi commented Jun 11, 2018

@rszibele So, I looked on to this but I wasn't able to find anything interesting on a Ubuntu based Linux machine. Can you run this program in your SUSE machine:

#!/usr/bin/env stack
{- stack
     --resolver lts-11.6
     --install-ghc
     runghc
     --package warp
     --package wai
     --package http-types
 -}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

import Network.HTTP.Types
import Network.Wai
import Network.Wai.Handler.Warp

app :: Application
app _req sendResponse =
  sendResponse $
  responseLBS status200 [("Content-Type", "text/plain")] "Hello Warp!"

main :: IO ()
main = runSettings (setHost "!4" defaultSettings) app

For executing it, you should do stack filename.hs and check if localhost:3000 works in your browser. And after that can you show the paste the output of the following command here:

$ netstat -lntp

There was one odd behavior which I found using !6 which made it work in both ipv4 and ipv6. But after reading some documentation, that seems to be the case of IPv4-mapped IPv6 addresses. It would be good to document that behavior as part of HostPreferences IMO.

@snoyberg
Copy link
Member

One minor FYI: if you're using yesod devel, you'll want to use the --host parameter on the command line to control which host yesod devel itself binds to. The config file will affect the application running behind yesod devel.

@rszibele
Copy link
Author

rszibele commented Jun 13, 2018

@psibi Here's the output of netstat after executing your snippet. It's bound correctly and it works.

richard@opensuse:~/Documents> netstat -lntp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      30801/ghc           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::1716                 :::*                    LISTEN      3018/kdeconnectd    
tcp6       0      0 ::1:631                 :::*                    LISTEN      -                   
tcp6       0      0 ::1:25                  :::*                    LISTEN      -

I've been debugging further and I've been wondering why your snippet works (as in, binds to IPv4) but the getting started project doesn't. It turns out that you pass !4 directly to WAI, while the yesod project detects the presence of the HOST environment variable and uses that instead if it is defined. OpenSUSE sets this variable by default.

richard@opensuse:~> echo $HOST
opensuse

If I change _env:HOST:*4 to *4 in settings.yml, the generated project works correctly as it no longer uses the HOST environment variable.

@snoyberg Now knowing that host gets set to opensuse on my computer and the setting gets overridden by default, I've also tried running stack exec -- yesod devel --host opensuse, and it works when I visit http://opensuse:3000 but it prints a bogus message:

Devel application launched: http://localhost:3000

It should actually be http://opensuse:3000 on my computer. The offending line: https://github.com/yesodweb/yesod/blob/master/yesod/Yesod/Default/Config2.hs#L97

To summarize what we've found:

  • OpenSUSE doesn't bind the computers hostname to localhost
  • OpenSUSE sets the HOST environment variable by default to the computers hostname and wont work out-of-the-box with yesod because the hostname isn't bound to localhost
  • yesod devel itself works but doesn't "detect" the app unless the host is provided to yesod devel as a command line argument

Two possible solutions which would independently make the getting started projects work out-of-the box:

  1. Prefix the environment variables yesod looks for within these generated projects with something unique like YESOD_ to prevent clashing of environment variables. For example: _env:YESOD_HOST:*4 and _env:YESOD_PORT:3000.
  2. Make yesod devel autodetect and use the same host as the app.

@snoyberg
Copy link
Member

I'll be honest: I'm not too terribly thrilled about making changes to Yesod for this case. Having localhost not working is pretty extreme. I'd be more willing to have a link on the quickstart page saying "You're on OpenSUSE? Click here." That said, I'm OK with prefixing YESOD_ in the template I think. I'm not at all convinced that yesod devel should do the same thing though; perhaps using IP address instead of localhost in the display would be OK.

@rszibele
Copy link
Author

localhost itself works, it's just that yesod binds to the hostname by default and not localhost, which isn't the same thing on OpenSUSE.

The prefix would also fix it, so either of the solutions is a good fix.

@StevenXL
Copy link
Member

StevenXL commented Jun 13, 2018

I've updated the QuickStart guide for openSUSE users in this PR, as this was the easiest change that both @snoyberg and @rszibele agreed would be acceptable.

IF that PR is merged, I think we can close this issue.

@snoyberg
Copy link
Member

The new templates have been pushed, can you give it a shot again and confirm that the problem has been solved?

@rszibele
Copy link
Author

@snoyberg Yes, the problem has been resolved.

@develop7
Copy link

it's just that yesod binds to the hostname by default and not localhost

confirming that, the HOST environment variable of yesod process is actually a default hostname instead of localhost. Which leads to question: why do we prefer it to the localhost or 127.0.0.1, like others do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants