Skip to content

Commit 937bb50

Browse files
committed
added importer to complete migration from LiGet
1 parent dc501a2 commit 937bb50

File tree

11 files changed

+152
-6
lines changed

11 files changed

+152
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Added compatibility mode with LiGet to keep the same endpoints
55
* V2 includes dependencies in package query results
66
* Switch production base image to slim stretch
7+
* added importer to complete migration from LiGet
78

89
### 0.1.0 (2018-Nov-09)
910

docker-compose-liget-compat.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ services:
1515
image: ${AIT_DOCKER_IMAGE_NAME}:${AIT_DOCKER_IMAGE_TAG}
1616
volumes:
1717
- ${IDE_WORK}/e2e/liget-compat/data/:/var/baget
18+
- ${IDE_WORK}/e2e/input:/data/simple #simulates LiGet's storage
1819
env_file:
1920
- ${ENV_FILE}
2021
mem_limit: 550m

docker-scripts/run.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ chown $NEWUID:$NEWGID -R /home/baget
4848
# Start server
4949
###########################################################################
5050

51+
if [ ! -z ${BAGET_IMPORT_ON_BOOT+x} ]; then
52+
sudo -u baget -E -H dotnet /app/BaGet.dll import --path ${BAGET_IMPORT_ON_BOOT}
53+
fi
54+
5155
cd /app
5256
if [[ $NEWGID != 0 ]]; then
5357
exec sudo -u baget -E -H dotnet /app/BaGet.dll

e2e/liget-compat/run.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ cat << EOF > /home/ide/.nuget/NuGet/NuGet.Config
1616
</configuration>
1717
EOF
1818

19-
echo "Sleeping 4s to wait for server to be ready"
20-
sleep 4
19+
echo "Sleeping 10s to wait for server to be ready"
20+
sleep 10
2121

2222
COMPAT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
2323
E2E_DIR="$COMPAT_DIR/.."
@@ -37,9 +37,8 @@ EOF
3737

3838
mono $E2E_DIR/.paket/paket.bootstrapper.exe
3939

40-
# BaGet would have all private packages imported already
40+
# BaGet running with BAGET_IMPORT_ON_BOOT should have all private packages imported already
4141
cd $E2E_DIR/input
42-
dotnet nuget push baget-two/bin/Debug/baget-two.2.1.0.nupkg --source http://nuget:9090/v3/index.json --api-key NUGET-SERVER-API-KEY
4342

4443
cd $COMPAT_DIR/paket
4544
rm -rf paket-files

readme.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ This will enable following behavior:
114114
- `/api/cache/v3/index.json` returns same content as original BaGet's `/cache/v3/index.json`.
115115
- `/api/v2/*` returns **V2** resources, same as `/v2/*`
116116

117+
### Importing packages
118+
119+
To make transition from LiGet or any other server which keeps `.nupkg` files in a directory,
120+
there is an `import` command:
121+
```
122+
dotnet BaGet.dll import --path dir
123+
```
124+
In the docker image you can setup environment variable - `BAGET_IMPORT_ON_BOOT=/data/simple`
125+
which will cause baget to first search for `nupkg` files in `$BAGET_IMPORT_ON_BOOT`, before starting server.
126+
Packages which were already added are skipped.
127+
Setting `BAGET_IMPORT_ON_BOOT=/data/simple` is sufficient for migration from LiGet.
128+
129+
*Note: you only need to set this variable once to perform initial migration.
130+
You should unset it in later deployments to avoid uncessary scanning.*
131+
117132
# Development
118133

119134
We rely heavily on docker to create reproducible development environment.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
5+
namespace BaGet.Core.Services
6+
{
7+
public class PackageImporter
8+
{
9+
private readonly IIndexingService _indexingService;
10+
11+
public PackageImporter(IIndexingService indexingService) {
12+
this._indexingService = indexingService;
13+
}
14+
15+
public async Task ImportAsync(string pkgDirectory, TextWriter output)
16+
{
17+
string[] files = Directory.GetFiles(pkgDirectory, "*.nupkg", SearchOption.AllDirectories);
18+
foreach (string file in files)
19+
{
20+
output.Write("Importing package {0} ", file);
21+
using(var uploadStream = File.OpenRead(file)) {
22+
var result = await _indexingService.IndexAsync(uploadStream);
23+
output.WriteLine(result);
24+
}
25+
}
26+
}
27+
}
28+
}

src/BaGet/Extensions/ServiceCollectionExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public static IServiceCollection ConfigureBaGet(
5555
services.ConfigureSearchProviders();
5656
services.ConfigureAuthenticationProviders();
5757

58+
services.AddTransient<PackageImporter, PackageImporter>();
59+
5860
return services;
5961
}
6062

src/BaGet/Program.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
using BaGet.Core.Mirror;
1+
using System;
2+
using BaGet.Core.Configuration;
3+
using BaGet.Core.Entities;
4+
using BaGet.Core.Mirror;
5+
using BaGet.Core.Services;
26
using BaGet.Extensions;
37
using Gelf.Extensions.Logging;
48
using McMaster.Extensions.CommandLineUtils;
59
using Microsoft.AspNetCore;
610
using Microsoft.AspNetCore.Hosting;
11+
using Microsoft.EntityFrameworkCore;
712
using Microsoft.Extensions.DependencyInjection;
813
using Microsoft.Extensions.Hosting;
914
using Microsoft.Extensions.Logging;
15+
using Microsoft.Extensions.Options;
1016

1117
namespace BaGet
1218
{
@@ -35,6 +41,36 @@ await provider
3541
.ImportAsync();
3642
});
3743
});
44+
45+
var optionImportPath = import.Option("-p|--path <directory>", "Directory with .nupkg files at any depth", CommandOptionType.SingleValue);
46+
import.OnExecute(async () => {
47+
var importDirectory = optionImportPath.HasValue()
48+
? optionImportPath.Value()
49+
: ".";
50+
51+
Console.WriteLine($"Importing packages from {importDirectory}");
52+
var provider = CreateHostBuilder(args).Build().Services;
53+
54+
var scopeFactory = provider.GetRequiredService<IServiceScopeFactory>();
55+
// Run migrations if enabled
56+
var databaseOptions = provider.GetRequiredService<IOptions<BaGetOptions>>()
57+
.Value
58+
.Database;
59+
if(databaseOptions.RunMigrations) {
60+
using (var scope = scopeFactory.CreateScope())
61+
{
62+
scope.ServiceProvider
63+
.GetRequiredService<IContext>()
64+
.Database
65+
.Migrate();
66+
}
67+
}
68+
69+
await provider
70+
.GetRequiredService<PackageImporter>()
71+
.ImportAsync(importDirectory, Console.Out);
72+
return 0;
73+
});
3874
});
3975

4076
app.OnExecute(() =>

tasks.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,15 @@ case "${command}" in
8080
rm -rf e2e/liget-compat/data/packages/*
8181
rm -rf e2e/liget-compat/data/cache/*
8282
export LiGetCompat__Enabled=true
83+
export BAGET_IMPORT_ON_BOOT=/data/simple
8384
ide --idefile Idefile.liget-compat "e2e/liget-compat/run.sh"
8485
;;
8586
all)
8687
ide "./build.sh --target All"
8788
./tasks.sh build_docker
8889
./tasks.sh test_docker
8990
./tasks.sh liget_compat_docker
90-
./tasks.sh stress_docker
91+
./tasks.sh stress_docker
9192
;;
9293
prepare_code_release)
9394
version=$2
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.IO;
3+
using System.Text;
4+
using System.Threading.Tasks;
5+
using BaGet.Core.Services;
6+
using BaGet.Tests.Support;
7+
using Microsoft.AspNetCore.TestHost;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Logging;
10+
using Xunit;
11+
using Xunit.Abstractions;
12+
13+
namespace BaGet.Tests.Services
14+
{
15+
[Trait("Category", "integration")] // because it uses external nupkg files
16+
public class PackageImporterIntegrationTest
17+
{
18+
public ITestOutputHelper Helper { get; private set; }
19+
20+
private TestServer server;
21+
22+
public PackageImporterIntegrationTest(ITestOutputHelper helper)
23+
{
24+
Helper = helper ?? throw new ArgumentNullException(nameof(helper));
25+
server = TestServerBuilder.Create().TraceToTestOutputHelper(Helper, LogLevel.Error).Build();
26+
}
27+
28+
[Fact]
29+
public async Task ImportExamplePackages()
30+
{
31+
var importer = server.Host.Services.GetRequiredService<PackageImporter>();
32+
using(var ms = new MemoryStream()) {
33+
var writer = new StreamWriter(ms, Encoding.UTF8);
34+
await importer.ImportAsync(TestResources.GetE2eInputDirectory(), writer);
35+
await writer.FlushAsync();
36+
string text = Encoding.UTF8.GetString(ms.ToArray());
37+
Assert.Contains("baget-test1.1.0.0.nupkg Success", text);
38+
Assert.Contains("baget-two.1.0.0.nupkg Success", text);
39+
Assert.Contains("baget-two.2.1.0.nupkg Success", text);
40+
}
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)