internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: jupyterhub/jupyterhub

Issue:
Correct spelling error in SSL message
When starting JupyterHub without SSL configured properly and `--no-ssl` flag isn't used, the error message printed (from `start_proxy()`, defined in `app.py`) misspells the name of the project:

``` python
" Refusing to run JuptyterHub without SSL."
" If you are terminating SSL in another layer,"
" pass --no-ssl to tell JupyterHub to allow the proxy to listen on HTTP."
```

`app.py`:lines 1021-1023



Discussion:

Resolving patch:
diff --git a/jupyterhub/app.py b/jupyterhub/app.py
--- a/jupyterhub/app.py
+++ b/jupyterhub/app.py
@@ -1018,7 +1018,7 @@ def start_proxy(self):
                     " There better be SSL termination happening somewhere else...")
             else:
                 self.log.error(
-                    "Refusing to run JuptyterHub without SSL."
+                    "Refusing to run JupyterHub without SSL."
                     " If you are terminating SSL in another layer,"
                     " pass --no-ssl to tell JupyterHub to allow the proxy to listen on HTTP."
                 )


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
`KeyError("User %k does not not exist.")` when Unix user has been deleted.
JupyterHub version: 0.6.1
OS: Debian Jessie

We had followed this wiki to setup JupyterHub to run as a service on Debian Jessie, using the init.d script instead of a systemd service unit file: https://github.com/jupyterhub/jupyterhub/wiki/Run-jupyterhub-as-a-system-service

However, we are running into the exact same problem as this guy: https://serverfault.com/questions/794938/jupyterhub-error-on-start-keyerror-user-k-does-not-exist

His solution is to delete the jupyter.sqlite file.

In our case, we allow Unix account users to log into JupyterHub. But one of the users has left the company, so we removed his Unix account, and his username is showing up in the KeyError.

Oddly enough, this problem only happens if we try to start JupyterHub as a service. If we run JupyterHub at the terminal, the KeyError doesn't show up, and users can actually use JupyterHub.

Is it safe to just delete the jupyterhub.sqlite file while JupyterHub is not running?



Discussion:
@ksze Thanks for the issue report.

Pinging @minrk. 


Resolving patch:
diff --git a/jupyterhub/app.py b/jupyterhub/app.py
--- a/jupyterhub/app.py
+++ b/jupyterhub/app.py
@@ -855,7 +855,13 @@ def init_users(self):
         # but changes to the whitelist can occur in the database,
         # and persist across sessions.
         for user in db.query(orm.User):
-            yield gen.maybe_future(self.authenticator.add_user(user))
+            try:
+                yield gen.maybe_future(self.authenticator.add_user(user))
+            except Exception:
+                # TODO: Review approach to synchronize whitelist with db
+                # known cause of the exception is a user who has already been removed from the system
+                # but the user still exists in the hub's user db
+                self.log.exception("Error adding user %r already in db", user.name)
         db.commit() # can add_user touch the db?
 
         # The whitelist set and the users in the db are now the same.


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
Deprecation of old spawners doesn't have a fallback
The current code in `user.py` says:

```
233                 # prior to 0.7, spawners had to store this info in user.server themselves.
234                 # Handle < 0.7 behavior with a warning, assuming info was stored in db by the Spawner.
235                 self.log.warning("DEPRECATION: Spawner.start should return (ip, port) in JupyterHub >= 0.7")
```

It's probably better to raise an exception instead
As it is, it gives the impression that the code can keep working as is, but in practice, the server ip and port are not set and the wait_up times out.



Discussion:
The deprecation should be correct because the 0.6 mechanism should indeed still work if ip, port are not returned. This is tested and confirmed to work in a few Spawners. What Spawner are you using where you see this failing?

@minrk we built our own spawners, so I was surprised when nothing worked anymore because our start didn't return the pair ;)

Can you share them? This would be a bug if the old way doesn't work anymore, because I tested it with Spawners that store the ip/port the old way and they do work with 0.7, so I'm not sure what yours are doing differently.

@minrk  I had to change this line https://github.com/simphony/simphony-remote/blob/master/remoteappmanager/spawners.py#L179

@minrk it is possible we are misusing the Local spawner...

@stefanoborini aha! I see what happened. LocalProcessSpawner itself updated to the new mechanism, removing the old way because it knows it's no longer necessary. But _subclasses_ of LocalProcessSpawner could implicitly rely on the base class's setting of the values in the db, which was removed.

If your subclass passed through the return value from `super().start()`, then it would work correctly in all JupyterHub versions, but since it was a safe assumption that the return value could be discarded before, there's no reason to assume that you would pass it through.

I'll add the old way back so that subclasses of LocalProcessSpawner continue to work, and trigger the deprecation warning.


Resolving patch:
diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py
--- a/jupyterhub/spawner.py
+++ b/jupyterhub/spawner.py
@@ -495,6 +495,16 @@ def start(self):
             raise
 
         self.pid = self.proc.pid
+
+        if self.__class__ is not LocalProcessSpawner:
+            # subclasses may not pass through return value of super().start,
+            # relying on deprecated 0.6 way of setting ip, port,
+            # so keep a redundant copy here for now.
+            # A deprecation warning will be shown if the subclass
+            # does not return ip, port.
+            if self.ip:
+                self.user.server.ip = self.ip
+            self.user.server.port = self.port
         return (self.ip or '127.0.0.1', self.port)
 
     @gen.coroutine


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
Generate config file with a path produces error
`jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub_config.py` produces the following error.

<img width="753" alt="screen shot 2016-10-12 at 22 34 56" src="https://cloud.githubusercontent.com/assets/2680980/19337689/2d05ef52-90cc-11e6-9700-b81deb7071c5.png">

Looking at the tests, it seems as if we are only testing the filename not the path+filename.

The docstring seems to indicate that the above command is valid:

<img width="790" alt="screen shot 2016-10-12 at 22 42 11" src="https://cloud.githubusercontent.com/assets/2680980/19337839/6a96207a-90cd-11e6-9821-c568b30e52e7.png">



Discussion:
Does `/etc/jupyterhub` exist? This is an error you get when trying to create a file in a directory that is not present.


Resolving patch:
diff --git a/jupyterhub/app.py b/jupyterhub/app.py
--- a/jupyterhub/app.py
+++ b/jupyterhub/app.py
@@ -180,7 +180,7 @@ class JupyterHub(Application):
 
     generate default config file:
 
-        jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub.py
+        jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub_config.py
 
     spawn the server on 10.0.1.2:443 with https:
 
@@ -1351,6 +1351,9 @@ def cleanup(self):
 
     def write_config_file(self):
         """Write our default config to a .py config file"""
+        if not os.path.exists(self.config_file):
+            print("Path does not exist. The destination directory must exist before generating config file.")
+            return
         if os.path.exists(self.config_file) and not self.answer_yes:
             answer = ''
             def ask():


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
Remove or edit unreachable code block
@minrk It looks like `_check_user_model` has a few code lines that don't seem to be reachable. Should we remove the lines after the return statement? https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/base.py#L144



Discussion:

Resolving patch:
diff --git a/jupyterhub/apihandlers/base.py b/jupyterhub/apihandlers/base.py
--- a/jupyterhub/apihandlers/base.py
+++ b/jupyterhub/apihandlers/base.py
@@ -140,19 +140,18 @@ def _check_model(self, model, model_types, name):
 
     def _check_user_model(self, model):
         """Check a request-provided user model from a REST API"""
-        return self._check_model(model, self._user_model_types, 'user')
-        for groupname in model.get('groups', []):
-            if not isinstance(groupname, str):
-                raise web.HTTPError(400, "group names must be str, not %r" % type(groupname))
+        self._check_model(model, self._user_model_types, 'user')
+        for username in model.get('users', []):
+            if not isinstance(username, str):
+                raise web.HTTPError(400, ("usernames must be str, not %r", type(username)))
 
     def _check_group_model(self, model):
-        """Check a request-provided user model from a REST API"""
+        """Check a request-provided group model from a REST API"""
         self._check_model(model, self._group_model_types, 'group')
-        for username in model.get('users', []):
-            if not isinstance(username, str):
-                raise web.HTTPError(400, "usernames must be str, not %r" % type(groupname))
+        for groupname in model.get('groups', []):
+            if not isinstance(groupname, str):
+                raise web.HTTPError(400, ("group names must be str, not %r", type(groupname)))
 
     def options(self, *args, **kwargs):
         self.set_header('Access-Control-Allow-Headers', 'accept, content-type')
         self.finish()
-    
\ No newline at end of file


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
Generate config file with a path produces error
`jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub_config.py` produces the following error.

<img width="753" alt="screen shot 2016-10-12 at 22 34 56" src="https://cloud.githubusercontent.com/assets/2680980/19337689/2d05ef52-90cc-11e6-9700-b81deb7071c5.png">

Looking at the tests, it seems as if we are only testing the filename not the path+filename.

The docstring seems to indicate that the above command is valid:

<img width="790" alt="screen shot 2016-10-12 at 22 42 11" src="https://cloud.githubusercontent.com/assets/2680980/19337839/6a96207a-90cd-11e6-9821-c568b30e52e7.png">



Discussion:
Does `/etc/jupyterhub` exist? This is an error you get when trying to create a file in a directory that is not present.


Resolving patch:
diff --git a/jupyterhub/app.py b/jupyterhub/app.py
--- a/jupyterhub/app.py
+++ b/jupyterhub/app.py
@@ -180,7 +180,7 @@ class JupyterHub(Application):
 
     generate default config file:
 
-        jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub.py
+        jupyterhub --generate-config -f /etc/jupyterhub/jupyterhub_config.py
 
     spawn the server on 10.0.1.2:443 with https:
 
@@ -1351,6 +1351,11 @@ def cleanup(self):
 
     def write_config_file(self):
         """Write our default config to a .py config file"""
+        config_file_dir = os.path.dirname(os.path.abspath(self.config_file))
+        if not os.path.isdir(config_file_dir):
+            self.exit("{} does not exist. The destination directory must exist before generating config file.".format(
+                config_file_dir,
+            ))
         if os.path.exists(self.config_file) and not self.answer_yes:
             answer = ''
             def ask():


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
jupyterhub update-db fails
When I run it, I get:

```
    FileNotFoundError: [Errno 2] No such file or directory: '/home/yuvipanda/code/jupyterhub-kubernetes-spawner/lib/python3.5/site-packages/jupyterhub/alembic.ini'
```

I didn't capture the full stack trace though.



Discussion:
What JupyterHub version is this? The `jupyterhub/alembic.ini` path doesn't make sense with master, because master writes a temporary alembic.ini at call-time.

Hmm...it may be that the initial creation of the alembic.ini at call-time is using a different path than upgrade-db with `alembic_ini`.

For this one, I think I was running JupyterHub from pypi initially, and
then did a 'pip install -e ~/code/jupyterhub' to get master...

On Thu, Oct 27, 2016 at 1:51 PM, Carol Willing notifications@github.com
wrote:

> Hmm...it may be that the initial creation of the alembic.ini at call-time
> is using a different path than upgrade-db with alembic_ini.
> 
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> https://github.com/jupyterhub/jupyterhub/issues/825#issuecomment-256765412,
> or mute the thread
> https://github.com/notifications/unsubscribe-auth/AAB23gMAJORCD16zdXifFyHnxUROfzQxks5q4Q7fgaJpZM4KdipG
> .

## 

Yuvi Panda T
http://yuvi.in/blog


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -66,6 +66,7 @@ def get_package_data():
     """
     package_data = {}
     package_data['jupyterhub'] = [
+        'alembic.ini',
         'alembic/*',
         'alembic/versions/*',
     ]


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
Generated jupyterhub_config.py has whitelist error
Hi Everyone,

Minor issue with jupyterhub_config.py that is generated by jupyterhub command. The string is as follows:
#c.Authenticator.whitelist = set('')

This causes all user logins to fail. When I changed it to the following--which is on the Getting Started page--the whitelist worked as expected:
c.Authenticator.whitelist = {''}

Again, minor issue, but it may trip up Python newbies. :)

--John



Discussion:
How did you run the config generation? This is what I get:

```python
#c.Authenticator.whitelist = set()
```

which is correct.
Hi @hokiegeek2,

Thanks for the issue report. I'm getting the same results as @minrk for Python 3.5 (as a reminder JupyterHub runs on Python3). Out of curiousity, how did you install JupyterHub? Perhaps there was already a config file in your environment.

I'm going to go ahead and close this issue since we can't replicate it. If you have additional information, I would be happy to look into it.

Thanks! - Carol

Hey Everyone,

I apologize for the delay in following up on this. @minrk Yes, the config generation results in this format. However, when I manually set the users in this data structure:
c.Authenticator.whitelist = set('hokiegeek2')
I get this message:
[W 2016-12-03 23:25:36.672 JupyterHub auth:138] User 'hokiegeek2' not in whitelist.

When I switch to this, the whitelist filter works correctly:
c.Authenticator.whitelist = {'hokiegeek2'}

--John
Thanks for the update @hokiegeek2.

@minrk Do we want to edit the comment about whitelist and/or add a note in the docs?

Resolving patch:
diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py
--- a/jupyterhub/auth.py
+++ b/jupyterhub/auth.py
@@ -56,6 +56,17 @@ class Authenticator(LoggingConfigurable):
         """
     ).tag(config=True)
 
+    @observe('whitelist')
+    def _check_whitelist(self, change):
+        short_names = [name for name in change['new'] if len(name) <= 1]
+        if short_names:
+            sorted_names = sorted(short_names)
+            single = ''.join(sorted_names)
+            string_set_typo = "set('%s')" % single
+            self.log.warning("whitelist contains single-character names: %s; did you mean set([%r]) instead of %s?",
+                sorted_names[:8], single, string_set_typo,
+            )
+
     custom_html = Unicode(
         help="""
         HTML form to be overridden by authenticators if they want a custom authentication form.


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
cwd isn't set for a managed service if user is set
Hi! Thanks for using JupyterHub.

If you are reporting an issue with JupyterHub:

**How to reproduce the issue**

Configure a managed service with both the `cwd` and `user` options.

**What you expected to happen**

The managed service should be started by the configured `user` in the `cwd`.

**What actually happens**

The `cwd` is passed to Popen (I have verified that) but it is lost when the process becomes that users (other than root). Thus `cwd` only appear to work if the `user` option is not set. This is important because the nbgrader formgrade service needs both of these options to work.

**Share what version of JupyterHub you are using**

Latest master (0.7.2).



Discussion:
Looks like the `LocalProcessSpawner` is setting the `cwd` to the user's home dir:

https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/spawner.py#L669

Resolving patch:
diff --git a/jupyterhub/services/service.py b/jupyterhub/services/service.py
--- a/jupyterhub/services/service.py
+++ b/jupyterhub/services/service.py
@@ -56,7 +56,7 @@
 
 from .. import orm
 from ..traitlets import Command
-from ..spawner import LocalProcessSpawner
+from ..spawner import LocalProcessSpawner, set_user_setuid
 from ..utils import url_path_join
 
 class _MockUser(HasTraits):
@@ -80,7 +80,7 @@ def make_preexec_fn(self, name):
         if not name or name == getuser():
             # no setuid if no name
             return
-        return super().make_preexec_fn(name)
+        return set_user_setuid(name, chdir=False)
 
     def start(self):
         """Start the process"""
diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py
--- a/jupyterhub/spawner.py
+++ b/jupyterhub/spawner.py
@@ -639,7 +639,7 @@ def _try_setcwd(path):
     os.chdir(td)
 
 
-def set_user_setuid(username):
+def set_user_setuid(username, chdir=True):
     """Return a preexec_fn for spawning a single-user server as a particular user.
 
     Returned preexec_fn will set uid/gid, and attempt to chdir to the target user's
@@ -666,7 +666,8 @@ def preexec():
         os.setuid(uid)
 
         # start in the user's home dir
-        _try_setcwd(home)
+        if chdir:
+            _try_setcwd(home)
 
     return preexec
 


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
API /user/{name} ambiguous
Both PATCH and POST method accept this json body:

{
  "name":  "nameOFtheuser",
  "admin": true
}

The hub will use the {name} inside the URL but if you try to call the endpoint with a PATCH method and different names (body and url) you will get 

 sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush.]

I think it would better to accept only one name and not both.

I propose to remove the name from the json body and return an error in case is provided.

https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/users.py#L152
https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/base.py#L141
https://github.com/jupyterhub/jupyterhub/blob/master/jupyterhub/apihandlers/base.py#L112


Discussion:

Resolving patch:
diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py
--- a/jupyterhub/apihandlers/users.py
+++ b/jupyterhub/apihandlers/users.py
@@ -150,6 +150,10 @@ def patch(self, name):
             raise web.HTTPError(404)
         data = self.get_json_body()
         self._check_user_model(data)
+        if 'name' in data and data['name'] != name:
+            # check if the new name is already taken inside db
+            if self.find_user(data['name']):
+                raise web.HTTPError(400, "User %s already exists, username must be unique" % data['name'])
         for key, value in data.items():
             setattr(user, key, value)
         self.db.commit()
@@ -209,7 +213,8 @@ def post(self, name):
             raise web.HTTPError(400, "%s's server is not running" % name)
         self.set_server_cookie(user)
         # a service can also ask for a user cookie
-        # this code prevent to raise an error
+        # this code prevents to raise an error
+        # cause service doesn't have 'other_user_cookies'
         if getattr(current, 'other_user_cookies', None) is not None:
             current.other_user_cookies.add(name)
 


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
cookie_id column in users table should be NOT NULL and UNIQUE
**How to reproduce the issue**

Accidentally delete the jupyterhub database, and when recreating it from logs make cookie_id for more than one user be empty or the same dummy value.

**What you expected to happen**

The db schema complains, telling me 'nuh-uh'.

**What actually happens**

All users who have the same cookie_id value are redirected to the notebook of the user with the lowest id among the users with same cookie_id, leaking private contents of notebook to others.

**Share what version of JupyterHub you are using**

0.7.2



Discussion:

Resolving patch:
diff --git a/jupyterhub/orm.py b/jupyterhub/orm.py
--- a/jupyterhub/orm.py
+++ b/jupyterhub/orm.py
@@ -381,7 +381,7 @@ class User(Base):
     last_activity = Column(DateTime, default=datetime.utcnow)
 
     api_tokens = relationship("APIToken", backref="user")
-    cookie_id = Column(Unicode(1023), default=new_token)
+    cookie_id = Column(Unicode(1023), default=new_token, nullable=False, unique=True)
     # User.state is actually Spawner state
     # We will need to figure something else out if/when we have multiple spawners per user
     state = Column(JSONDict)


Test patch:
Repository: jupyterhub/jupyterhub

Issue:
c.Spawner.port is not configurable
**How to reproduce the issue**

1. Set `c.Spawner.port = 8888` in jupyterhub_config.py

**What you expected to happen**
1. `self.port` inside a Spawner should be 8888

**What actually happens**
1. `self.port` inside spawner is actually still 0

**Share what version of JupyterHub you are using**

0.7

I'm pretty sure it's just the `port` traitlet missing a `.tag(config=True)`


Discussion:

Resolving patch:
diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py
--- a/jupyterhub/spawner.py
+++ b/jupyterhub/spawner.py
@@ -77,9 +77,13 @@ class Spawner(LoggingConfigurable):
 
         Defaults to `0`, which uses a randomly allocated port number each time.
 
+        If set to a non-zero value, all Spawners will use the same port,
+        which only makes sense if each server is on a different address,
+        e.g. in containers.
+
         New in version 0.7.
         """
-    )
+    ).tag(config=True)
 
     start_timeout = Integer(60,
         help="""


Test patch: