Skip to content

Commit 2c7c5a3

Browse files
authored
Merge pull request coollabsio#571 from coollabsio/next
v3.8.4
2 parents c471eed + 806ffac commit 2c7c5a3

26 files changed

+196
-134
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ dist
1111
client
1212
apps/api/db/*.db
1313
local-serve
14-
apps/api/db/migration.db-journal
14+
apps/api/db/migration.db-journal
15+
apps/api/core*

apps/api/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ async function initServer() {
161161
} catch (error) { }
162162
try {
163163
const isOlder = compareVersions('3.8.1', version);
164-
if (isOlder === -1) {
164+
if (isOlder === 1) {
165165
await prisma.build.updateMany({ where: { status: { in: ['running', 'queued'] } }, data: { status: 'failed' } });
166166
}
167167
} catch (error) { }

apps/api/src/jobs/deployApplication.ts

+71-65
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import fs from 'fs/promises';
44
import yaml from 'js-yaml';
55

66
import { copyBaseConfigurationFiles, makeLabelForStandaloneApplication, saveBuildLog, setDefaultConfiguration } from '../lib/buildPacks/common';
7-
import { createDirectories, decrypt, defaultComposeConfiguration, executeDockerCmd, getDomain, prisma } from '../lib/common';
7+
import { createDirectories, decrypt, defaultComposeConfiguration, executeDockerCmd, getDomain, prisma, decryptApplication } from '../lib/common';
88
import * as importers from '../lib/importers';
99
import * as buildpacks from '../lib/buildPacks';
1010

@@ -27,7 +27,7 @@ import * as buildpacks from '../lib/buildPacks';
2727

2828
const th = throttle(async () => {
2929
try {
30-
const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } });
30+
const queuedBuilds = await prisma.build.findMany({ where: { status: { in: ['queued', 'running'] } }, orderBy: { createdAt: 'asc' } });
3131
const { concurrentBuilds } = await prisma.setting.findFirst({})
3232
if (queuedBuilds.length > 0) {
3333
parentPort.postMessage({ deploying: true });
@@ -37,68 +37,72 @@ import * as buildpacks from '../lib/buildPacks';
3737

3838
for (const queueBuild of queuedBuilds) {
3939
actions.push(async () => {
40-
const application = await prisma.application.findUnique({ where: { id: queueBuild.applicationId }, include: { destinationDocker: true, gitSource: { include: { githubApp: true, gitlabApp: true } }, persistentStorage: true, secrets: true, settings: true, teams: true } })
41-
const { id: buildId, type, sourceBranch = null, pullmergeRequestId = null, forceRebuild } = queueBuild
42-
const {
43-
id: applicationId,
44-
repository,
45-
name,
46-
destinationDocker,
47-
destinationDockerId,
48-
gitSource,
49-
configHash,
50-
fqdn,
51-
projectId,
52-
secrets,
53-
phpModules,
54-
settings,
55-
persistentStorage,
56-
pythonWSGI,
57-
pythonModule,
58-
pythonVariable,
59-
denoOptions,
60-
exposePort,
61-
baseImage,
62-
baseBuildImage,
63-
deploymentType,
64-
} = application
65-
let {
66-
branch,
67-
buildPack,
68-
port,
69-
installCommand,
70-
buildCommand,
71-
startCommand,
72-
baseDirectory,
73-
publishDirectory,
74-
dockerFileLocation,
75-
denoMainFile
76-
} = application
77-
const currentHash = crypto
78-
.createHash('sha256')
79-
.update(
80-
JSON.stringify({
81-
pythonWSGI,
82-
pythonModule,
83-
pythonVariable,
84-
deploymentType,
85-
denoOptions,
86-
baseImage,
87-
baseBuildImage,
88-
buildPack,
89-
port,
90-
exposePort,
91-
installCommand,
92-
buildCommand,
93-
startCommand,
94-
secrets,
95-
branch,
96-
repository,
97-
fqdn
98-
})
99-
)
100-
.digest('hex');
40+
let application = await prisma.application.findUnique({ where: { id: queueBuild.applicationId }, include: { destinationDocker: true, gitSource: { include: { githubApp: true, gitlabApp: true } }, persistentStorage: true, secrets: true, settings: true, teams: true } })
41+
let { id: buildId, type, sourceBranch = null, pullmergeRequestId = null, forceRebuild } = queueBuild
42+
application = decryptApplication(application)
10143
try {
44+
if (queueBuild.status === 'running') {
45+
await saveBuildLog({ line: 'Building halted, restarting...', buildId, applicationId: application.id });
46+
}
47+
const {
48+
id: applicationId,
49+
repository,
50+
name,
51+
destinationDocker,
52+
destinationDockerId,
53+
gitSource,
54+
configHash,
55+
fqdn,
56+
projectId,
57+
secrets,
58+
phpModules,
59+
settings,
60+
persistentStorage,
61+
pythonWSGI,
62+
pythonModule,
63+
pythonVariable,
64+
denoOptions,
65+
exposePort,
66+
baseImage,
67+
baseBuildImage,
68+
deploymentType,
69+
} = application
70+
let {
71+
branch,
72+
buildPack,
73+
port,
74+
installCommand,
75+
buildCommand,
76+
startCommand,
77+
baseDirectory,
78+
publishDirectory,
79+
dockerFileLocation,
80+
denoMainFile
81+
} = application
82+
const currentHash = crypto
83+
.createHash('sha256')
84+
.update(
85+
JSON.stringify({
86+
pythonWSGI,
87+
pythonModule,
88+
pythonVariable,
89+
deploymentType,
90+
denoOptions,
91+
baseImage,
92+
baseBuildImage,
93+
buildPack,
94+
port,
95+
exposePort,
96+
installCommand,
97+
buildCommand,
98+
startCommand,
99+
secrets,
100+
branch,
101+
repository,
102+
fqdn
103+
})
104+
)
105+
.digest('hex');
102106
const { debug } = settings;
103107
if (concurrency === 1) {
104108
await prisma.build.updateMany({
@@ -258,7 +262,6 @@ import * as buildpacks from '../lib/buildPacks';
258262
];
259263
if (secrets.length > 0) {
260264
secrets.forEach((secret) => {
261-
secret.value = decrypt(secret.value)
262265
if (pullmergeRequestId) {
263266
if (secret.isPRMRSecret) {
264267
envs.push(`${secret.name}=${secret.value}`);
@@ -353,13 +356,16 @@ import * as buildpacks from '../lib/buildPacks';
353356
where: { id: buildId, status: { in: ['queued', 'running'] } },
354357
data: { status: 'failed' }
355358
});
356-
await saveBuildLog({ line: error, buildId, applicationId });
359+
await saveBuildLog({ line: error, buildId, applicationId: application.id });
357360
}
358361
});
362+
359363
}
364+
360365
await pAll.default(actions, { concurrency })
361366
}
362367
} catch (error) {
368+
console.log(error)
363369
} finally {
364370
}
365371
})

apps/api/src/lib/common.ts

+31-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import * as serviceFields from './serviceFields'
1919
import { saveBuildLog } from './buildPacks/common';
2020
import { scheduler } from './scheduler';
2121

22-
export const version = '3.8.3';
22+
export const version = '3.8.4';
2323
export const isDev = process.env.NODE_ENV === 'development';
2424

2525
const algorithm = 'aes-256-ctr';
@@ -1977,6 +1977,12 @@ export async function cleanupDockerStorage(dockerId, lowDiskSpace, force) {
19771977
} catch (error) {
19781978
//console.log(error);
19791979
}
1980+
// Cleanup build caches
1981+
try {
1982+
await executeDockerCmd({ dockerId, command: `docker builder prune -a -f` })
1983+
} catch (error) {
1984+
//console.log(error);
1985+
}
19801986
}
19811987
}
19821988

@@ -2022,3 +2028,27 @@ export function defaultComposeConfiguration(network: string): any {
20222028
}
20232029
}
20242030
}
2031+
export function decryptApplication(application: any) {
2032+
if (application) {
2033+
if (application?.gitSource?.githubApp?.clientSecret) {
2034+
application.gitSource.githubApp.clientSecret = decrypt(application.gitSource.githubApp.clientSecret) || null;
2035+
}
2036+
if (application?.gitSource?.githubApp?.webhookSecret) {
2037+
application.gitSource.githubApp.webhookSecret = decrypt(application.gitSource.githubApp.webhookSecret) || null;
2038+
}
2039+
if (application?.gitSource?.githubApp?.privateKey) {
2040+
application.gitSource.githubApp.privateKey = decrypt(application.gitSource.githubApp.privateKey) || null;
2041+
}
2042+
if (application?.gitSource?.gitlabApp?.appSecret) {
2043+
application.gitSource.gitlabApp.appSecret = decrypt(application.gitSource.gitlabApp.appSecret) || null;
2044+
}
2045+
if (application?.secrets.length > 0) {
2046+
application.secrets = application.secrets.map((s: any) => {
2047+
s.value = decrypt(s.value) || null
2048+
return s;
2049+
});
2050+
}
2051+
2052+
return application;
2053+
}
2054+
}

apps/api/src/routes/api/v1/applications/handlers.ts

+1
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ export async function deployApplication(request: FastifyRequest<DeployApplicatio
451451
data: {
452452
id: buildId,
453453
applicationId: id,
454+
sourceBranch: branch,
454455
branch: application.branch,
455456
pullmergeRequestId,
456457
forceRebuild,

apps/api/src/routes/api/v1/iam/handlers.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,11 @@ export async function getTeam(request: FastifyRequest<OnlyId>, reply: FastifyRep
158158
});
159159
const team = await prisma.team.findUnique({ where: { id }, include: { permissions: true } });
160160
const invitations = await prisma.teamInvitation.findMany({ where: { teamId: team.id } });
161+
const { teams } = await prisma.user.findUnique({ where: { id: userId }, include: { teams: true } })
161162
return {
163+
currentTeam: teamId,
162164
team,
165+
teams,
163166
permissions,
164167
invitations
165168
};
@@ -275,10 +278,10 @@ export async function inviteToTeam(request: FastifyRequest<InviteToTeam>, reply:
275278
if (!userFound) {
276279
throw {
277280
message: `No user found with '${email}' email address.`
278-
};
281+
};
279282
}
280283
const uid = userFound.id;
281-
if (uid === userId) {
284+
if (uid === userId) {
282285
throw {
283286
message: `Invitation to yourself? Whaaaaat?`
284287
};

apps/api/src/routes/api/v1/sources/handlers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export async function listSources(request: FastifyRequest) {
99
try {
1010
const teamId = request.user?.teamId;
1111
const sources = await prisma.gitSource.findMany({
12-
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } },
12+
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } }, githubApp: { gitSource: { forPublic: false } } },
1313
include: { teams: true, githubApp: true, gitlabApp: true }
1414
});
1515
return {

apps/api/src/routes/webhooks/github/handlers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
146146
message: 'Queued. Thank you!'
147147
};
148148
} else if (githubEvent === 'pull_request') {
149-
const pullmergeRequestId = body.number;
149+
const pullmergeRequestId = body.number.toString();
150150
const pullmergeRequestAction = body.action;
151151
const sourceBranch = body.pull_request.head.ref.includes('/') ? body.pull_request.head.ref.split('/')[2] : body.pull_request.head.ref;
152152
if (!allowedActions.includes(pullmergeRequestAction)) {

apps/ui/src/lib/components/Usage.svelte

+15-17
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@
8686

8787
<div class="w-full">
8888
<div class="flex items-center">
89-
<h1 class="title text-4xl">Hardware Details</h1>
90-
<div class="flex space-x-4">
89+
<h1 class="title lg:text-3xl">Hardware Details</h1>
90+
<div class="flex space-x-4">
9191
{#if $appSession.teamId === '0'}
9292
<button on:click={manuallyCleanupStorage} class:loading={loading.cleanup} class="btn btn-sm"
9393
>Cleanup Storage</button
@@ -101,42 +101,41 @@
101101
</div>
102102
</div>
103103
<div class="divider" />
104-
<div class="grid grid-flow-col gap-4 grid-rows-3 lg:grid-rows-1">
105-
<div class="stats stats-vertical lg:stats-horizontal w-full mb-5 bg-transparent rounded">
106-
<div class="font-bold flex lg:justify-center">Memory</div>
104+
<div class="grid grid-flow-col gap-4 grid-rows-3 justify-start lg:justify-center lg:grid-rows-1">
105+
<div class="stats stats-vertical min-w-[16rem] mb-5 rounded bg-transparent">
107106
<div class="stat">
108-
<div class="stat-title">Total</div>
107+
<div class="stat-title">Total Memory</div>
109108
<div class="stat-value text-2xl">
110109
{(usage?.memory.totalMemMb).toFixed(0)}<span class="text-sm">MB</span>
111110
</div>
112111
</div>
113112

114113
<div class="stat">
115-
<div class="stat-title">Used</div>
114+
<div class="stat-title">Used Memory</div>
116115
<div class="stat-value text-2xl">
117116
{(usage?.memory.usedMemMb).toFixed(0)}<span class="text-sm">MB</span>
118117
</div>
119118
</div>
120119

121120
<div class="stat">
122-
<div class="stat-title">Free</div>
121+
<div class="stat-title">Free Memory</div>
123122
<div class="stat-value text-2xl">
124123
{usage?.memory.freeMemPercentage}<span class="text-sm">%</span>
125124
</div>
126125
</div>
127126
</div>
128127

129-
<div class="stats stats-vertical lg:stats-horizontal w-full mb-5 bg-transparent rounded">
130-
<div class="font-bold flex lg:justify-center">CPU</div>
128+
<div class="stats stats-vertical min-w-[20rem] mb-5 bg-transparent rounded">
129+
131130
<div class="stat">
132-
<div class="stat-title">Total</div>
131+
<div class="stat-title">Total CPU</div>
133132
<div class="stat-value text-2xl">
134133
{usage?.cpu.count}
135134
</div>
136135
</div>
137136

138137
<div class="stat">
139-
<div class="stat-title">Usage</div>
138+
<div class="stat-title">CPU Usage</div>
140139
<div class="stat-value text-2xl">
141140
{usage?.cpu.usage}<span class="text-sm">%</span>
142141
</div>
@@ -147,24 +146,23 @@
147146
<div class="stat-value text-2xl">{usage?.cpu.load}</div>
148147
</div>
149148
</div>
150-
<div class="stats stats-vertical lg:stats-horizontal w-full mb-5 bg-transparent rounded">
151-
<div class="font-bold flex lg:justify-center">Disk</div>
149+
<div class="stats stats-vertical min-w-[16rem] mb-5 bg-transparent rounded">
152150
<div class="stat">
153-
<div class="stat-title">Total</div>
151+
<div class="stat-title">Total Disk</div>
154152
<div class="stat-value text-2xl">
155153
{usage?.disk.totalGb}<span class="text-sm">GB</span>
156154
</div>
157155
</div>
158156

159157
<div class="stat">
160-
<div class="stat-title">Used</div>
158+
<div class="stat-title">Used Disk</div>
161159
<div class="stat-value text-2xl">
162160
{usage?.disk.usedGb}<span class="text-sm">GB</span>
163161
</div>
164162
</div>
165163

166164
<div class="stat">
167-
<div class="stat-title">Free</div>
165+
<div class="stat-title">Free Disk</div>
168166
<div class="stat-value text-2xl">
169167
{usage?.disk.freePercentage}<span class="text-sm">%</span>
170168
</div>

apps/ui/src/lib/components/svg/applications/Docker.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
</script>
44

55

6-
<svg viewBox="0 0 128 128" class={isAbsolute ? 'absolute top-0 left-0 -m-8 h-16 w-16' : 'mx-auto w-10 h-10'}>
6+
<svg viewBox="0 0 128 128" class={isAbsolute ? 'absolute top-0 left-0 -m-5 h-12 w-12' : 'mx-auto w-10 h-10'}>
77
<path d="M124.8 52.1c-4.3-2.5-10-2.8-14.8-1.4-.6-5.2-4-9.7-8-12.9l-1.6-1.3-1.4 1.6c-2.7 3.1-3.5 8.3-3.1 12.3.3 2.9 1.2 5.9 3 8.3-1.4.8-2.9 1.9-4.3 2.4-2.8 1-5.9 2-8.9 2H79V49H66V24H51v12H26v13H13v14H1.8l-.2 1.5c-.5 6.4.3 12.6 3 18.5l1.1 2.2.1.2c7.9 13.4 21.7 19 36.8 19 29.2 0 53.3-13.1 64.3-40.6 7.4.4 15-1.8 18.6-8.9l.9-1.8-1.6-1zM28 39h10v11H28V39zm13.1 44.2c0 1.7-1.4 3.1-3.1 3.1-1.7 0-3.1-1.4-3.1-3.1 0-1.7 1.4-3.1 3.1-3.1 1.7.1 3.1 1.4 3.1 3.1zM28 52h10v11H28V52zm-13 0h11v11H15V52zm27.7 50.2c-15.8-.1-24.3-5.4-31.3-12.4 2.1.1 4.1.2 5.9.2 1.6 0 3.2 0 4.7-.1 3.9-.2 7.3-.7 10.1-1.5 2.3 5.3 6.5 10.2 14 13.8h-3.4zM51 63H40V52h11v11zm0-13H40V39h11v11zm13 13H53V52h11v11zm0-13H53V39h11v11zm0-13H53V26h11v11zm13 26H66V52h11v11zM38.8 81.2c-.2-.1-.5-.2-.8-.2-1.2 0-2.2 1-2.2 2.2 0 1.2 1 2.2 2.2 2.2s2.2-1 2.2-2.2c0-.3-.1-.6-.2-.8-.2.3-.4.5-.8.5-.5 0-.9-.4-.9-.9.1-.4.3-.7.5-.8z" fill="#019BC6"></path>
88
</svg>
99

0 commit comments

Comments
 (0)