singularityhub / sregistry

server for storage and management of singularity images
https://singularityhub.github.io/sregistry
Mozilla Public License 2.0
103 stars 42 forks source link

Custom user is not able to push an image #248

Closed RonaldEnsing closed 4 years ago

RonaldEnsing commented 4 years ago

I would like to have my CI/CD pipeline push singularity images to my sregistry instance. In order to do that, I needed to create a custom sregistry user for my CI/CD, because obviously I do not want to use the token of any other regular user for that. I used the Django Administration site to add this user and a token for this user was automatically created.

When I tried to push an image with this custom user, I noticed that I am not able to do so because a push is only allowed if a collection already exists and is owned by this user. Since I cannot login on the sregistry website with this custom user I had to find another way to create a collection. So I created a team and team-owned collection in the web site using my own user account. Then I added the custom user to that team using the python manage.py shell and then making the changes manually, because I can only invite users in the web interface (I cannot add them).

When I setup the remotes.yaml and .sregistry for the custom user accordingly, I still get FATAL: Unable to push image to library: request did not succeed: http status code: 500. which I do not get for the regular account.

Any ideas what would cause this? Is there more I need to do besides adding the custom user to the team?

I am using commit 1dc800b8eff66013df59a80c1801847874e11341 of sregistry and singularity v3.3.0 (installed from source) on ubuntu 18.04.

vsoch commented 4 years ago

500 is a server error, can you look at uwsgi logs?

docker-compose logs --tail=100 uwsgi
RonaldEnsing commented 4 years ago

docker-compose logs --tail=100 uwsgi gives me:

uwsgi_1      | GET NamedEntityView
uwsgi_1      | <QueryDict: {}>
uwsgi_1      | gitlab-ci
uwsgi_1      | Internal Server Error: /v1/entities/gitlab-ci
uwsgi_1      | Traceback (most recent call last):
......
......
uwsgi_1      |   File "./shub/apps/library/views/helpers.py", line 89, in generate_user_data
uwsgi_1      |     'updatedAt': user.last_login.strftime(formatString),
uwsgi_1      | AttributeError: 'NoneType' object has no attribute 'strftime'
vsoch commented 4 years ago

I need to finish up a PR for another project, but I'll take a look soon! I would like this to work - it makes sense to want to have a robot user, and if /when we do get it working we can write some docs for how to go about it.

RonaldEnsing commented 4 years ago

Okay, great. Since this custom (robot) user has never logged in, there's probably also no last_login, and maybe that's why it fails.

vsoch commented 4 years ago

oh yeah, taking a look now - that's easy to fix! Can you write a few lines that I can add to a section about creating a robot user? I think we'd want something like:

How to Generate a Robot User

You must be an admin of the server to generate a robot user.

  1. Use the Django Administration site to add this user and a token for this user will be automatically created. If you need to refresh the token, you can do so here.
  2. Since the collection must already exist and you cannot log in as the robot user, you should create the collection with your user account, create a team and add the collection to be owned by the team, and then add the robot user to the team inside the container like so:
# can you share the commands you used?

I'll work on starting a PR for the issue you just hit, and we can add the text above to the docs.

RonaldEnsing commented 4 years ago

The quick fix (workaround) for now is to simply set an arbitrary last_login for the robot user using the django administration site.

edit: And sure, I will add a few lines to the documentation.

vsoch commented 4 years ago

okay I've written the docs and I'm about to open a PR - I suspect we are going to run into another issue with checking permissions on the collection (there hasn't been a lot of recent work with teams), but I'd like for you to test out and verify. I'll link the PR here shortly.

vsoch commented 4 years ago

https://github.com/singularityhub/sregistry/pull/249

RonaldEnsing commented 4 years ago

You were quicker than me updating the docs. Looks good, these were indeed the commands I used on the shell in the container. I'll comment further in #249.

vsoch commented 4 years ago

okay great! Let me know about the create permission - I don't see any logic carried forward to check associated teams so I don't think it will work.

RonaldEnsing commented 4 years ago

What create permission are you referring to?

vsoch commented 4 years ago

Basically, just let me know if the user is unable to push a container to the collection (create container is what I'm referring to).

RonaldEnsing commented 4 years ago

Yes, I've successfully pushed a container with the regular user to the collection owned by the team.

vsoch commented 4 years ago

Can you verify that if you remove the team, it doesn't work?

vsoch commented 4 years ago

And was this done with sregistry client or Singularity?

RonaldEnsing commented 4 years ago

With singularity

vsoch commented 4 years ago

Can you confirm that if you remove the user from the team it doesn't work? I'm having a hard time tracing how this is working.

vsoch commented 4 years ago

E.g.

        if token.user not in collection.owners.all():
            return Response(status=403)  

And collection.owners is a list that I don't see being derived based on the team.

RonaldEnsing commented 4 years ago

Ah, you're right. I removed the user from the team and I am still able to push to the collection. After I pushed, this user is automatically added as a member again (not owner).

vsoch commented 4 years ago

Can you tell me what you see for collection.members.all() vs collection.owners.all() (before and after?)

vsoch commented 4 years ago

I'm not sure why it's not triggering to return a permission denied when the user isn't found in the owners, it should return a 403.

vsoch commented 4 years ago

I think we need to debug that first.

vsoch commented 4 years ago

Ahh I know what it is, I don't think teams are being used here, the functions in the collection just add users directly to collection.contributors() or collection.owners(). And now I see how the teams fit in - I didn't want any one to just be able to see all the users in the registry willy nilly, so you are only allowed to see and select from the teams. The teams themselves aren't directly linked to the collections.

So - can you verify that the robot account is still a part of collection.owners.all()? If so, things are working as expected and we don't have any issue (and yes I totally forgot how I implemented that and I'll go put my head in the snow for a refresh!)

vsoch commented 4 years ago

I can also update the example to show how to add the user to an owner in the collection without adding a team (you really don't need to!)

vsoch commented 4 years ago

okay! Just updated the PR docs - take a look and let me know if all is well.

RonaldEnsing commented 4 years ago

Can you tell me what you see for collection.members.all() vs collection.owners.all() (before and after?)

The user is still collection owner, before and after.

RonaldEnsing commented 4 years ago

okay! Just updated the PR docs - take a look and let me know if all is well.

Looks good

vsoch commented 4 years ago

Thank you for your help with this!

RonaldEnsing commented 4 years ago

Thank you for the quick response and fixes