Skip to content

Commit

Permalink
fix(docker-builder): always use a new instance to avoid mixing docker…
Browse files Browse the repository at this point in the history
… services
  • Loading branch information
nicotsx committed Dec 10, 2024
1 parent 316a688 commit 8cec009
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 145 deletions.
43 changes: 13 additions & 30 deletions e2e/0005-guest-dashboard.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect, test } from '@playwright/test';
import { app } from '../packages/backend/src/core/database/drizzle/schema';
import { loginUser } from './fixtures/fixtures';
import { installApp, loginUser } from './fixtures/fixtures';
import { clearDatabase, db } from './helpers/db';
import { setSettings } from './helpers/settings';

Expand All @@ -21,45 +20,29 @@ test('user can activate the guest dashboard and see it when logged out', async (
await expect(page.getByText('No apps to display')).toBeVisible();
});

test('logged out users can see the apps on the guest dashboard', async ({ browser }) => {
test('logged out users can see the apps on the guest dashboard', async ({ page, context }) => {
await loginUser(page, context);

const store = await db.query.appStore.findFirst();

await db.insert(app).values({
config: {},
isVisibleOnGuestDashboard: true,
id: `hello-world_${store?.id}`,
exposed: true,
exposedLocal: true,
domain: 'duckduckgo.com',
status: 'running',
openPort: true,
});
await db.insert(app).values({
config: {},
openPort: true,
isVisibleOnGuestDashboard: false,
id: `actual-budget_${store?.id}`,
exposed: false,
exposedLocal: false,
status: 'running',
});

const context = await browser.newContext();
const page = await context.newPage();
if (!store) {
throw new Error('No store found');
}

await loginUser(page, context);
await page.goto('/settings');
await installApp(page, store?.id, 'nginx', { visibleOnGuestDashboard: true, domain: 'duckduckgo.com' });
await installApp(page, store?.id, '2fauth', { visibleOnGuestDashboard: false });

await page.goto('/settings');
await page.getByRole('tab', { name: 'Settings' }).click();
await page.getByLabel('guestDashboard').setChecked(true);
await page.getByRole('button', { name: 'Update settings' }).click();
await page.getByTestId('logout-button').click();

await expect(page.getByText(/Hello World web server/)).toBeVisible();
const locator = page.locator('text=Actual Budget');
await expect(page.getByText(/Open-source simple and fast web server/)).toBeVisible();
const locator = page.locator('text=2Fauth');
await expect(locator).not.toBeVisible();

await page.getByRole('link', { name: /Hello World/ }).click();
await page.getByRole('link', { name: /Nginx/ }).click();

const [newPage] = await Promise.all([context.waitForEvent('page'), page.getByRole('menuitem', { name: 'duckduckgo.com' }).click()]);

Expand Down
28 changes: 28 additions & 0 deletions e2e/fixtures/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,31 @@ export const loginUser = async (page: Page, _: BrowserContext) => {

await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
};

type InstallAppOpts = {
visibleOnGuestDashboard?: boolean;
domain?: string;
};

export const installApp = async (page: Page, storeId: number, appId: string, opts: InstallAppOpts = {}) => {
await page.goto(`/app-store/${storeId}/${appId}`);

// Install app
await page.getByRole('button', { name: 'Install' }).click();

await expect(page.getByText('Display on guest dashboard')).toBeVisible();

if (opts.visibleOnGuestDashboard) {
await page.getByLabel('isVisibleOnGuestDashboard').setChecked(true);
}

if (opts.domain) {
await page.getByLabel('exposed', { exact: true }).setChecked(true);
await page.getByPlaceholder('Domain name').fill(opts.domain);
}

await page.getByRole('button', { name: 'Install' }).click();

await expect(page.getByText('Installing')).toBeVisible();
await expect(page.getByText('Running')).toBeVisible({ timeout: 60000 });
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { z } from 'zod';
import { AppFilesManager } from '../apps/app-files-manager';
import { AppHelpers } from '../apps/app.helpers';
import { BackupManager } from '../backups/backup.manager';
import { DockerComposeBuilder } from '../docker/builders/compose.builder';
import { DockerService } from '../docker/docker.service';
import { EnvUtils } from '../env/env.utils';
import { MarketplaceService } from '../marketplace/marketplace.service';
Expand All @@ -30,97 +29,43 @@ export class AppLifecycleCommandFactory {
private readonly dockerService: DockerService,
private readonly backupManager: BackupManager,
private readonly marketplaceService: MarketplaceService,
private readonly dockerComposeBuilder: DockerComposeBuilder,
) {}

createCommand(eventData: z.infer<typeof appEventSchema>) {
const command = eventData.command;

switch (command) {
case 'install':
return new InstallAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
this.envUtils,
);
return new InstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers, this.envUtils);
case 'start':
return new StartAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
);
return new StartAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers);
case 'stop':
return new StopAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
);
return new StopAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers);
case 'restart':
return new RestartAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
);
return new RestartAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers);
case 'uninstall':
return new UninstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.dockerComposeBuilder);
return new UninstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService);
case 'reset':
return new ResetAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
this.envUtils,
);
return new ResetAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers, this.envUtils);
case 'backup':
return new BackupAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.backupManager,
);
return new BackupAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.backupManager);
case 'restore':
return new RestoreAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.backupManager,
eventData.filename,
);
case 'generate_env':
return new GenerateAppEnvCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
);
return new GenerateAppEnvCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers);
case 'update':
return new UpdateAppCommand(
this.logger,
this.appFilesManager,
this.dockerService,
this.marketplaceService,
this.dockerComposeBuilder,
this.appHelpers,
this.backupManager,
eventData.performBackup,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { BackupManager } from '@/modules/backups/backup.manager';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import { AppLifecycleCommand } from './command';
Expand All @@ -12,10 +11,9 @@ export class BackupAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly backupManager: BackupManager,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);

this.logger = logger;
this.appFilesManager = appFilesManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export class AppLifecycleCommand {
protected appFilesManager: AppFilesManager,
protected dockerService: DockerService,
protected marketplaceService: MarketplaceService,
protected dockerComposeBuilder: DockerComposeBuilder,
) {}

protected async ensureAppDir(appId: string, form: AppEventFormInput): Promise<void> {
Expand All @@ -31,7 +30,8 @@ export class AppLifecycleCommand {
try {
const { services } = dynamicComposeSchema.parse(composeJson.content);
const { storeId } = extractAppId(appId);
const composeFile = this.dockerComposeBuilder.getDockerCompose(services, form, storeId);
const dockerComposeBuilder = new DockerComposeBuilder();
const composeFile = dockerComposeBuilder.getDockerCompose(services, form, storeId);

await this.appFilesManager.writeDockerComposeYml(appId, composeFile);
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { LoggerService } from '@/core/logger/logger.service';
import type { AppFilesManager } from '@/modules/apps/app-files-manager';
import type { AppHelpers } from '@/modules/apps/app.helpers';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import type { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import type { AppEventFormInput } from '@/modules/queue/entities/app-events';
Expand All @@ -13,10 +12,9 @@ export class GenerateAppEnvCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { AppHelpers } from '@/modules/apps/app.helpers';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { EnvUtils } from '@/modules/env/env.utils';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
Expand All @@ -14,11 +13,10 @@ export class InstallAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
private readonly envUtils: EnvUtils,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { AppHelpers } from '@/modules/apps/app.helpers';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import type { EnvUtils } from '@/modules/env/env.utils';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
Expand All @@ -14,11 +13,10 @@ export class ResetAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
private readonly envUtils: EnvUtils,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { AppHelpers } from '@/modules/apps/app.helpers';
import type { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import type { AppEventFormInput } from '@/modules/queue/entities/app-events';
Expand All @@ -13,10 +12,9 @@ export class RestartAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string, form: AppEventFormInput, skipEnvGeneration = false): Promise<{ success: boolean; message: string }> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { BackupManager } from '@/modules/backups/backup.manager';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import { AppLifecycleCommand } from './command';
Expand All @@ -12,11 +11,10 @@ export class RestoreAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly backupManager: BackupManager,
private readonly filename: string,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string): Promise<{ success: boolean; message: string }> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { AppHelpers } from '@/modules/apps/app.helpers';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import type { AppEventFormInput } from '@/modules/queue/entities/app-events';
Expand All @@ -13,10 +12,9 @@ export class StartAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);

this.logger = logger;
this.appFilesManager = appFilesManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerService } from '@/core/logger/logger.service';
import { AppFilesManager } from '@/modules/apps/app-files-manager';
import { AppHelpers } from '@/modules/apps/app.helpers';
import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder';
import { DockerService } from '@/modules/docker/docker.service';
import { MarketplaceService } from '@/modules/marketplace/marketplace.service';
import type { AppEventFormInput } from '@/modules/queue/entities/app-events';
Expand All @@ -13,10 +12,9 @@ export class StopAppCommand extends AppLifecycleCommand {
appFilesManager: AppFilesManager,
dockerService: DockerService,
marketplaceService: MarketplaceService,
dockerComposeBuilder: DockerComposeBuilder,
private readonly appHelpers: AppHelpers,
) {
super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder);
super(logger, appFilesManager, dockerService, marketplaceService);
}

public async execute(appId: string, form: AppEventFormInput, skipEnvGeneration = false) {
Expand Down
Loading

0 comments on commit 8cec009

Please sign in to comment.