NuGet / NuGetGallery

NuGet Gallery is a package repository that powers https://www.nuget.org. Use this repo for reporting NuGet.org issues.
https://www.nuget.org/
Apache License 2.0
1.54k stars 645 forks source link

NuGet.Server: Adding support for SQL Server (and other database backends) #5430

Open NickCraver opened 6 years ago

NickCraver commented 6 years ago

One of the things we really want at Stack Overflow is a simple internet NuGet feed without external dependencies. This has a few legs to it, we want to:

NuGet.Server

NuGet.Server is the simplicity and minimal setup and dependencies we want, but is still ultimately file based and therefore has inherent limitations:

NuGetGallery

The obvious question: why not just use Gallery?

So: SQL Server. I played with what's needed to make this happen and it's not all that much. I have a working version of this on a branch here: NickCraver/NuGet.Server (craver/sql-server branch) with most of the relevant pieces in this commit: https://github.com/NickCraver/NuGet.Server/commit/96953922c5a645f24548345388797dfe44b0056a

Here's a view on the current state of things: 2018-02-10 08_16_37-sqlquery1 sql - local local nuget cravertop_nrcra 54 _ - microsoft sql serv

Note: the Packages table has PackageData directly in it (again - just a first pass), this returns too much data for most things. It's quite easy to make this another table and I'll do that next.

It's a first pass with a few pitfalls, but all of them are straightforward to remedy. This is just the rest of a few nights getting a feed up. It's already fully functional, but needs a few global changes to be workable:

Overall note: While this issue and current code supports SQL Server, if we can figure out the dependency issue EF Core can very easily be swapped out for MySQL, SQLite, Postgres, etc. - anything that EF Core supports as the usage is very basic. Perhaps making the provider itself a plugin somehow would make things like NuGet.Server.MySQL an option. I'm not sure how that would work...so I'm starting the discussion here with SQL Server.

cc @joelverhagen

lahma commented 6 years ago

I love everything here and would like to replace our NuGet server with less disk-based feed - SQL Server is already natural backup target. The transparent mirror is great too.

As a current user I'd like to see easy migration path. We have a folder full of package names with subfolders for versions...

NickCraver commented 6 years ago

@lahma That reminds me! Currently the file system watcher where you can drop files into the \Packages folder resides in the ServerPackageRepository (and therefore is only active when the backend file store is in use), but IMO, is a distinct piece of functionaity.

There's no reason to tie the folder drop functionality to the ultimate backend store. If we moved this (and had some event handlers on the thing perhaps), it'd just pickup files and drop them into whatever backend store is in use. The leads me to migration: while not a one-click solution "just copy your packages here and we'll suck them in" is still pretty appealing as an easy-to-do option serving multiple use cases.

@joelverhagen thoughts here? I could tackle moving it into a shared place as part of this proposal if welcomed.

joelverhagen commented 6 years ago

thoughts here? I could tackle moving it into a shared place as part of this proposal if welcomed.

Love the idea. This would also facilitate improved test coverage of that component... It's a bit fiddly right now. I tried this in the past but ran into pain. Definitely worth another stab.

Thus far it seems like upstream and decouple file system watcher belong in the main packages: NuGet.Server or one of I two dependencies.

And the EF integration belongs in NuGet.Server.Database or some such name.

ghost commented 6 years ago

In case others are looking for a hosted option that already does a lot of this, you can check out VSTS NuGet which gives you geo-redundancy private feeds with the read-through caching you mention.

Funny enough, our project started out with doing exactly what you are proposing - I remember hitting the same DI scoping issue you're talking about. However, we ended up going in different direction. Unfortunately, we were doing it on an internal SQL framework that makes the code we wrote not particularly helpful to your pursuit.